Как использовать "animateTransform" для инлайн SVG анимации
() translation by (you can also view the original English article)
Сегодня мы вас познакомим с использованием 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 код оттуда. Всё что нам нужно - код между открывающим <svg>
тегом и закрывающим тегом </svg>
.
К примеру Sketch создаёт следующий SVG код голубого прямоугольника на изображении выше.
1 |
<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"> |
2 |
<!-- Generator: Sketch 3.1 (8751) - http://www.bohemiancoding.com/sketch -->
|
3 |
<title>Slice 2</title> |
4 |
<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="MSPage"> |
7 |
<rect id="Rectangle-1" fill="#3C81C1" sketch:type="MSShapeGroup" x="0" y="0" width="100" height="125"></rect> |
8 |
</g>
|
9 |
</svg>
|
Чтобы визуально с кодом было легче работать мы сделаем пару небольших изменений.
Установите элементу svg
ширину width
и высоту height
- 100%
, а также удалите viewBox
. Удалите комментарии Generator
, title
, desc
, defs
и g
элементы.
В итоге у вас должно получится что-то вроде этого:
1 |
<svg version="1.1" width="100%" height="100%" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns"> |
2 |
<rect id="Rectangle-1" fill="#3C81C1" sketch:type="MSShapeGroup" x="0" y="0" width="100" height="125"></rect> |
3 |
</svg>
|
Добавьте этот код в HTML документ, в браузере вы увидите такой же прямоугольник, который нарисовали в Sketch:



Обратите внимание: на изображении выше показаны X и Y оси, они нам понадобятся во время создания анимации. Вы поймете зачем в скором времени.
Что делает “animateTransform”?
Если ответить коротко - animateTransform
элемент создаёт анимацию устанавливая значения трансформации для SVG фигуры.
Учитывая это, следующий вопрос:
Хорошо, так что же делает "Transform"?
Добавление фигуре transform
- позволяет модифицировать её внешний вид в 2D пространстве. Существует пять различных типов трансформации, которые можно использовать:
-
translate
-
scale
-
rotate
-
skewX
skewY
Атрибут animateTransfom
позволяет вам анимировать различные состояния трансформации, поэтому перед тем как начать, важно понять принципы работы самой трансформации.
Трансформации и 2D пространство
Трансформации в 2D пространстве зависят от X и Y координат на X / Y осях, как вы могли заметить на изображении с голубым прямоугольником, выше.
- Ось
X
является горизонтальной линией в 2D пространстве, аY
ось соответственно вертикальная линия. По умолчанию каждая фигура начинается на позиции равной0
на обеих осях координатX
иY
. - Начиная от
0
позиции поX
оси, положительные значения соответствуют движению вправо, негативные значения соответствуют движению влево. - Начиная от
0
позиции на осиY
, положительные значения соответствую движению вниз, негативные значению соответствуют движению вверх.
Если на данный момент это не совсем понятно, не волнуйтесь, со временем, когда вы ознакомитесь с примерами, ситуация прояснится.
Также не стоит беспокоиться о коде трансформации, так как мы разберём это при создании анимации. Для начала я хочу объяснить основы пяти типов трансформации и что они делают.
Translate
Данный вид трансформации передвигает фигуру относительно X оси (горизонтальная ось) и относительно Y оси (вертикальная ось).
К примеру вот наш голубой прямоугольник со значениями translate
150
по оси X
(горизонтальная ось) и 20
по оси Y
(вертикальная ось):



Помните мы обсуждали до этого, что положительные значение позиции на оси X
отвечают за движение вправо и что положительные значение позиции Y
отвечают за движение вниз.
Установив значение translate
для X
равное 150
, наш прямоугольник сдвинулся вправо на 150 пикселей. Задав значение Y
равное 20
тем самым мы сдвинули прямоугольник вниз на 20 пикселей.
Scale
Этот вид трансформации увеличивает размер согласно оси X (ширина) и согласно оси Y (высота).
Значения Scale увеличивают оригинальный размер фигуры. К примеру если мы зададим значение scale X
равное 3
фигура станет в три раза шире. Если задать значение scale Y
равное 1.25
фигура станет на четверть выше, выглядеть это будет так:



Rotate
Данный вид трансформации вращает фигуру вокруг, согласно указанным градусам.
Ротация работает относительно значению градусов, тем самым вращая фигуру. К примеру, ротация прямоугольника на 45 градусов:



По умолчанию фигура будет вращаться относительно верхнего левого угла, но вы также можете вращать её относительно другой точки. Мы рассмотрим как это сделать позже, в данном туториале.
SkewX
Данная трансформация искажает фигуру относительно X оси (горизонтальная).
Искажение относительно оси X также измеряется в градусах. К примеру прямоугольник на изображении ниже искажён на 20 градусов относительно X оси:



SkewY
Эта трансформация искажает фигуру относительно Y (вертикально) оси согласно заданному значение градусов.
SkewY
работает точно также как и SkewX
, единственное отличие, что трансформация выполняется вертикально согласно оси Y:



Анимация трансформаций
Теперь когда мы разобрались, как работают трансформации, мы сможем без труда создать анимацию для различных состояний трансформации. Основной процесс состоит из трёх шагов:
- Установите изначальное состояние трансформации:
from
состояние.
- Установите конечное состояние трансформации:
to
состояние.
- Установите время повторение для переходов анимации от
from
иto
состояния.
Лучше всего это можно понять на практике, так что давайте начнём с анимации translate
трансформации.
Анимация Translate трансформаций
Помните ранее наш голубой прямоугольник по умолчанию находился на позиции 0 0
, то есть 0
на X
оси и 0
на оси Y
. Мы установили позицию в качестве from
состояния.
Далее мы рассмотрели пример, где тому же голубому прямоугольнику были заданы значения translate равные 150 20
, то есть 150
по оси X
и 20
по оси Y
. Позиция была установлена, как to
состояние.
Используя animateTransform
мы плавно передвигаем прямоугольник от состояния from
к to
, в течении двух секунд.
Ваша SVG фигура, в данном случае прямоугольник, должна иметь открывающий и закрывающий теги, то есть <rect></rect>
.
Атрибут animateTransform
должен находиться между этих двух тегов, следующим образом:
1 |
<rect id="Rectangle-1" fill="#3C81C1" sketch:type="MSShapeGroup" x="0" y="0" width="100" height="125"> |
2 |
<animateTransform attributeName="transform" |
3 |
type="translate" |
4 |
from="0 0" |
5 |
to="150 20" |
6 |
begin="0s" |
7 |
dur="2s" |
8 |
repeatCount="indefinite" |
9 |
/>
|
10 |
</rect>
|
Обратите внимание на свойства внутри animateTransform
тега. Они контролируют, как ваша анимация будет работать.
Мы установили type
равный translate, что означает, что будет применяться тип трансформации translate
. Как и планировалось, мы установили значение позиции 0 0
для from
состояния и 150 20
для состояния to
.
Значение begin
установлено равным 0s
, что означает - анимация начнётся с ноля секунд после загрузки, dur
имеет значение 2s
, означает, что анимация будет отображаться в течении двух секунд. Наконец мы добавили repeatCount
со значением indefinite
, тем самым анимация будет работать без остановки, повторятся в цикле.
В результате мы получим следующую анимацию:



Анимация остальных трансформаций
Процесс точно такой же для ротации и других четырёх типов трансформаций. Установив значение type
той трансформации, которая вам необходима, введите значения для from
и to
состояний.
Для примера, мы можем использовать следующие значения animateTransform
, чтобы растянуть наш прямоугольник до размера, который мы видели до этого в части, где обсуждалась scale трансформация.
1 |
<animateTransform attributeName="transform" |
2 |
type="scale" |
3 |
from="1 1" |
4 |
to="3 1.25" |
5 |
begin="0s" |
6 |
dur="2s" |
7 |
repeatCount="0" |
8 |
/>
|
Так как scale трансформация увеличивает оригинальный размер фигуры, мы начали со значения 1 1
для from
. Делая это мы увеличиваем, умножаем оригинальный размер на 1.
Наше значение to
равно 3 1.25
, создаст анимацию нашей scale трансформации, увеличив в три раза ширину на оси X и на четверть увеличив оригинальную высоту на оси Y.



Обратите внимание: анимация в браузере работает гораздо плавнее, чем на GIF изображении выше.
Анимация нескольких трансформаций
Мы можем соединить обе анимации, которые были созданы, так что translate и scale будут работать одновременно. Вы можете использовать лишь один тег animateTransform
внутри тега rect
, поэтому для нескольких анимаций, нам понадобится g
теги, которые представляют из себя группу SVG объектов.
Чтобы это работало добавьте открывающий и закрывающий <g></g>
теги вокруг rect
тегов:
1 |
<g>
|
2 |
<rect id="Rectangle-1" fill="#3C81C1" sketch:type="MSShapeGroup" x="0" y="0" width="100" height="125"> |
3 |
<animateTransform attributeName="transform" |
4 |
type="scale" |
5 |
from="1 1" |
6 |
to="3 1.25" |
7 |
begin="0s" |
8 |
dur="2s" |
9 |
repeatCount="0" |
10 |
/>
|
11 |
</rect>
|
12 |
</g>
|
Затем добавьте вторую анимацию после закрывающего тега </rect>
, перед закрывающим </g>
тегом. В данном случае будет добавлена наша translate трансформация:
1 |
<g>
|
2 |
<rect id="Rectangle-1" fill="#3C81C1" sketch:type="MSShapeGroup" x="0" y="0" width="100" height="125"> |
3 |
<animateTransform attributeName="transform" |
4 |
type="scale" |
5 |
from="1 1" |
6 |
to="3 1.25" |
7 |
begin="0s" |
8 |
dur="2s" |
9 |
repeatCount="0" |
10 |
/>
|
11 |
</rect>
|
12 |
<animateTransform attributeName="transform" type="translate" from="0 0" to="150 20" begin="0s" dur="2s" repeatCount="0" /> |
13 |
</g>
|
Теперь обе scale и translate трансформации анимируются одновременно:



Вы можете использовать animateTransform
один раз для фигуры или группы. Для добавления большего количества анимаций, оберните набор тегов группы вокруг кода и внути определите дополнительный animateTransform
тег.
Давайте быстро взглянем на оставшиеся три типа трансформации, каждый создаётся изменением type
, значений from
и to
, а также скомбинированы с первоначальной translate анимации.
Анимация ротации (Rotation) плюс перехода (Translation)
В этом примере type
обладает значением rotate
, from
равен 0
- при загрузке нет ротации и to
установлено значение 45
, тем самым фигура вращается на 45 градусов в течении двух секунд:



SkewX и SkewY анимация плюс переход (Translation)
Для следующих двух анимаций значение type
равно skewX
и skewY
, from
равняется 0
, никакого искажения при загрузке и to
равно 20
, тем самым фигура исказится на 20 градусов за две секунды:






Практический пример: иконка загрузчика
Существует бесконечное количество всевозможных видов анимации, которые вы можете создать, используя данные методы, но одна из очевидно полезных - создание иконки загрузчика, где вы раньше полагались на GIF анимацию.
Вот иконка загрузчика, которую я создала за пять минут, используя Sketch:



После чего экспортировала SVG файл, получив следующий код:
1 |
<svg width="36px" height="36px" viewBox="0 0 36 36" 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"> |
2 |
<!-- Generator: Sketch 3.1 (8751) - http://www.bohemiancoding.com/sketch -->
|
3 |
<title>loader01 2</title> |
4 |
<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="MSPage"> |
7 |
<g id="Group-3" sketch:type="MSLayerGroup" fill="#4990E2"> |
8 |
<rect id="Rectangle-1" sketch:type="MSShapeGroup" x="16.5873418" y="0" width="3" height="9.13705584"></rect> |
9 |
<rect id="Rectangle-2" fill-opacity="0.58" sketch:type="MSShapeGroup" x="16.678481" y="26.8629442" width="3" height="9.13705584"></rect> |
10 |
<rect id="Rectangle-4" fill-opacity="0.79" sketch:type="MSShapeGroup" transform="translate(31.530380, 17.954315) rotate(-270.000000) translate(-31.530380, -17.954315) " x="30.0303797" y="13.3857868" width="3" height="9.13705584"></rect> |
11 |
<rect id="Rectangle-3" fill-opacity="0.37" sketch:type="MSShapeGroup" transform="translate(4.735443, 18.045685) rotate(-270.000000) translate(-4.735443, -18.045685) " x="3.23544304" y="13.4771574" width="3" height="9.13705584"></rect> |
12 |
<rect id="Rectangle-4" fill-opacity="0.72" sketch:type="MSShapeGroup" transform="translate(29.758244, 24.676171) rotate(-240.000000) translate(-29.758244, -24.676171) " x="28.2582441" y="20.1076435" width="3" height="9.13705584"></rect> |
13 |
<rect id="Rectangle-3" fill-opacity="0.3" sketch:type="MSShapeGroup" transform="translate(6.507579, 11.323829) rotate(-240.000000) translate(-6.507579, -11.323829) " x="5.00757864" y="6.75530065" width="3" height="9.13705584"></rect> |
14 |
<rect id="Rectangle-4" fill-opacity="0.65" sketch:type="MSShapeGroup" transform="translate(24.871110, 29.609153) rotate(-210.000000) translate(-24.871110, -29.609153) " x="23.37111" y="25.0406255" width="3" height="9.13705584"></rect> |
15 |
<rect id="Rectangle-3" fill-opacity="0.23" sketch:type="MSShapeGroup" transform="translate(11.394713, 6.390847) rotate(-210.000000) translate(-11.394713, -6.390847) " x="9.89471277" y="1.82231869" width="3" height="9.13705584"></rect> |
16 |
<rect id="Rectangle-4" fill-opacity="0.51" sketch:type="MSShapeGroup" transform="translate(11.473642, 29.654839) rotate(-150.000000) translate(-11.473642, -29.654839) " x="9.97364166" y="25.0863108" width="3" height="9.13705584"></rect> |
17 |
<rect id="Rectangle-3" fill-opacity="0.93" sketch:type="MSShapeGroup" transform="translate(24.792181, 6.345161) rotate(-150.000000) translate(-24.792181, -6.345161) " x="23.2921811" y="1.77663341" width="3" height="9.13705584"></rect> |
18 |
<rect id="Rectangle-4" fill-opacity="0.44" sketch:type="MSShapeGroup" transform="translate(6.553148, 24.755301) rotate(-120.000000) translate(-6.553148, -24.755301) " x="5.05314826" y="20.1867727" width="3" height="9.13705584"></rect> |
19 |
<rect id="Rectangle-3" fill-opacity="0.86" sketch:type="MSShapeGroup" transform="translate(29.712675, 11.244699) rotate(-120.000000) translate(-29.712675, -11.244699) " x="28.2126745" y="6.67617143" width="3" height="9.13705584"></rect> |
20 |
</g>
|
21 |
</g>
|
22 |
</svg>
|
Данная иконка состоит из нескольких фигур внутри группы и как мы узнали до этого, мы можем применить animateTransform
для группы, я добавила код анимации перед закрывающим </g>
тегом:
1 |
</g>
|
2 |
<animateTransform attributeName="transform" |
3 |
type="rotate" |
4 |
from="0 18 18" |
5 |
to="360 18 18" |
6 |
begin="0s" |
7 |
dur="0.85s" |
8 |
repeatCount="indefinite" |
9 |
/>
|
10 |
</g>
|
11 |
</svg>
|
Код выше, вращает иконку от 0 до 360 градусов, то есть полный оборот.
Вращаем оси
Обратите внимание, что в этот раз я добавила дополнительные два числа, для from
и to
. Это сообщает нашей анимации вращаться фигуре по внутренним осям X / Y на 18 18
, с учетом что центр фигуры размером 36x36 пикселей.
Тем самым мы получим следующую анимацию:



Опять же анимация в браузере будет выглядеть плавнее, чем GIF, поэтому не поленитесь проверить настоящий пример. Как вы поняли очень быстро можно соединить вместе анимации, благодаря этому можно получить реальную пользу.
В заключении
В том случае если ранее вы не особо использовали SVG анимацию, теперь у вас есть все необходимые инструменты, чтобы начать.
Дополнительная информация
- Отличный пример на Codepen анимированного SVG загрузчика
- Больше информации о том как работает Transform на W3C
- Скачайте копию исходников для данного туториала, поиграйтесь с ними, повеселитесь, создавая свою инлайн SVG анимацию!