First of twelve animations.
Loading Animations (13 part series)
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
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
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 thekeySplinesattribute.keyTimes: Defines the specific moments during the animation's duration when thekeyPointswill occur, ranging from0to1. In this case, I defined three moments:0, which is the start;0.5, which is the middle; and1, which is the end.keyPoints: Defines where the circle should be along the path, ranging from0to1. I defined three positions for each moment ofkeyTimes:0, which is the start of the path;1, which is the end of the path; and0, 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 betweenkeyPoints. I defined the same curve for both the forward and return motion:x1 = 0.2,y1 = 0.6,x2 = 0.7, andy2 = 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 thexaxis.repeatCount="indefinite": the animation repeats indefinitely.dur="10000ms": the duration is 10 seconds for the examples.calcMode="spline": to use Bézier curves in thekeySplinesattribute.keyTimes: Defines the specific moments during the animation's duration when thevalueswill be set toattributeName, ranging from0to1. 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; and1, which is the start again.values: Defines the values theattributeNamewill take. I defined five values for each moment ofkeyTimes:10at the start of the arc;8at the peak of the arc;10at the end of the arc;8at the peak again; and10at the start again. That is, the radius increases to10at the start and end of the arc and returns to8at the other moments.keySplines: Defines Bézier curves to smooth the progression betweenvalues. I defined the same two curves for both the forward and return motion:x1 = 0,y1 = 1,x2 = 1, andy2 = 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 from10to8quickly in the first half of the curve.x1 = 1,y1 = 0,x2 = 1, andy2 = 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 from8to10quickly 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 theyaxis.repeatCount="indefinite": the animation repeats indefinitely.dur="10000ms": the duration is 10 seconds for the examples.calcMode="spline": to use Bézier curves in thekeySplinesattribute.keyTimes: Defines the specific moments during the animation's duration when thevalueswill be set toattributeName, ranging from0to1. 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; and1, which is the start again.values: Defines the values theattributeNamewill take. I defined five values for each moment ofkeyTimes:8at the start of the arc;8.6at the peak of the arc;8at the end of the arc;8.6at the peak again; and8at the start again. That is, the radius increases to8.6while the circle is at the peak of the arc, and returns to8at the other moments.keySplines: Defines Bézier curves to smooth the progression betweenvalues. I defined the same two curves for both the forward and return motion:x1 = 0,y1 = 1,x2 = 0.5, andy2 = 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 from8to8.6quickly.x1 = 1,y1 = 0,x2 = 1, andy2 = 0(visualization on cubic-bezier.com). It's a curve that starts slowly and accelerates greatly towards the end. This way, the value goes from8.6to8quickly 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 thevalueswill be set toattributeName, ranging from0to1. In this case, I defined three moments:0, which is the start;0.5, which is the middle; and1, which is the end.values: Defines the values theattributeNamewill take. I defined three values for each moment ofkeyTimes:0, no rotation;180, half turn; and0, 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
calcModeandkeySplines, 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>