- Как использовать «animateTransform» для инлайн SVG анимации
- Перед тем как мы начнём
- Rotating elements
- Animating a square
- Rotating arbitrary elements
- Comments (16)
- Andrea on 17 Oct 2013, 2:55 p.m.
- Chris Cuevas on 16 Nov 2013, 12:32 a.m.
- Jim Higson on 26 Dec 2013, 12:39 p.m.
- Peedy on 1 Mar 2015, 7:45 p.m.
- Anonymous on 19 Apr 2015, 4:53 p.m.
- Alex Latenko on 6 Aug 2015, 3:38 p.m.
- Anonymous on 10 Mar 2016, 11:28 p.m.
- Stefan Fröhlich on 3 Jun 2016, 11:30 a.m.
- Warre Buysse on 5 Jun 2016, 1:44 p.m.
- kione on 27 Jun 2016, 2:13 p.m.
- Andrea on 15 Jul 2017, 10:30 p.m.
- Robert on 8 Aug 2017, 11:37 p.m.
- James Briano on 12 Mar 2018, 4:29 p.m.
- jumanja on 12 Sep 2018, 10:03 p.m.
- Regina on 19 May 2020, 5:28 p.m.
- Challenge. on 20 May 2020, 6:03 a.m.
Как использовать «animateTransform» для инлайн SVG анимации
Kezz Bracey Last updated Oct 21, 2014
Сегодня мы вас познакомим с использованием animateTransform для создания инлайн SVG (scalable vector graphics) анимации.
Если вы мало что знаете о SVG, я рекомендую обратить внимание на «Начинаем работать с Scalable Vector Graphics (SVG)», чтобы разобраться во многих деталях.
Техника, которую мы будем изучать позволяет создавать привлекательные иконки и анимации изображений без применения GIF, JPEG или PNG, а также не используя JavaScript, ну и конечно же без Flash.
Данную анимацию будет легко редактировать в будущем, так как представляет она из себя исключительно код, конечный результат будет занимать всего 2 KB драгоценного пространства на диске, что само собой сыграет роль при передаче файла от сервера к клиенту пользователя.
Перед тем как мы начнём
Чтобы анимировать SVG фигуру, для начала нам нужно сделать её. Самый простой способ для создания SVG, который я нашла — использовать Sketch от Bohemian Coding. Если вы не покупали лицензию Sketch, можно воспользоваться бесплатной версией на 30 дней, этого будет вполне достаточно для нашего туториала.
Нам понадобится SVG код, нарисуйте фигуру в Sketch, после чего выделите фрагмент (slice) и экспортируйте его в качестве SVG файла.
Далее мы можем открыть экспортированный файл в текстовом редакторе (к примеру Sublime Text) и скопировать SVG код оттуда. Всё что нам нужно — код между открывающим .
К примеру Sketch создаёт следующий SVG код голубого прямоугольника на изображении выше.
width="100px" height="125px" viewBox="0 0 100 125" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
Rotating elements
The page explains how to animate simple SVG transformations using the tag. The code for the example can be found by following the Github link above.
Square rotating about its centre
[NOTE: SVG’s SMIL animations are deprecated and you should probably use CSS transformations instead.]Animating a square
This is the code for the animated square at the top of this page:
The important points to note are:
- The element is a child of the element.
- The type is «rotate» (could also be «translate», «scale», «skewX» or «skewY»).
- The from and to are in the form «n1 n2 n3».
- The rotation starts at 0 degrees and changes to 360 degrees (the n1 values).
- The centre of rotation is at (n2, n3) and doesn’t change (it could if you wanted).
- The dur is «4s», meaning a full rotation takes 4 second.
- The repeatCount is «indefinite», but can be a number, even a decimal, if you want the animation to stop after it has repeated some number of times.
- You can also use begin and end attributes to determine when to start and stop the animation.
Rotating arbitrary elements
I was first inspired to tackle this problem after seeing this question on Stack Overflow. So I found a tutorial for how to draw gears using Inkscape (here) and tried to animate them.
In order to rotate an element about its centre, you first need to know its centre. For or elements that’s easy, but for a path, it’s not so straightforward.
(EDIT: As Jim says in the comments, you could draw the elements so their center is at the origin, and then translate them to where you want. This simplifies things at lot, but sometimes you don’t get to draw the image yourself.)
The only way I could find to determine the centre of a path, short of writing my own program to parse the coordinates, was to use Javascript and the getBBox() function to find the bounding box of the element.
Below is a function that takes an element id, a duration (seconds to complete one rotation), and a direction (1 for clockwise, -1 for anti-clockwise). It then finds the element with that id, determines its centre with getBBox(). It then builds an element from scratch and adds it to the chosen element. Finally, it calls beginElement() to start the animation.
function addRotateTransform(target_id, dur, dir) < var my_element = svg.getElementById(target_id); var a = svg.createElementNS("http://www.w3.org/2000/svg", "animateTransform"); var bb = my_element.getBBox(); var cx = bb.x + bb.width/2; var cy = bb.y + bb.height/2; a.setAttributeNS(null, "attributeName", "transform"); a.setAttributeNS(null, "attributeType", "XML"); a.setAttributeNS(null, "type", "rotate"); a.setAttributeNS(null, "dur", dur + "s"); a.setAttributeNS(null, "repeatCount", "indefinite"); a.setAttributeNS(null, "from", "0 "+cx+" "+cy); a.setAttributeNS(null, "to", 360*dir+" "+cx+" "+cy); my_element.appendChild(a); a.beginElement(); >
addRotateTransform requires an svg element to be defined in order to create the animateTransform element. We can get the svg element by adding onload=»init(evt)» to the SVG element and defining an init function to extract the svg from the evt (which is an object representing the onload event).
This function can be added within the SVG itself in the following element:
var svg; function init(evt) < if (window.svgDocument == null) < svg = evt.target.ownerDocument; >addRotateTransform('gear-1', 12, 1); addRotateTransform('gear-2', 16, -1); > function addRotateTransform(target_id, dur, dir)
This is also where you can call the addRotateTransform function. Here I’ve called it twice to target elements with ids «gear-1» and «gear-2». It might seem like a lot of code just to rotate some elements, but you just need to add it to the top of your SVG and then it’s easy to rotate any of the elements you chose by selecting the relevant ids.
Comments (16)
Andrea on 17 Oct 2013, 2:55 p.m.
Hello ! How can I rotate an object (ex. a rectangle) only when a variable is set at TRUE ? (When the variable is FALSE the rectangle has to stop). Thanks very much
Chris Cuevas on 16 Nov 2013, 12:32 a.m.
This is brilliant! This is exactly what I have been looking for!
Jim Higson on 26 Dec 2013, 12:39 p.m.
A little advice: if you draw all the cogs in inkscape at the origin (so their centres are at (0,0) it is much easier to position and rotate them.
Peedy on 1 Mar 2015, 7:45 p.m.
THANK YOU FOR PROVIDING THIS PIECE OF CAKE .
With your code-snippet I was able to rotate my fan-blades . :-))
Anonymous on 19 Apr 2015, 4:53 p.m.
It took me hours to get this to work, until I found this.. Thanks for the script!
Alex Latenko on 6 Aug 2015, 3:38 p.m.
Thank you a lot, Peter for this perfect script!
Thats exactly the thing I have being looking for!
Anonymous on 10 Mar 2016, 11:28 p.m.
In chrome I got this warning.
«SVG’s SMIL animations (, , etc.) are deprecated and will be removed. Please use CSS animations or Web animations instead.»
Stefan Fröhlich on 3 Jun 2016, 11:30 a.m.
Brilliant solution! The rotating_gears.svg unfortunately isn’t working on IE9-11 and Edge. Even though it should be possible, right?
Any ideas to get it running on MS’s offspring?
Warre Buysse on 5 Jun 2016, 1:44 p.m.
This post might be five years old but it helped me understand svg animateTransform rotation, thank you.
kione on 27 Jun 2016, 2:13 p.m.
Still very helpful! Thanks for the share
Andrea on 15 Jul 2017, 10:30 p.m.
Hello ! How can I rotate an object (ex. a rectangle) only when a variable is set at TRUE ? (When the variable is FALSE the rectangle has to stop). Thanks very much
Robert on 8 Aug 2017, 11:37 p.m.
I am using VueJS and trying to do this. I didn’t want to use inline JS. For my particular purpose, I was trying to get a circular geo icon to rotate when as user clicks «Find nearby businesses.» . I was able to work around this by rotating the entire SVG box with CSS and not just the path. However, I can see how this wouldn’t work unless your viewbox is perfectly square, all sides same length. Since my image was circular, it works for me.
James Briano on 12 Mar 2018, 4:29 p.m.
jumanja on 12 Sep 2018, 10:03 p.m.
Thanks a lot for your site, really helpgul. Regarding SMIL deprecation, it seems Google attempted to deprecate it, but they suspended their attempt, as you can read in this thread: https://stackoverflow.com/questions/30965580/deprecated-smil-svg-animation-replaced-with-css-or-web-animations-effects-hover
Regina on 19 May 2020, 5:28 p.m.
It seems, Google Chrome and Edge both have problems with indefinite rotation — I am rotating a group of elements (a wind-mill) with continuous rotation. Works fine in FF and Safari, but Chrome and Edge counter-rotate to the beginning, destroying the whole effect. Any ideas why?
Challenge. on 20 May 2020, 6:03 a.m.
Here is a challenge I can’t find a solution for: hot do you rotate from 350 degrees to 10 degrees smoothly, passing over 0 degree? Say you have a function that only returned what the next degree should and not know where it’s starting from. Is there a better way than checking if it’s passed half the circumference, and do math to manually go to 360, than stop animating. Then restart from 0 and go to 10 ?
If you just say animate from 350 to 10, it will go the other way around. annoying, but logical. Think of a compass to get the concept.