Techniques for SVG Animation and Development

Heidi Olsen
7 min readJan 19, 2022

--

[Orginally posted on eROI]

Learn SVG animation techniques including transforming an element on an x- and y-axis, blinking, hover states, clipping paths and scrolling backgrounds.

In part one of this series, Ed took you through how to optimize SVG graphics and why SVG is a smarter choice over the other rasterized options. In addition to being infinitely scalable, we can animate and interact with SVG just like we’re able to do with HTML. SVG has built-in animation syntax called SMIL, but due to its poor support in certain browsers, its best to use CSS and Javascript.

There are three ways you can use an SVG: Embed with the <img> tag, background-image or inline. The problem with embedding an SVG or using it as a background image is you are not able to call the IDs and classes you add to the SVG code. You actually want to just plop the entire SVG code right in your document. If you are trying to keep your code DRY, you can use PHP to include your SVG instead:

<?php echo file_get_contents("illustration.svg"); ?>

PREPARING YOUR FILES

To prepare the SVG for animation, open the file in Illustrator to group shapes and paths into separate objects. Once grouped into separate objects, you can transform the entire object as if it were a single shape. It is also a good idea to remove vector points that aren’t visible to save space or use a tool like SVGO to remove redundant or unnecessary code.

For our first illustration, we would like to animate the rocket and the star field separately, while keeping the background static. In Illustrator I create three groups:

  • Field (background)
  • Stars
  • Rocket

While Illustrator is a widely preferred vector editor, Sketch is also a great option.

I placed them under the main layer “space” which results in the following code:

<svg id="space">
<g id="field">
<!-- Grouped shapes and paths -->
</g>
<g id="stars">
<!-- Grouped shapes and paths -->
</g>
<g id="rocket">
<!-- Grouped shapes and paths -->
</g>
</svg>

If you do not have access to a vector program, you can also edit the code directly by adding the <g> element around the paths and shapes you want in a group, similar to how you would wrap elements in a <div> in HTML.

Here you can create the content that will be used within the module.

ANIMATE ALONG THE X- AND Y-AXIS

https://codepen.io/SwissWebMiss/pen/MKreJm

The goal of our first illustration is to show the rocket floating through space. To illustrate the rocket floating along in zero gravity, we want to animate the “rocket” object along the y-axis.

To animate an object, we will be using the CSS transform property. The transform property allows you to visually manipulate an element by skewing, rotating, translating, or scaling. The translate function moves an element sideways or up and down. If you are moving an object up and down, use transform: translateY(value);, left and right use transform: translateX(value); or if you are moving an object sideways, you can use transform: translate(value, value). The first value will move the element to the right (positive value) and left (negative value). The second value will move it up (negative value) or down (positive value).

Let’s go over how to create keyframes animation. If an animation has the same starting and ending properties, one way to do that is to comma-separate the 0% and 100% values:

@keyframes hover_y {
0%, 100% {
transform: translateY(0);
}
50% {
transform: translateY(10%);
}
}

This will animate our rocket up the Y-Axis 10% of the height. To learn more about Keyframe Animation Syntax and SVG animation, visit CSS-Tricks.

We will next call the animation for our rocket group:

#rocket {
animation-name: hover_y;
animation-duration: 7s;
animation-timing-function: ease-in-out;
animation-iteration-count: infinite;
}

Similar to the padding and margin css properties, we can declare the animation property in shorthand by separating the values with a space:

#rocket {
-webkit-animation: hover_y 7s ease-in-out infinite;
-moz-animation: hover_y 7s ease-in-out infinite;
-o-animation: hover_y 7s ease-in-out infinite;
animation: hover_y 7s ease-in-out infinite;
}

CSS Animation Shorthand Syntax
animation: name duration timing-function delay iteration-count direction fill-mode play-state;

Make sure to add the appropriate prefixes to help the animation be supported in all browsers, including Opera, Firefox, IE and Chrome. Using a plugin like Autoprefixer will add vendor prefixes to CSS for you by using values from Can I Use. To keep the code clean and simple for education purposes, the rest of the code outlined in this blog will not use prefixes.

Next let’s animate our stars along the x-axis:

@keyframes hover_x {
0%, 100% {
transform: translateX(0);
}
50% {
transform: translateX(5%);
}
}
#stars {
animation: hover_x 25s ease-in-out infinite;
}

By animating the star group along the x-axis at a smaller distance over a longer duration, the movement is more subtle. I also want to stay consistent in the way I use easing on the elements in order to create a consistent aesthetic. Now let’s look at the result:

ANIMATE ON HOVER

https://codepen.io/SwissWebMiss/pen/xZpqxB

Next up we will animate a rocket launching into space! Again we will look at our SVG in Illustrator to create the necessary groups to animate. This time we will be creating a group that includes the third rocket as well as three different groups within that group that will include the three different flames: flame1, flame2 and takeoff.

The resulting code looks like this:

<svg>
<g id="background">
</g>
<g id="launchpad">
</g>
<g id="rockets">
<g id="rocket1"></g>
<g id="rocket2"></g>
<g id="rocket3"></g>
<g id="rocket4">
<g id="takeoff"></g>
<g id="flame1"></g>
<g id="flame2"></g>
<g id="body"></g>
</g>
</g>
</svg>

Even though we will only be animating one rocket in this demonstration, we want to have the ability to create additional animations in the future. To start off, we want to animate our flame1 and flame2 to flicker on and off to show the rocket getting ready for lift off as well as to prompt the user to hover over the rocket. To do this we will set the opacity to show and hide our flames:

@keyframes hideshow {
0% { opacity: 1; }
10% { opacity: 1; }
15% { opacity: 0; }
100% { opacity: 0; }
}

We will then add the animation to each group with a slight variation in duration and delay so they stagger in view:

#flame1 {
animation: hideshow 5s 1.5s ease-in-out infinite;
}
#flame2 {
animation: hideshow 5s 0.5s ease-in-out infinite;
}

Next we want to animate the rocket on hover. To do so, we will create an animation that is called on hover:

@keyframes hover_y {
0% {
transform: translateY(0);
}
100% {
transform: translateY(-150%);
}
}

Because we only want the rocket to launch on hover and not be continuous, we will set our off state:

#rocket3 {
transform: translateY(0);
}

And then our hover state:

#rocket3:hover {
animation: hover_y 7s ease-in-out;
}

For a rocket to launch, it needs fire power. We will animate our takeoff group similar to the smaller flames:

@keyframes takeoff {
0% { opacity: 1; }
10% { opacity: 1; }
15% { opacity: 0; }
20% { opacity: 1; }
100% { opacity: 1; }
}

To only have the takeoff show on hover, we have to hide it on our off-state:

#takeoff {
opacity:0;
}

And call the animation when the rocket is hovered:

#rocket3:hover #takeoff {
animation: takeoff 7s 0.5s ease-in-out infinite;
}

Let’s check out the end result:

See the Pen Rocket Launch by Heidi Olsen (@SwissWebMiss) on CodePen.

SVG CLIP PATHS AND BACKGROUND SCROLLING

https://codepen.io/SwissWebMiss/pen/WrdmoQ

Last but certainly not least we look at creating a rotating planet by creating an SVG clipping path and a scrolling background texture. The setup of our SVG file will be as follows:

<svg>
<g id=”background”></g>
<g id=”texture”></g>
<g id=”overlay”></g>
</svg>

First we need to create a clipping path in our SVG. To do so, you will need to define a clipPath in the <defs> element before you define your groups. Defining elements inside of <defs> allow the objects to be reused later in the SVG without being directly rendered. Inside our clipPath we include our circle:

<defs>
<clipPath id="planet" width="465" height="465">
<circle id="clip" fill="none" stroke="#010101" stroke-width="5.5" stroke-miterlimit="10" cx="772.529" cy="261.992" r="232.637"/>
</clipPath>
</defs>

We then create a group called “clip” to wrap around our background texture and add the clip-path property to our CSS:

<g id="clip">
<g id="texture"></g>
</g>
#clip {
clip-path: url(#planet);
}

Next we will animate the background texture to scroll along the x-axis infinitely. To do so, we need to create a seamless, tiling texture so the user cannot identify where it starts and ends. I was able to duplicate the original texture and connect it end to end to create this effect.

Next I create the animation to scroll the background image:

@keyframes rotate { 
0% {
transform: translateX(0);
}
100% {
transform: translateX(-50%);
}
}
#texture {
animation:rotate 25s linear infinite;
}

This time I chose to use linear timing function so it held the same speed from start to end.

Did you know?
You can now use the CSS property mix-blend-mode to apply the blending options used in Photoshop and Illustrator? By adding the class “multiply” to the yellow and blue shapes in the planet, I am able to apply a “multiply” blend mode on the shapes with CSS.

That wraps up just a few ways to animate SVGs. For more inspiration, check out CodePen.

--

--