Creative Coding with SVGs
zuubaDigital

<animateMotion>

The animateMotion element allows you to animate an object along a path.

Let’s start by animating a circle along a star path. First we create the circle and the star. Make sure to put the circle at the 0,0 coordinate.

1 2 3 4 5 6 7 8 9 <svg width="500" height="500" viewBox="0 0 500 500"> <path d="M249.5 97L283.738 202.375H394.536L304.899 267.5L339.137 372.875L249.5 307.75L159.863 372.875L194.101 267.5L104.464 202.375H215.262L249.5 97Z" fill="none" stroke="black" stroke-width="2" /> <circle cx="0" cy="0" r="10" fill="black"></circle> </svg>

Now let’s add the animateMotion element. You’ll see that it looks similar to what you’d see with <animate> and <animateTransform> except for the path attribute.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <svg width="500" height="500" viewBox="0 0 500 500"> <path d="M249.5 97L283.738 202.375H394.536L304.899 267.5L339.137 372.875L249.5 307.75L159.863 372.875L194.101 267.5L104.464 202.375H215.262L249.5 97Z" fill="none" stroke="black" stroke-width="2" /> <circle cx="0" cy="0" r="10" fill="black"> <animateMotion dur="8s" begin="0s" repeatCount="indefinite" path="" /> </circle> </svg>

Now let's copy the “d” contents of the path and paste it into the “path” attribute of the animateMotion element.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <svg width="500" height="500" viewBox="0 0 500 500"> <path d="M249.5 97L283.738 202.375H394.536L304.899 267.5L339.137 372.875L249.5 307.75L159.863 372.875L194.101 267.5L104.464 202.375H215.262L249.5 97Z" fill="none" stroke="black" stroke-width="2" /> <circle cx="0" cy="0" r="10" fill="black"> <animateMotion dur="8s" begin="0s" repeatCount="indefinite" path="M249.5 97L283.738 202.375H394.536L304.899 267.5L339.137 372.875L249.5 307.75L159.863 372.875L194.101 267.5L104.464 202.375H215.262L249.5 97Z" /> </circle> </svg>

Something that may have been lost in the example is how the object being animated (in this case, the circle) has to be centered at the origin. Check out what happens when the circle is NOT centered on the origin.

1 <circle cx="50" cy="50" r="10" fill="black"> ...

Let’s try to replicate a simple version of the car traveling on the road shown in the intro to this section. Instead of a car, we’ll use a simple rectangle. Notice how the rectangle is drawn so that it’s center sits at the origin.

1 2 3 4 5 6 <svg width="500" height="500" viewBox="0 0 500 500"> <path .../> <rect x="-15" y="-7" width="30" height="14" fill="black"> <animateMotion .../> </rect> </svg>

The rectangle is properly centered, but we want its orientation to match that of the path, so that it always points in the direction of the animation.

Fortunately for us, it’s an easy fix. Simply add the rotate attribute and set it to “auto.”

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <svg width="500" height="500" viewBox="0 0 500 500"> <path d="M249.5 97L283.738 202.375H394.536L304.899 267.5L339.137 372.875L249.5 307.75L159.863 372.875L194.101 267.5L104.464 202.375H215.262L249.5 97Z" fill="none" stroke="black" stroke-width="2" /> <rect x="-15" y="-7" width="30" height="14" fill="black"> <animateMotion rotate="auto" dur="8s" begin="0s" repeatCount="indefinite" path="M249.5 97L283.738 202.375H394.536L304.899 267.5L339.137 372.875L249.5 307.75L159.863 372.875L194.101 267.5L104.464 202.375H215.262L249.5 97Z" /> </rect> </svg>

What if we want to animate a more complex object around the path, like this car?



Let’s add the car to <defs>, and place it in the svg with the <use> element

1 2 3 4 5 6 7 8 9 <svg width="500" height="500" viewBox="0 0 500 500"> <defs> <g id="nice_car"> <path .../> </g> </defs> <path .../> <use href="#nice_car" x="0" y="0" /> </svg>

Now we’ll animate it. As you can see, the animation is off, just like the rectangle we animated earlier.

1 2 3 4 5 6 7 8 9 10 11 12 <svg width="500" height="500" viewBox="0 0 500 500"> <defs> <g id="nice_car"> <path .../> </g> </defs> <path .../> <use href="#nice_car" x="0" y="0"> <animateMotion dur="8s" begin="0s" repeatCount="indefinite" rotate="auto" path="M249.5 97L283.738 202.375H394.536L304.899 267.5L339.137 372.875L249.5 307.75L159.863 372.875L194.101 267.5L104.464 202.375H215.262L249.5 97Z" /> </use> </svg>

In order to center the car at the origin, we’ll need to add a transform to it’s group. Since the car is 50x30, we’ll need to translate it by -25 and -15 to center it. Now the animation looks much better!

1 2 3 4 5 6 7 8 9 10 11 12 <svg width="500" height="500" viewBox="0 0 500 500"> <defs> <g id="nice_car" transform="translate(-25 -15)"> <path .../> </g> </defs> <path .../> <use href="#nice_car" x="0" y="0"> <animateMotion dur="8s" begin="0s" repeatCount="indefinite" rotate="auto" path="M249.5 97L283.738 202.375H394.536L304.899 267.5L339.137 372.875L249.5 307.75L159.863 372.875L194.101 267.5L104.464 202.375H215.262L249.5 97Z" /> </use> </svg>

As a final touch, lets swap out the star path for another star with rounded corners, so the car can turn more smoothly:

mpath

If you want multiple objects to move along the same path, you can use the mpath element to specify the path for animateMotion element (instead of using the path attribute). Pass the path via the href attribute.

<mpath href="#path-id" />
1 2 3 4 5 6 7 8 <svg width="500" height="500" viewBox="0 0 500 500"> <path id="starfish" .../> <use href="#nice_car" x="0" y="0" fill="red"> <animateMotion dur="8s" begin="0s" repeatCount="indefinite" rotate="auto"> <mpath href="#starfish" /> </animateMotion> </use> </svg>

Check out the full example on codepen.

animate attributes

  1. id - needed to chain animations, i.e begin=”first.end”
  2. href - (needed if animate element is not encapsulated by the element you wish to animate)
  3. attributeName=<name of attribute>
  4. from - <value>
  5. to - <value>
  6. begin - <value>
  • time in seconds - ex. from=”2s”
  • time based on beginning of another animation -ex. from=”firstAnim.begin”,
  • time based on end of another animation - ex. from=”firstAnim.end”
  • time based on begin or end of another animation + time offset - ex. from=”firstAnim.end+2s”
  • click interaction - ex. begin=”click”
  1. dur - <value>
  • time in seconds (s) or milliseconds (ms) - dur=”5s”
  1. repeatCount - <value>
  • number - repeatCount=”4”
  • indefinite- ex. repeatCount=”indefinite”
  1. fill
  • freeze
  • remove
  1. calcMode - <value> - used to set pacing, animation curves, type of motion
  • linear
  • discrete
  • paced
  • spline
  1. values
  • Animation values, used with keyTimes to dictate the pace of the animation - ex. values=”20; 50; 300”
  1. keyTimes
  • List of values from 0 to 1 used to to dictate the pace of the animation - ex. keytimes=”0; .3; .9; 1”

additional attributes for animateTransform:

  1. attributeName - ”transform”
  2. transform-origin - “<x> <y>” default is “0 0”
  3. type - ”<type keyword>”
  • translate
  • rotate
  • scale
  • skewX, skewY

additional attributes for animateMotion:

  1. path - ”<path data>”
  2. mpath - <mpath href="#id-of-path" />