SVG

Animation

SVG can be animated by CSS, SMIL or JavaScript

SVG
Animation


Ways to Animate

SVG can be animated by the following ways:


CSS Animation

Line Animation

We can animate stroke-dashoffset of any shape to make the animation. To make it work, we first have to define stroke-dasharray for the animated element.

There are two options:

  1. Short Dash - a shape has stroke-dasharray smaller than the shape total path length.
  2. Long Dash - a shape has stroke-dasharray longer than the shape path length.
Short stroke-dasharray:

Example:

The following demonstrates the first option (see more in Line Animation Demo). All the three shapes in this example have identical code. The difference is the stroke-dasharray of each shape. The shape on the left has no dash and therefore it doesn't animate.

No stroke-dasharray stroke-dasharray="20 20" stroke-dasharray="200 200"

Example:

stroke-dasharray="28 28"

Aall the examples above are of the class 'stroke-dashoffset-anim'. The CSS animation is defined as:

CSS:
@keyframes stroke-dashoffset-anim {
    0%,
    100% {
        stroke-dashoffset: 0;
    }
    50% {
        stroke-dashoffset: 1000;
    }
}

.stroke-dashoffset-anim {
    animation: stroke-dashoffset-anim 10s reverse infinite;
}

The steps to define the animation are the following:

  1. Define a shape/path with stroke.
  2. Define stroke-dasharray for the animated object.
  3. Define @keyframes to change the "offset" of the stroke, which moves the position of the dashes. For example:
    CSS:
    .path {
      stroke-dasharray: 100;
      animation: dash 5s linear;
    }
    
    @keyframes dash {
        from { stroke-dashoffset: 0; }
        to { stroke-dashoffset: 1000; }
    }

Long stroke-dasharray:

We can create an animated line-drawing effect using CSS. The animation would require you to know the total length of the path you’re animating and then to use the stroke-dashoffset and stroke-dasharray SVG properties to achieve the drawing effect.

You can animate it with CSS using the following rules:

CSS:
#path {
    stroke-dasharray: pathLength;
    stroke-dashoffset: pathLength;
    /* transition stroke-dashoffset */
    transition: stroke-dashoffset 2s linear;
}

svg:hover #path {
  stroke-dashoffset: 0;
}

Example:

The following demonstrates long stroke-dasharray with animating stroke-dashoffset to zero.

stroke-dasharray="4000"
CSS:
@keyframes long-stroke-anim {
    to {
        stroke-dashoffset: 0;
    }
}

#long-stroke-anim {
    animation: long-stroke-anim 10s infinite;
}

Example:

The following demonstrates long stroke-dasharray with stroke-dashoffset to zero on hover. There are two identical pathes: one is white without animation and the second is black with bigger stroke width and with offset animation on hover.

Hover Me
CSS:
#line {
    stroke: black;
    stroke-dasharray: 3000;
    stroke-dashoffset: 3000;
    stroke-width: 4;
    transition: stroke-dashoffset 20s linear;
}

svg:hover #line {
    stroke-dashoffset: 0;
}

Most of the examples you see of SVG line animations use JavaScript. That's because it's hard to know what the length of that stroke actually is. Ues getTotalLength() function to get the path length inJavaScript.


Motion Path Animation

For more details see Motion Path Specification. Look also in CSS Motion Path as of October 2016 and CSS Motion Path beyond the Big Three Properties 2018.

See also Motion Path Examples.

One of the most compelling things that SMIL offers for realistic motion in SVG is motion along a path. Now it becomes possible also with CSS. Chrome recently announced their initial support of the CSS Motion Path module.

CSS Motion Paths allow web pages to animate graphical objects along paths, specified using CSS. It introduces the following new CSS properties: offset-path, offset-distance (position on offset-path), and motion-rotation (auto, reverse <angle>).

Motion-rotation:

  • "auto" means the element will rotate with the path.
  • "reverse" means the element will also rotate with the path, but it will add 180 degress, so it will be facing backward.
  • "auto Xdeg" (or "reverse Xdeg") will do the same except add X degrees.
  • "Xdeg" will no longer rotate with the path, the element will stay fixed facing the same direction.
#

A motion path may consist of a basic shapes like circle, polygon. To allow curves and sub-paths, the specification adds the path() function in addition to the existing basic shapes functions. The path() function takes an SVG Path string as input.

CSS:
#mp-1 {
    offset-path: path('M 250,80 H 50 Q 30,80 30,50 Q 30,20 50,20 H 250 Q 280,20,280,50 Q 280,80,250,80Z');
    animation: motionpath 10s linear infinite both;
}

@keyframes motionpath {
    100% {
        offset-distance: 100%;
    }
}

HTML:
<svg width="300px" height="100px" fill="transparent">
    <path stroke="red" d='M 250,80 H 50 Q 30,80 30,50 Q 30,20 50,20 H 250 Q 280,20,280,50 Q 280,80,250,80Z' />
    <rect x="0" y="0" width="300" height="100" stroke="black" stroke-width="1" />
    <rect id="mp-1" x="0" y="0" width="20" height="20" fill="blue" stroke="black" stroke-width="1" />
</svg>
CSS:

#mp-car {
    offset-path: path('M62.9 14.9c-25-7.74-56.6 4.8-60.4 24.3-3.73 19.6 21.6 35 39.6 37.6 42.8 6.2 72.9-53.4 116-58.9 65-18.2 191 101
    215 28.8 5-16.7-7-49.1-34-44-34 11.5-31 46.5-14 69.3 9.38 12.6 24.2 20.6 39.8 22.9 91.4 9.05 102-98.9 176-86.7 18.8 3.81 33 17.3
    36.7 34.6 2.01 10.2.124 21.1-5.18 30.1');
    animation: motionpath 10s linear infinite;
}

@keyframes motionpath {
    100% {
        offset-distance: 100%;
    }
}

HTML:
<svg width="100%" height="150">
        <path stroke="red" fill="none" d='M62.9 14.9c-25-7.74-56.6 4.8-60.4 24.3-3.73 19.6 21.6 35 39.6 37.6 42.8
        6.2 72.9-53.4 116-58.9 65-18.2 191 101 215 28.8 5-16.7-7-49.1-34-44-34 11.5-31 46.5-14 69.3 9.38 12.6 24.2 20.6 39.8 22.9
        91.4 9.05 102-98.9 176-86.7 18.8 3.81 33 17.3 36.7 34.6 2.01 10.2.124 21.1-5.18 30.1' />
        <image id="mp-car" x="-30" y="-19" width="60" height="38"  xlink:href="../images/car-small.png" />
</svg>
CSS:
#star {
    offset-path: path(' M119 60.2l34.4-50.3-1.7 60.9 57.5-20.4L172 98.7l58.5 17.3-58.5 17.2
                37.2 48.4-57.5-20.5 1.7 61-34.4-50.3-34.5 50.3 1.7-61-57.5 20.5 37.2-48.4L7.4
                116l58.5-17.3-37.2-48.3 57.5 20.4-1.7-60.9z');
    animation: motionpath 10s linear infinite both;
}
@keyframes motionpath {
    100% {
        offset-distance: 100%;
    }
}

HTML:
<svg width="239.8" height="232.8" viewBox="0 0 239.8 232.8">
    <g fill="none" stroke="red" >
        <path d="M84.1 222l-56-40.6-21.4-65.7 21.4-65.9L84.1 9h69.3l56 40.8 21.4 65.9-21.4 65.7-56 40.6z" />
        <path  d="M119 60.2l34.4-50.3-1.7 60.9 57.5-20.4L172 98.7l58.5 17.3-58.5 17.2 37.2
                48.4-57.5-20.5 1.7 61-34.4-50.3-34.5 50.3 1.7-61-57.5 20.5 37.2-48.4L7.4 116l58.5-17.3-37.2-48.3
                57.5 20.4-1.7-60.9z" />
        <circle id="star" r="20" stroke="black" fill="blue" />

    </g>
</svg>

SMIL

Beside the CSS, SVG has another way do animation built right into the SVG syntax itself.

SMIL can animate any SVG presentation attribute. It allows complex animation. For example we can animate an object along an arbitrary path using animateMotion SVG element.

Animation is done by manipulating the attributes of shapes over time. This is done using one or more of the 5 SVG animation elements:

See SMIL Animation.

Example:

<svg width="300" height="100">
    <rect x="0" y="0" width="300" height="100" stroke="red" fill="transparent" stroke-width="1" />
    <circle cx="0" cy="50" r="15" fill="blue" stroke="black" stroke-width="1">
        <animate attributeName="cx" from="0" to="300" dur="5s" repeatCount="indefinite" />
    </circle>
</svg>