Skip to main content

Loading Animations: January

· 11 min read

First of twelve animations.


Loading Animations (13 part series)
  1. Introduction
  2. January
  3. February
  4. March
  5. April
  6. May
  7. June
  8. July
  9. August
  10. September
  11. October
  12. November
  13. December

Animation

Result:

Introduction

Using SVG, I created this animation based on the following structure:

<!-- dimensions --><svg>  <defs>    <!-- path traced by the circle -->    <path />  </defs>  <!-- background -->  <rect />  <!-- drawing of the path traced by the circle, for debugging -->  <path />  <!-- circle -->  <ellipse>    <!-- animation that moves the circle along the path -->    <animateMotion>      <mpath />    </animateMotion>    <!-- animation that stretches the circle along the x axis -->    <animate />    <!-- animation that stretches the circle along the y axis -->    <animate />    <!-- animation that rotates the circle -->    <animateTransform />  </ellipse></svg>

How it works

info

To keep the explanation concise, I've left out some elements and attributes from the following code blocks.

Dimensions

Here, I set the animation's width and height to 200 pixels using svg attributes.

Using a rect element, I defined a white background with a gray border and rounded corners. The stroke is drawn centered on the border of the rect, meaning it extends equally inside and outside. Since I set the strokeWidth to 1 pixel, to avoid cutting off half of the stroke, I subtracted 1 pixel from the width (0.5 pixels from each side) and height (0.5 pixels from the top and bottom), then moved it 0.5 pixels along the x and y axes. This ensures that the border isn't clipped by the height and width limits set in the svg element.

Result



Code

<svg  xmlns="http://www.w3.org/2000/svg"  viewBox="0 0 200 200"  width="200"  height="200">  <rect    width="199"    height="199"    x="0.5"    y="0.5"    fill="white"    stroke="lightgray"    strokeWidth="1"    rx="6"  /></svg>

Path

Inside defs, I defined the path that the circle will follow, which is referenced by its id, motion-path. The path is a quadratic curve, defined using the Q command.

After the rect (the background), I defined another path to visualize the motion path, as anything inside defs is not rendered. This second path is removed once the animation is complete.

Result



Code

<svg>  <defs>    <path id="motion-path" d="M50,150 Q100,0 150,150" />  </defs>  <rect></rect>  <path    d="M50,150 Q100,0 150,150"    fill="none"    stroke="lightgray"    strokeWidth="1"  /></svg>

Circle and its animations

info

The final duration of the animation is one and a half seconds. In this section, the animations last for 10 seconds to make them more noticeable.

Animation that follows the path

Initially, I created the animation that defines the full cycle of the circle's motion.

I used an ellipse element to define the circle, as it allows separate control of the radii on the x and y axes. By using different radii, I was able to deform the circle during the animation. The mpath element references the path#motion-path, while the animateMotion element defines the animation.

In the animateMotion element, I defined the attributes as follows:

  • repeatCount="indefinite": the animation repeats indefinitely.
  • dur="10000ms": the duration is 10 seconds for the examples.
  • calcMode="spline": to use Bézier curves in the keySplines attribute.
  • keyTimes: Defines the specific moments during the animation's duration when the keyPoints will occur, ranging from 0 to 1. In this case, I defined three moments: 0, which is the start; 0.5, which is the middle; and 1, which is the end.
  • keyPoints: Defines where the circle should be along the path, ranging from 0 to 1. I defined three positions for each moment of keyTimes: 0, which is the start of the path; 1, which is the end of the path; and 0, which returns to the start of the path. So, at the first moment, the position is at the start of the path, at the second it is at the end, and at the third it is back at the start, completing the animation cycle.
  • keySplines: Defines Bézier curves to smooth the progression between keyPoints. I defined the same curve for both the forward and return motion: x1 = 0.2, y1 = 0.6, x2 = 0.7, and y2 = 0.4 (visualization on cubic-bezier.com). It’s a curve that starts slightly faster, slows down in the middle, and speeds up again at the end. This way, the circle moves quickly at the impact points, while moving slower when it is in the air.

Result



Code

<svg>  <defs></defs>  <rect />  <path />  <ellipse rx="8" ry="8" fill="black">    <animateMotion      repeatCount="indefinite"      dur="10000ms"      calcMode="spline"      keyTimes="0; 0.5; 1"      keyPoints="0; 1; 0"      keySplines="0.2,0.6,0.7,0.4; 0.2,0.6,0.7,0.4"    >      <mpath href="#motion-path" />    </animateMotion>  </ellipse></svg>

Stretching Animations

Next, I created animations that distort the circle in some way.

Animating rx

To convey the idea of impact, I created an animation that stretches the circle horizontally when it hits the ground.

In the animate element, I defined the attributes as follows:

  • attributeName="rx": represents the radius on the x axis.
  • repeatCount="indefinite": the animation repeats indefinitely.
  • dur="10000ms": the duration is 10 seconds for the examples.
  • calcMode="spline": to use Bézier curves in the keySplines attribute.
  • keyTimes: Defines the specific moments during the animation's duration when the values will be set to attributeName, ranging from 0 to 1. In this case, I defined five moments: 0, which is the start of the arc; 0.25, which is the peak of the arc; 0.5, which is the end of the arc; 0.75, which is the peak again; and 1, which is the start again.
  • values: Defines the values the attributeName will take. I defined five values for each moment of keyTimes: 10 at the start of the arc; 8 at the peak of the arc; 10 at the end of the arc; 8 at the peak again; and 10 at the start again. That is, the radius increases to 10 at the start and end of the arc and returns to 8 at the other moments.
  • keySplines: Defines Bézier curves to smooth the progression between values. I defined the same two curves for both the forward and return motion:
    • x1 = 0, y1 = 1, x2 = 1, and y2 = 1 (visualization on cubic-bezier.com). It's a curve that starts fast and slows down in the middle towards the end. This way, the value goes from 10 to 8 quickly in the first half of the curve.
    • x1 = 1, y1 = 0, x2 = 1, and y2 = 0 (visualization on cubic-bezier.com). It's a curve that starts slowly and speeds up greatly at the end. This way, the value goes from 8 to 10 quickly only at the end of the curve.
    • This way, the circle deforms rapidly at the impact points, while it returns to normal when it is in the air.

Only rx animated



Animating ry

To convey the idea of speed, I created an animation that stretches the circle vertically when it is moving through the air. However, this animation does not take the circle's trajectory into account, which is addressed in the next section.

In the animate element, I defined the attributes as follows:

  • attributeName="ry": represents the radius on the y axis.
  • repeatCount="indefinite": the animation repeats indefinitely.
  • dur="10000ms": the duration is 10 seconds for the examples.
  • calcMode="spline": to use Bézier curves in the keySplines attribute.
  • keyTimes: Defines the specific moments during the animation's duration when the values will be set to attributeName, ranging from 0 to 1. In this case, I defined five moments: 0, which is the start of the arc; 0.25, which is the peak of the arc; 0.5, which is the end of the arc; 0.75, which is the peak again; and 1, which is the start again.
  • values: Defines the values the attributeName will take. I defined five values for each moment of keyTimes: 8 at the start of the arc; 8.6 at the peak of the arc; 8 at the end of the arc; 8.6 at the peak again; and 8 at the start again. That is, the radius increases to 8.6 while the circle is at the peak of the arc, and returns to 8 at the other moments.
  • keySplines: Defines Bézier curves to smooth the progression between values. I defined the same two curves for both the forward and return motion:
    • x1 = 0, y1 = 1, x2 = 0.5, and y2 = 1 (visualization on cubic-bezier.com). It's a curve that starts fast and slows down more towards the end. This way, the value goes from 8 to 8.6 quickly.
    • x1 = 1, y1 = 0, x2 = 1, and y2 = 0 (visualization on cubic-bezier.com). It's a curve that starts slowly and accelerates greatly towards the end. This way, the value goes from 8.6 to 8 quickly only at the end of the curve.
    • This way, the circle deforms slightly while it's in the air.

Only ry animated



Result



Code

<svg>  <defs></defs>  <rect />  <path />  <ellipse>    <animateMotion></animateMotion>    <animate      attributeName="rx"      repeatCount="indefinite"      dur="10000ms"      calcMode="spline"      values="10; 8; 10; 8; 10"      keyTimes="0; 0.25; 0.5; 0.75; 1"      keySplines="0,1,1,1; 1,0,1,0; 0,1,1,1; 1,0,1,0"    />    <animate      attributeName="ry"      repeatCount="indefinite"      dur="10000ms"      calcMode="spline"      values="8; 8.6; 8; 8.6; 8"      keyTimes="0; 0.25; 0.5; 0.75; 1"      keySplines="0,1,0.5,1; 1,0,1,0; 0,1,0.5,1; 1,0,1,0"    />  </ellipse></svg>

Rotation Animation

Next, I created the animation that rotates the circle so that the animation of the ry attribute follows the correct trajectory.

In the animateTransform element, I defined the attributes as follows:

  • attributeName="transform": transformation attribute.
  • repeatCount="indefinite": the animation repeats indefinitely.
  • dur="10000ms": the duration is 10 seconds for the examples.
  • type="rotate": rotation type.
  • keyTimes: Defines the specific moments during the animation's duration when the values will be set to attributeName, ranging from 0 to 1. In this case, I defined three moments: 0, which is the start; 0.5, which is the middle; and 1, which is the end.
  • values: Defines the values the attributeName will take. I defined three values for each moment of keyTimes: 0, no rotation; 180, half turn; and 0, no rotation again. That is, while the circle moves between one extreme and the other of the arc, the circle completes a half turn.
  • It is not necessary to define calcMode and keySplines, as the animation is linear.

Result



Code

<svg>  <defs></defs>  <rect />  <path />  <ellipse>    <animateMotion></animateMotion>    <animate />    <animate />    <animateTransform      attributeName="transform"      repeatCount="indefinite"      dur="10000ms"      type="rotate"      values="0; 180; 0"      keyTimes="0; 0.5; 1"    />  </ellipse></svg>

Conclusion

It was a fun animation to create, as it allowed me to explore new techniques with SVG. I hadn't had the chance to use the animateMotion, animateTransform, and mpath elements before, which are essential for creating smoother and more dynamic movements. The animateMotion element, for example, was crucial for making the circle follow a path in a simple way.

Throughout the process, I learned more about how Bézier curves work in the keySplines attribute, which gave me more precise control over the acceleration and deceleration of the animations, allowing me to create more natural transitions. One of the challenges was adjusting these values to achieve an organic movement, and experimenting with different curves was key to achieving the animation I had in mind.

Additionally, studying these techniques expanded my understanding of SVG as a whole, which will certainly be useful for future posts.

Result



Code

<svg  xmlns="http://www.w3.org/2000/svg"  viewBox="0 0 200 200"  width="200"  height="200">  <defs>    <path id="motion-path" d="M50,150 Q100,0 150,150" />  </defs>  <rect    width="199"    height="199"    x="0.5"    y="0.5"    fill="white"    stroke="lightgray"    strokeWidth="1"    rx="6"  />  <ellipse rx="8" ry="8" fill="black">    <animateMotion      repeatCount="indefinite"      dur="1500ms"      calcMode="spline"      keyTimes="0; 0.5; 1"      keyPoints="0; 1; 0"      keySplines="0.2,0.6,0.7,0.4; 0.2,0.6,0.7,0.4"    >      <mpath href="#motion-path" />    </animateMotion>    <animate      attributeName="rx"      repeatCount="indefinite"      dur="1500ms"      calcMode="spline"      values="10; 8; 10; 8; 10"      keyTimes="0; 0.25; 0.5; 0.75; 1"      keySplines="0,1,1,1; 1,0,1,0; 0,1,1,1; 1,0,1,0"    />    <animate      attributeName="ry"      repeatCount="indefinite"      dur="1500ms"      calcMode="spline"      values="8; 8.6; 8; 8.6; 8"      keyTimes="0; 0.25; 0.5; 0.75; 1"      keySplines="0,1,0.5,1; 1,0,1,0; 0,1,0.5,1; 1,0,1,0"    />    <animateTransform      attributeName="transform"      repeatCount="indefinite"      dur="1500ms"      type="rotate"      values="0; 180; 0"      keyTimes="0; 0.5; 1"    />  </ellipse></svg>

Recommended reading