Svgjqueryhow To Use
Svgjqueryhow To Use
“animateTransform” for
Inline SVG Animation
by Kezz Bracey21 Oct 2014
Difficulty:BeginnerLength:MediumLanguages:
SVG AnimationSketchUI Design
Today we’ll be stepping you through the basics of using animateTransform to
generate inline animations with SVG (scalable vector graphics).
If you’re brand new to SVG I recommend checking out Getting Started With Scalable
Vector Graphics (SVG) to bring you up to speed.
The techniques you’ll be learning will allow you to create sophisticated icon and
image animations without a single GIF, JPEG or PNG, with zero JavaScript, and
without the faintest whisper of Flash.
The animations you create will be easy to edit later because they’re pure code, and the
results will only take up a couple of KB of precious bandwidth when they’re viewed.
Before We Begin
To animate SVG shapes you’ll first need the ability to create them. I’ve found the
easiest way to create SVGs is to use Sketch from Bohemian Coding. If you don’t own
Sketch you can grab a free 30-day trial for the purposes of this tutorial.
We’ll be manipulating the SVG code, so after you’ve drawn a shape in Sketch, create
a slice around it and export that slice as an SVG file.
You’ll then be able to open your exported file in a code editor (like Sublime Text) and
copy the SVG code from within. All you need is the code from the
opening <svg> tag to the closing </svg> tag.
For example, Sketch generates the following SVG code for the blue rectangle pictured
above:
1<svg width="100px" height="125px" viewBox="0 0 100 125" version="1.1" xmlns="http://www.w3.o
2xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
3 <!-- Generator: Sketch 3.1 (8751) - http://www.bohemiancoding.com/sketch -->
4 <title>Slice 2</title>
<desc>Created with Sketch.</desc>
5 <defs></defs>
6 <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type
7 <rect id="Rectangle-1" fill="#3C81C1" sketch:type="MSShapeGroup" x="0" y="0" width="1
8 </g>
9</svg>
To make the code visually easier to work with, we’ll make a couple of little changes
to the code.
Set the svg element’s width and height to 100% and delete the viewBox setting.
Also delete the Generator comment, and the title , desc , defs and g elements.
You should end up with something like this:
1 <svg version="1.1" width="100%" height="100%" xmlns="http://www.w3.org/2000/svg" xmlns:xl
xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
2 <rect id="Rectangle-1" fill="#3C81C1" sketch:type="MSShapeGroup" x="0" y="0" width="100"
3 </svg>
Drop that code into an HTML document and, when viewed in the browser, you should
see the same blue rectangle on your page as you saw in Sketch:
Note: The above image includes an X and Y axis in the background as you'll need to
understand these in order to create your animations. You’ll learn why shortly.
2. scale
3. rotate
4. skewX
5. skewY
The X axis is the horizontal line in 2D space, and the Y axis is the vertical
line. By default, every shape starts at a position of 0 on both
the X and Y axis.
From the 0 position on the X axis, positive values correspond with moving to
the right, and negative values correspond with moving to the left.
From the 0 position on the Y axis, positive values correspond with moving
downwards, and negative values correspond with moving upwards.
If this doesn't make complete sense yet don’t worry, as it will become much clearer as
you see the examples of each type of transformation below.
Don’t worry about the code for these transformations either, as we’ll cover that when
we move onto creating animations. To start with I just want you to get the essentials
down on what the five types of transformation actually do.
Translate
This shifts the shape’s position on the X axis (horizontal) and Y axis (vertical).
For example, here is our blue rectangle with translate values of 150 on
the X (horizontal) axis and 20 on the Y (vertical) axis:
Remember from the section above that positive values on the X axis correspond with
moving to the right, and positive values on the Y axis correspond with moving
downwards.
By setting the translate value for X to positive 150 , our rectangle has moved to
the right by 150 pixels. Setting the value for Y to positive 20 has moved our
rectangle down by 20 pixels.
Scale
This multiplies the shape’s overall size on the X axis (width) and Y axis (height).
Scale settings work as multipliers of the shape’s original size. For example, if we set
the X scale to 3 it would make the shape three times wider. If we set the Y scale
to 1.25 it would make the shape one and a quarter times higher, like so:
Al
so translated (150, 20)
Rotate
This rotates the shape around a given point by degrees.
Rotation works by setting the number of degrees by which you want to rotate the
shape. For example, here is our rectangle rotated by 45 degrees:
Al
so translated (150, 20)
By default the shape will rotate around its top left corner but you can also have it
rotate around a different point. We’ll cover how that’s done later in the tutorial.
SkewX
This skews the shape along the X (horizontal) axis.
Skewing along the X axis also works in degrees. For example, in the image below our
rectangle is skewed by 20 degrees along the X axis:
Al
so translated (150, 20)
SkewY
This skews the shape along the Y (vertical) axis by degrees.
SkewY works in exactly the same way as SkewX , only the transformation happens
vertically along the Y axis like so:
Al
so translated (150, 20)
Animating Transformations
Now that you know what transforms actually do, you can start creating animations
between different states of transformation. The basic process has three steps:
We then looked at an example of that same blue rectangle with translate settings
of 150 20 applied, i.e. 150 on the X axis and 20 on the Y axis. We’ll set this
position as our to state.
Using animateTransform we can make the rectangle slide smoothly between
our from and our to states over a period of two seconds.
Your SVG shape, in this case rectangle, will need to have both opening and closing
tags e.g. <rect></rect> .
The animateTransform attribute should be placed in between these tags like so:
01 <rect id="Rectangle-1" fill="#3C81C1" sketch:type="MSShapeGroup" x="0" y="0" width="100"
<animateTransform attributeName="transform"
02
type="translate"
03 from="0 0"
04 to="150 20"
05 begin="0s"
06
07 dur="2s"
repeatCount="indefinite"
08 />
09 </rect>
10
Take a look at the properties that have been set within the animateTransform tag.
These are what control how your animation runs.
The value for begin is set to 0s , meaning the animation will begin zero seconds
after load, and dur is set to 2s , meaning the animation will run over a period of two
seconds. Finally, we’ve included repeatCount set to indefinite meaning the
animation will replay on loop.
For example, we can use the following animateTransform settings to scale our
rectangle up to the size you saw in the earlier section on scale transformation:
1
<animateTransform attributeName="transform"
2 type="scale"
3 from="1 1"
4 to="3 1.25"
5 begin="0s"
dur="2s"
6
repeatCount="0"
7 />
8
Because scale transformation settings multiply the shape’s original size we start with a
value of 1 1 on the from setting. Doing this sets its original size at a multiplication
of 1.
Our to setting of 3 1.25 will animate our scale transformation up to three times the
original width on the X axis, and one and a quarter the original height on the Y axis.
Note: You’ll find your actual in-browser animations run much smoother than the
screen capture GIF you see above.
Animate Multiple Transformations
We can also combine the two animations we’ve created so far, to both translate and
scale at the same time. You can only use a single animateTransform tag inside
your rect tag, so to use multiple animations you'll need to incorporate a set
of g tags, which represent a group of SVG objects.
To make this work, add opening and closing <g></g> tags around your
existing rect tags:
01
02 <g>
03 <rect id="Rectangle-1" fill="#3C81C1" sketch:type="MSShapeGroup" x="0" y="0" width="100"
<animateTransform attributeName="transform"
04 type="scale"
05 from="1 1"
06 to="3 1.25"
07 begin="0s"
dur="2s"
08 repeatCount="0"
09 />
10 </rect>
11 </g>
12
Then add your second animation outside the closing </rect> tag, but before the
closing </g> tag. In this case we’re going to reintroduce our translate transformation:
01
02 <g>
03 <rect id="Rectangle-1" fill="#3C81C1" sketch:type="MSShapeGroup" x="0" y="0" width="100"
<animateTransform attributeName="transform"
04 type="scale"
05 from="1 1"
06 to="3 1.25"
07 begin="0s"
08 dur="2s"
repeatCount="0"
09 />
10 </rect>
11 <animateTransform attributeName="transform" type="translate" from="0 0" to="150 20" begi
12 </g>
13
We now have both scale and translate transformations animating simultaneously:
You can use animateTransform once per shape or group. If you need to add more
animations, wrap another set of group tags around your code and nest your
additional animateTransform tag inside it.
Let’s take a quick look at the remaining three transformation types, each one created
by changing only the type , from and to settings, and also combined with our
original translation animation.
In this example type has been set to rotate , from has been set to 0 to begin with
no rotation, and to has been set to 45 so we rotate 45 degrees over two seconds:
SkewX and SkewY Animation (plus Translation)
An
imated skewX transformation
An
imated skewY transformation
Revolve Axis
Note that this time I have also included an extra two numbers in both
the from and to settings. This tells the animation to revolve around a point on the
shape’s own internal X / Y axis of 18 18 , i.e. the center of the shape given it is
36x36 pixels in size.
Wrapping Up
If you haven’t yet taken a run at SVG animation you should now have the tools you
need to get a good solid start.
Further Reading
Great Codepen example of animated loader SVGs
More about how animateTransform works over at W3C.
Grab yourself a copy of the source for this tutorial, play around with the
examples and have fun creating your own inline SVG animations!
Kezz Bracey
Hi there. I'm a designer and coder who specializes in web design and development and also
works in the areas of game development and digital art. In the web space my focus is on theme
development for WordPress, Ghost or any other themeable platform, and on finding the latest
most efficient, user focused design and dev techniques of the day. In game development I'm
addicted to playing with every different engine, toolset and framework I can find and I could
spend months at a time immersed in level design. And in digital art there's little I love more than
creating realistic style vector pieces, and of course assets for games through original art or photo
manipulation. In short, if it's creative and you can make it digitally with code or design apps, I
love it.
kezzbracey
Sign on the Dotted Line:
Animating Your Own SVG
Signature
by Ian Yates1 May 2015
Difficulty:IntermediateLength:MediumLanguages:
Animation CSSSVG
Animating the stroke of an SVG is perfect for simulating handwriting. Over the
course of two tutorials we’re going to use CSS animation to make a signature neatly
appear to be written, as though you’re signing the page yourself.
1. SVG File
Before we dive into any code, we’re going to need an SVG version of your signature.
It doesn’t matter what software you use to make this, but try to keep the lines and
curves as smooth as possible for best effect.
Here’s mine, which you can see is drawn with three separate paths:
Fir
st path
Se
cond path
Th
ird path
Make sure your artboard is cropped tightly to the signature, then save the file as an
SVG.
In this case, the elements we’re left with look something like:
1 <svg>
2 <line/>
3 <path/>
4 <line/>
</svg>
5
Within our main <svg> we have a <line> , then a <path> , then another <line> .
These are the three vectors we drew, differentiated only because, technically, a line
has no curvature, so it’s defined differently to a path in SVG.
3. Add Classes
We’ll need to separately target these vectors with CSS a little later on, so make sure
they each have a suitable class name. The <svg> element will likely already have an
id reflecting the layer name in the application it was designed with.
1 <svg id="signature">
2 <line class="stroke-I" />
3 <path class="stroke-an" />
4 <line class="stroke-flourish" />
</svg>
5
I’ve given my vectors class names depending on what they are (the first one is the “I”
in my name, for example).
New Project
I’m going to build this using CodePen, but you can use standalone HTML and CSS
documents if you prefer. Paste the SVG code directly into your HTML document.
Then, remove the attributes each of the path and line elements have in common,
placing them instead in the CSS document. For example, you’ll notice attributes like:
fill="none"
stroke="#0F436D"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
stroke-miterlimit="10"
These can be removed and applied via CSS instead, like so:
1
path,
2 line {
3 fill: none;
4 stroke: #2a3745;
5 stroke-width: 2;
6 stroke-linecap: round;
stroke-linejoin: round;
7 stroke-miterlimit: 10;
8 }
9
Much cleaner!
5. Begin Animating
In order to animate the strokes of this SVG we’re going to be using a technique first
discussed by Jake Archibald. The idea is as follows: each of these vectors is going to
be given a dashed stroke. We do this by applying a stroke-dasharray value within
the CSS:
Dash Length
For each of these vectors we make the stroke-dasharray precisely the length of the
path, so each one has a single dash covering its entire length. This takes a bit of trial
and error, but in our case the values look look like this:
01
.stroke-I {
02 stroke-dasharray: 80;
03 }
04
05 .stroke-an {
06 stroke-dasharray: 360;
07 }
08
.stroke-flourish {
09 stroke-dasharray: 40;
10 }
11
Now, in order to animate these strokes, we need to offset each of the dashes so that
the gap covers the vector, not the dash. Does that make sense? These illustrations
might help. In this first one, imagine the dashed line is being used to cover the flourish
at the end of the signature.
Now in this one we’ve offset the dash, so it’s the gap which is over the flourish:
Now all we need to do is use CSS to animate from the offset state to the other.
6. Keyframes
CSS animation relies on first defining keyframes. Each keyframe represents states
along a timeline, then our browsers render the animations between them.
Let’s first see how this dash offset can be animated. We’ll use the first stroke, the “I”,
and animate between two states. Begin by setting up some keyframes:
1
@keyframes write1 {
2 0% {
3 stroke-dashoffset: 80;
4 }
5 100% {
stroke-dashoffset: 0;
6 }
7 }
8
Here we give the keyframes a name ( write1 ) and using shorthand syntax specify that
at the very beginning of the timeline ( 0% ) we want the stroke-dashoffset to
be 80 . In other words: the dash, which is exactly 80px long, will be offset
completely.
At the end of the timeline (at 100% ) we want the stroke-dashoffset to be 0 , so
the dash is once more covering the vector.
Apply Animation
Now we have our keyframes, let’s attach them to an animation. We add another
declaration to our stroke-I rule:
1 .stroke-I {
2 stroke-dasharray: 80;
3 animation: write1 3s infinite linear;
}
4
Here, using the animation property, we say that we want to use
the write1 keyframes defined a moment ago, we want the whole thing to last
exactly 3 seconds, we want the animation to loop infinitely and we want the speed to
be linear (so that there’s no acceleration or deceleration).
Here’s what we get:
Note: I’m using Autoprefixer in CodePen which saves me having to use browser
prefixes on the animation stuff.
Now we’re getting somewhere! Each vector is animating perfectly, in a linear motion
lasting 3 seconds.
7. Sequential Animation
Currently we have three strokes all animating simultaneously. However, we ideally
want the “I” to animate, then the “an”, then finally the flourish at the end. If we were
to visualise that along a timeline it might look like this:
We can actually represent these sections of the timeline perfectly in our CSS
keyframes. For example, the first section (from 0% to 33.3%) is when we want our “I”
to animate, so we alter the keyframes to finish at 33.3% instead of 100%:
1
@keyframes write1 {
2 0% {
3 stroke-dashoffset: 80;
4 }
5 33.3% {
stroke-dashoffset: 0;
6
}
7 }
8
Now, given that all three of our animations are the same length (3 seconds) we can
make sure the second doesn’t start until 33.3%, when the first animation is complete:
1 @keyframes write2 {
2 0%, 33.3% {
3 stroke-dashoffset: 360;
4 }
5 100% {
6 stroke-dashoffset: 0;
}
7 }
8
Here’s what that gives us:
Further Refinement
What we have is good, but it isn’t perfect–certainly far from a realistic pen movement.
Each of these three vectors is being drawn over the course of one second, irrespective
of its length. The middle vector is wa-ay longer than the last, so it should logically
take longer to draw. A better timeline might look something like this:
For added realism there’s even a gap between the first vector finishing and the second
beginning. So let’s alter our keyframe values to reflect that:
01
02
03 @keyframes write1 {
04 0% {
stroke-dashoffset: 80;
05 }
06 20% {
07 stroke-dashoffset: 0;
08 }
}
09
10
@keyframes write2 {
11 0%, 25% {
12 stroke-dashoffset: 360;
13 }
14 90% {
15 stroke-dashoffset: 0;
}
16 }
17
18 @keyframes write3 {
19 0%, 90% {
20 stroke-dashoffset: 40;
21 }
100% {
22 stroke-dashoffset: 0;
23 }
24 }
25
26
Finally, let’s speed things up by changing all the 3s values to 2s . We can also
update the animation declarations so that each one runs just once, not infinitely
looping:
1 animation: write1 2s 1 linear;
You might also want to play with the linear value, instead adding some easing such
as ease-in , ease-in-out , ease-out etc. to make the movement less uniform.
What does that all give us?
Next Time
We’ve made great progress and learned a lot along the way! In the next tutorial we’ll
take things a step further, using Waypoints.js to help us control when the animation
takes place. I’ll see you there!
Ian Yates
Web Design editor at Envato Tuts+
My name's Ian; I'm the web design editor round these parts and I also run the translation project.
Ask me anything you like about web design, in any language… I'll find someone who knows the
answer!
snapti
Difficulty:IntermediateLength:ShortLanguages:
Today, we will cover two specific techniques you can employ to show scroll
progress, and leave you with a toolset to create your own. Let's get started!
01 <!doctype html>
02 <html>
<head>
03
<title>Progress Indicator Animation</title>
04
<link rel="stylesheet" href="css/normalize.css">
05
<link rel="stylesheet" href="css/style.css">
06
</head>
07 <body>
08 <!-- fake post content goes here -->
09 <script src="js/jquery.min.js"></script>
10
<script src="js/script.js"></script>
11
</body>
12
</html>
13
0 <main>
1 <article>
0 <header>
2
<h1>
0 <div class="container">
3
How Should We Show Progress While Scrolling a Post?
0
</div>
4
</h1>
0
5 </header>
0 <div class="article-content">
6 <h2 class="lead-in">
0 <div class="container">
7 Lorem ipsum dolor sit amet, consectetur adipisicing elit.
0 </div>
8
</h2>
0
<div class="container">
9
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada f
1 amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est.
0 Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean ferme
ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id
1 erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus</p
1
<!-- add your own additional lorem here -->
1 </div>
2
</div>
1
</article>
3
<footer>
1
4 <h3 class="read-next"><small>Read Next:</small><br>How do I Implement a Foobar?</
1
5
1
6
1
7
1
8
1
9
2 </footer>
0 </main>
2
1
2
2
2
3
2
4
2
5
Basic Styling
We're going to use some basic styling to make our post a little more attractive.
01 @import url(http://fonts.googleapis.com/css?family=Domine:400,700);
02 body {
font-size: 16px;
03
}
04
h1,
05
h2,
06
h3,
07 h4,
08 h5,
h6 {
09
font-family: "Domine", sans-serif;
10
}
11
12
h1 {
13
font-size: 3.5em;
14 }
15
16 .lead-in {
17 color: #fff;
18 font-weight: 400;
19 padding: 60px 0;
background-color: #0082FF;
20
}
21
22
article header {
23
border-top: 3px solid #777;
24
padding: 80px 0;
25 }
26
27 .article-content {
28 font-size: 1em;
29 font-weight: 100;
30 line-height: 2.4em;
}
31
32
p {
33
margin: 4em 0;
34
}
35
36
37
38
.container {
39
width: 700px;
40
margin: 0 auto;
41
}
42
43
44 footer {
45 text-align: center;
46 background-color: #666;
47 color: #fff;
48 padding: 40px 0;
margin-top: 60px;
49
}
50
51
.read-next {
52
font-size: 2em;
53
}
54
55
56
06 $w.on('scroll', function(){
The above code sets the window height and the body height, and when the
user scrolls it uses those values to set a perc variable (short for percentage).
We also utilize Math.min and Math.max to limit the values to the 0-100 range.
Circle Indicator
The first indicator we will create is an SVG circle. We will utilize the
SVG stroke-dasharray and stroke-dashoffset properties to show progress.
First, let's add the progress indicator to the document.
01 <div class="progress-indicator">
02 <svg>
<g>
03
<circle cx="0" cy="0" r="20" class="animated-circle" transform="translate(50,
04
</g>
05
<g>
06
<circle cx="0" cy="0" r="38" transform="translate(50,50)" />
07
08 </g>
09 </svg>
10 <div class="progress-count"></div>
11 </div>
01 .progress-indicator {
02 position: fixed;
top: 30px;
03
right: 30px;
04
width: 100px;
05
height: 100px;
06
}
07 .progress-count {
08 position: absolute;
09 top: 0;
10 left: 0;
11 width: 100%;
height: 100%;
12
text-align: center;
13
line-height: 100px;
14
color: #0082FF;
15
}
16
17 svg {
18 position: absolute;
19 }
20 circle {
21 fill: rgba(255,255,255,0.9);
22
23
}
24
25 svg .animated-circle {
26 fill: transparent;
27 stroke-width: 40px;
28 stroke: #0A74DA;
29 stroke-dasharray: 126;
stroke-dashoffset: 126;
30
}
31
32
These styles set us up to animate our circle element. Our progress should
always be visible, so we set position to fixed on the .progress-
indicator class, with positioning and sizing rules. We also set our progress
The circles are positioned in the center using transform on the SVG elements
themselves. We start the center of our circles using transform. We use a
technique here that allows us to apply a rotation from the center of our circles
in order to start the animation at the top of the circle (rather than the right side
of the circle). In SVG, transforms are applied from the top left of an element.
This is why we must center our circles at 0, 0 , and move the circle's center
to the center of the SVG itself using translate(50, 50) .
01
02 (function(){
var $w = $(window);
03
var $circ = $('.animated-circle');
04
var $progCount = $('.progress-count');
05
var wh = $w.height();
06
var h = $('body').height();
07 var sHeight = h - wh;
08 $w.on('scroll', function(){
09 var perc = Math.max(0, Math.min(1, $w.scrollTop()/sHeight));
10 updateProgress(perc);
11 });
12
function updateProgress(perc){
13
var circle_offset = 126 * perc;
14
$circ.css({
15
"stroke-dashoffset" : 126 - circle_offset
16
});
17
$progCount.html(Math.round(perc * 100) + "%");
18 }
19
20 }());
21
The offset that matches our circle happens to be about 126. It's important to
note that this won't work for all circles, as 126 is about the circumference of a
circle with a radius of 20. To calculate the stroke-dashoffset for a given circle,
mutiply the radius by 2PI. In our case, the exact offset would be 20 * 2PI =
125.66370614359172 .
Horizontal Progress Variation
For our next example, we'll make a simple horizontal bar fixed to the top of the
window. To accomplish this, we'll use an empty progress indicator div.
1 <div class="progress-indicator-2"></div>
Note: we've added the "-2" to allow us to include this example in the same
CSS file.
1 .progress-indicator-2 {
2 position: fixed;
3 top: 0;
4 left: 0;
5 height: 3px;
background-color: #0A74DA;
6
}
7
2 function updateProgress(perc){
4 }
01 (function(){
02 var $w = $(window);
06 var wh = $w.height();
07 var h = $('body').height();
09 $w.on('scroll', function(){
updateProgress(perc);
11
});
12
13
function updateProgress(perc){
14
var circle_offset = 126 * perc;
15
$circ.css({
16 "stroke-dashoffset" : 126 - circle_offset
17 });
18 $progCount.html(Math.round(perc * 100) + "%");
19
21 }
22
}());
23
24
You would then use the minCount in conjunction with the perc variable we
are updating on scroll to show the reader their remaining time to read the
article. Here's a very basic implementation of this concept.
1
function updateProgress(perc){
2 var minutesCompleted = Math.round(perc * minCount);
3 var remaining = minCount - minutesCompleted;
4 if (remaining){
6 } else {
$(".progress-indicator").hide();
7
}
8
}
9
01 (function(){
02
03 var $w = $(window);
14
15 setSizes();
16
17 $w.on('scroll', function(){
26 $circ.css({
});
28
$progCount.html(Math.round(perc * 100) + "%");
29
30
32 }
33
34 }());
35
This code declares a function which sets the variables we need to calculate
the progress at any given screen size, and calls that function on resize. We
also re-trigger scroll on window resize so that our updateProgress function is
executed.