Its Pullups, but in SVG Animations

Scalable Vector Graphics, SVGs are cool because they can be zoom infinitely and still not get pixelated. They are very lite and are also a web standard. That's why they are used primarily for logos. Now lets set the case. Your boss tells you to create a svg logo, which you were able to do with the help of apps like Inkscape. After seeing it, your boss then tells you to add some loading animations to increase the websites aesthetic. So how do you do it?

SVG Brush-up

Now to make this blog interesting I animated a figure doing pull-ups. As you may remember, SVGs are declared inside the svg tag as a child of the body in HTML. There are various types of SVG elements like circle, line etc.

There are two ways of doing SVG animation. First is through the <animate/> tag. This technique is also called SMIL. I believe this will be deprecated soon, but it is something you should learn. Second is through CSS. In this blog I will go through SMIL and in the next one over the CSS way.

In SMIL, one suggestion that I would give is that, to declare SVG styles in CSS, unless we want to animate it. We do this for just synatic sugar. First lets create our figure.

<svg width='500' height='800'>
    <circle id='head'cx='200' cy='300' r='60'>
    </circle>
    <polyline id='body' points='200,365 200,550' stroke-linecap="round">
    </polyline>

    <polyline id='armR' points='200,365 255,525' stroke-linecap="round">
    </polyline>

    <polyline id='armL' points='200,365 145,525' stroke-linecap="round">
    </polyline>

    <polyline id='legR' points='200,550 255,695' stroke-linecap="round">            
    </polyline>

    <polyline id='legL' points='200,550 145,695' stroke-linecap="round">
    </polyline>

    <polyline id='rod' points="0,300 400,300" stroke-linecap="round"></polyline>
</svg>    
body {
    margin: 0;
    padding: 0%;
    overflow: hidden;
    background-color: rgb(247, 202, 201);
}
#head {
    fill: None;
    stroke:black ;
    stroke-width:10; 
    fill:rgb(243, 224, 190);
}
#body {
    fill:None;
    stroke:black;
    stroke-width: 10;
}
#armR {
    fill:None;
    stroke:black;
    stroke-width: 10;
}
#armL {
    fill:None;
    stroke:black;
    stroke-width: 10;
}
#legR {
    fill:None;
    stroke:black;
    stroke-width: 10;
}
#legL {
    fill:None;
    stroke:black;
    stroke-width: 10;
}
#rod {            
    fill:None;
    stroke:rgb(100, 100, 100);
    stroke-width: 20;
}

Animating

The drawback of SMIL is that animation is done every frame. Whenever we want an object to move from place A to B to C, we would have write the animation for each movement and give delay each time. Its scarier done then said. 

<circle id='head'cx='200' cy='300' r='60'>
    <animate attributeName='cy' dur='0.5s' to='300' fill='freeze' end='4s' begin='1s' repeatCount="indefinite" />
    <animate attributeName='cy' dur='2s' to='270' fill='freeze' begin='5s' repeatCount="indefinite" />
</circle>

In the above code, for the head, we first define what we want to animate, is it the radius, color, line-width or position. In our case it is the y-coordinate, since in pull ups you move up and down. After that we define the duration of the animation and position/state we want it to reach. Fill defines whether to return to the initial position or to stay after completion. End defines when we want to end the animation. Begin is the delay we want before the animation. And finally we say that this animation will be indefinite or will run infinite times.

Each state we want the svg to be in, is declared individually and the delay for the next state is based on the timing of the previous state. If this doesn't exhaust you, then you must be coding in assembly. We do this for every svg part. The other body parts i our case, are animated based on points, since they are lines. All points defined, are connected/joined while rendering.

<polyline id='body' points='200,365 200,550' stroke-linecap="round">
    <animate attributeName='points' dur='0.5s' to='200,365 200,550' fill='freeze' end='4s'  begin='1s' repeatCount="indefinite" />
    <animate attributeName='points' dur='2s' to='200,335 200,520' fill='freeze' begin='5s' repeatCount="indefinite"  />
</polyline>

The animation should thus look like this.

Until, this person, Jolly, does some pullups, you can go over the full code, which will be available on my GitHub Page. Until the next blog,

Happy SMILing!!

Comments

Most Popular Posts