Playing with css animations

As a full-stack .net web-developer I have been doing a lot of html, css and EcmaScript. Often projects start out with a dedicated front-end developer doing his thing, but normally projects go into maintenance mode and then all fixes or new features are handled by the last mand standing, aka me. Therefore I have to be fluent in all things front-end.

Recently I’ve been looking into css3 transforms, transitions and animations. I remember when anything moving had to be either Flash or Java. Then came jQuery and made it simple to use EcmaScript to make things that move or smoothly transform on mouseover etc. I’ve been doing $.animate() a lot!

But lately I’ve been looking into css animations. If you already know what you can do with css animations, then this post is not for you. If on the other hand, you are still doing $.animate(), read on and maybe you can get inspired and write less jQuery next time.

I decided to try and make something that mimics the interface my AppleTV has, when I play music.

The interface is really clean on simple, but there are some “moving parts”.

  • The album cover , which is turned a bit to create a 3D effect:
    cover
    Simple:

    transform: rotateY(30deg);

    Dont’ forget to set

    perspective: 800px;

    on the parent element or else it will not look like real 3D.

  • Then there is the progressbar showing how far you are into the song
    progressbar
    This is made with two divs

    <div id="progress-bar">
       <div id="progressed"></div>
    </div>
    
    
    #progress-bar{
        width: 245px;
        height: 20px;
        border: 1px solid white;
        #progressed{
            width: 20%;
            height: 100%;
            background: rgba(255, 255, 255, 0.3);
        }
    }

    and then it is animated to go from 0 to 100 % within 200 seconds:

    @keyframes progress-bar
    {
        from { width: 0; }
        to { width: 100%; }
    }
    
    #progressed{
        animation-name: progress-bar;
        animation-duration: 200s;
    }

    Pretty simple.

  • Then there is the title text, which scrolls if the text is too long to fit, but it stops and starts with an ease-in, ease-out effect.
    titletext

    <span id="text">Michael Jackson - Invincible - Somebody put your hand out</span>
    <span id="text-repeated">Michael Jackson - Invincible - Somebody put your hand out</span>
    
    @keyframes marquee
    {
        from { margin-left: 0; }
        to { margin-left: -506px;}
    }
    
    
    #text{
        animation-name: marquee;
        animation-duration: 20s;
        animation-iteration-count: infinite;
        animation-timing-function: cubic-bezier(0.3,0,0.7,1)
    }

    In this case the animation-timing-function has a standard ease-in/ease-out function, but I felt that it started and stopped to slow, so I decided to make my own. I used cubic-bezier.com to experiment with the values.

  • Finally the entire screen swivels every 30 seconds in a motion, where left and right side of the screen switches place.
    swivel
    This one was  a bit tricky to achieve. First the animation has to do noting for a long time, then the screen swivels and content switches place and then it does nothing for a long time again. Finally the animation is played in reverse.
    I chose to solve the “first nothing happens for a long time” part like this:

    @keyframes rotate-screen
    {
        0% { transform: rotateY(0deg);}
        48% { transform: rotateY(0deg);}
        50% { transform: rotateY(90deg);}
        50.1% { transform: rotateY(-90deg);}
        52% { transform: rotateY(0deg);}
        100% { transform: rotateY(0deg);}
    }
    
    #content{
        animation-name: rotate-screen;
        animation-duration: 30s;
        animation-timing-function: linear;
        animation-iteration-count: infinite;
        animation-direction: alternate;
    }

    This swivels the screen back and forth every 15 seconds (50% of 30 seconds). The turn is performed withing 4% of 30 seconds, so it goes quite fast. It doesn’t go from 0 to 180 degrees, because then everything would be seen from the back (mirrored) in the second half of the animation. The almost instant switch from 90 to -90 degrees makes it look like a smooth turn all the way around while at the same time making sure nothing has it “back turned” to the user.

  • The last part of the puzzle was to make left and right parts of the screen switch sides mid-turn.
    I used the same method as above to move the two parts of the screen:

    @keyframes flip-sides-details
    {
        0%{ left: 300px; }
        50%{ left: 300px; }
        50.1%{ left: 50px; }
        100%{ left: 50px; }
    }

The complete end result looks like this:

I’m sure there are many ways to improve upon this. E.g. I noticed afterwards that it is possible to specify that an animation should not be smooth but instead consist of a defined number of steps. That could be handy for the “switch sides” part of the animation.

Do you have any suggestions for improvements?

Leave a Reply