- WaSQL Wired
- Posts
- SMIL - SVG Animations without JS or CSS
SMIL - SVG Animations without JS or CSS
An in depth look at SMIL for svg animation effects without using JavaScript or CSS.
SMIL is a native SVG animation specification that allows you to animate elements without JavaScript. SMIL is supported in Chrome, Firefox, Safari, and the new Chromium-based Edge. It works by adding special animation elements as children of the SVG elements you want to animate. There are four main Animation Elements
animate - Changes any single attribute over time
animateTransform - Animates transform attributes (rotate, scale, etc.)
animateMotion - Moves an element along a path
set - Sets an attribute value for a specified duration without transition
In these animation elements there are essential attributes that define what the animation does.
attributeName - Specifies which attribute to animate
from, to, values - Define the animation values
dur - Duration of animation
begin - When to start the animation
fill - What to do after animation completes ("freeze" or "remove")
repeatCount - Number of repetitions ("indefinite" for endless)
calcMode - How intermediate values are calculated
Now that we understand the parameters and rules lets dig into how to use each of these elements and provide some examples.
This animates a rectangle's width from 50px to 250px over 3 seconds, repeating indefinitely.
The following example animates a circle's horizontal position with custom timing - moving 70% of the distance in the first 70% of the time.
Notice the keyTimes
attribute the previous example. keyTimes in SMIL animations is a powerful timing control mechanism that works together with the values
attribute to precisely define the timing of an animation sequence. Here is how keyTimes
works:
keyTimes
is a semicolon-separated list of values between 0 and 1Each value represents a point in time as a fraction of the total duration
The first value must be 0, and the last value must be 1
The number of values in
keyTimes
must match the number of values in thevalues
attributeValues must be in ascending order
You can also have Multiple Simultaneous Animations attached to an element. The following example applies three simultaneous animations to a circle: position, color, and size.
Using the animateMotion element you can define motion along a path. The following example moves a circle along a curved path while automatically rotating to follow the path's direction.
You can use the begin attribute to have one animation begin when another one ends. The following example shows a circle animation that starts when the rectangle animation ends, creating a sequence.
The begin
attribute in SMIL animations is quite versatile, accepting various value types to control when an animation starts. Here are the options available for the begin
attribute:
Time Values
Clock values: Direct time specification
begin="5s"
- Start after 5 seconds after document loadbegin="01:30"
- Start after 1 minute, 30 secondsbegin="00:00:10"
- Start after 10 seconds (hours:minutes)
Element events: Start animation when an event occurs on an element
begin="elementID.click"
- Start when element with ID 'elementID' is clickedbegin="elementID.mouseover"
- Start when mouse hovers over the elementbegin="elementID.mouseout"
- Start when mouse leaves the elementbegin="elementID.focus"
- Start when element receives focusbegin="elementID.blur"
- Start when element loses focus
Document events: Start based on document-level events
begin="SVGLoad"
- Start when SVG document loadsbegin="DOMContentLoaded"
- Start when DOM content is loadedbegin="load"
- Start when the entire page loadsbegin="resize"
- Start when the window is resizedbegin="scroll"
- Start when scrolling occurs
Animation Synchronization
Animation-based timing: Start relative to other animations
begin="animID.begin"
- Start when animation with ID 'animID' beginsbegin="animID.end"
- Start when animation with ID 'animID' endsbegin="animID.repeat(2)"
- Start when animation with ID 'animID' begins its 2nd repeat
Offset synchronization: Start with offset from other animation events
begin="animID.end+2s"
- Start 2 seconds after animation 'animID' endsbegin="elementID.click+500ms"
- Start 500ms after element click
Multiple Begin Times
Multiple values: List of values separated by semicolons
begin="2s; 10s"
- Start at 2 seconds and again at 10 secondsbegin="button.click; anim2.end+1s"
- Start on button click or 1s after anim2 ends
Special Values
Indefinite: Animation won't start automatically
begin="indefinite"
- Animation starts only when triggered by script
calcMode - Lastly, lets talk about calcMode
. The calcMode
attribute in SMIL animations determines how intermediate values are calculated between keyframes during an animation. It controls the pacing and interpolation between animation values, affecting how smooth or abrupt transitions appear. calcMode accepts the following values:
linear
(default)Creates a uniform, constant-speed animation
Transitions occur at a steady pace between values
Equal change per unit of time
discrete
No interpolation between values
Animation jumps directly from one value to the next at specified times
Creates step-like, sudden changes
paced
Ensures the animation moves at a constant overall speed
Automatically adjusts timing to normalize the pace across all segments
Ignores
keyTimes
values if specified
spline
Uses cubic Bezier curves to create custom acceleration and deceleration
Requires
keySplines
attribute to define control pointsEnables easing effects like ease-in, ease-out, etc.
Here are examples demonstrating each of the calcMode options:
Linear
Discrete
Paced
Spline
Of course you can have multiple objects in the same svg file as the following example shows.
So now you know how to use SMIL inside of svg files to produce cool animation effects. Thanks for reading. If you liked it please share!