Advertisement
  1. Web Design
  2. HTML & CSS

Как анимировать праздничные иконки SVG при помощи CSS

Scroll to top
Read Time: 17 min

Russian (Pусский) translation by AlexBioJS (you can also view the original English article)

Пришла пора, поэтому в этом руководстве мы рассмотрим, как создавать некоторые праздничные SVG-иконки, анимированные при помощи CSS. На Iconmelon, сайте, где выложено много бесплатных наборов векторных иконок, которые могут вас сильно заинтересовать, вы можете найти некоторые замечательные иконки. Иконки, которые я использую здесь, предоставлены Sam Jones. Так что возьмите себе чашку эггнога (* напиток на основе взбитых яиц с добавлением молока, коньяка или рома, сахара, специй; подаётся горячим или холодным. Здесь и далее примеч. пер.), затащите ваш лэптоп на Рождественское полено (* большое полено, сжигаемое в Рождественский сочельник) и давайте приступим!

SVG и Веб

Если вы заинтересованы в использовании SVG в веб, рекомендую начать с иконок. С элементами SVG легко работать, они не зависят от разрешения экрана и имеют небольшой вес, поэтому иконки естественным образом подходят для векторного формата. Более того, так же, как и в случае с HTML, для элементов SVG можно задать стилевое оформление при помощи технологии CSS, включающей в себя анимации CSS3. За счет добавления капельки интерактивности в ваши иконки  при помощи анимаций вам может быть легче создать очаровательный опыт взаимодействия для ваших пользователей и также предоставить контекст о том, что представляет из себя иконка.

В качестве вступления в тему о том, как использовать SVG в веб, ознакомьтесь с SVG Files: From Illustrator to the Web.

Обратите внимание: в нижеприведенных демоверсиях используются передовые технологии, которые на момент написания этого руководства не поддерживаются в некоторых браузерах, таких как Internet Explorer. Для работы с руководством вам больше всего подойдет Chrome или Safari. Поддержка Mozilla вполне возможна, если вы будете использовать соответственные префиксы для свойств. Вы можете быть уверены, что поддержка этих технологий будет улучшена в будущем.

Кроме того: в этом руководстве я опустил несколько важных префиксов браузеров некоторых свойств CSS, чтобы сделать код более лаконичным и читабельным. Ознакомьтесь с библиотекой prefixfree, созданной Lea Verou, если бы вы хотели облегчить процесс написания кода CSS без префиксов. Также вы могли бы попробовать создавать ваши демоверсии на Codepen, который можно легко настроить на использование prefixfree.


Подготавливаем код SVG для редактирования

Одна из главных трудностей при работе с SVG – то, что с кодом тяжело работать. Код SVG, экспортируемый Illustrator (предпочитаемым мною графическим редактором), довольно нечитабельный на первый взгляд. Inkscape в этом отношении лучше, однако я обнаружил, что путем упрощения и форматирования можно сделать код значительно более читабельным и удобным для работы.

Ниже приведен код SVG для первого примера анимации, который я продемонстрирую, – Рождественской огонек.

1
2
<?xml version="1.0" encoding="utf-8"?>
3
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
4
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
5
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
6
 width="64px" height="64px" viewBox="0 0 64 64" enable-background="new 0 0 64 64" xml:space="preserve">
7
<path id="outline" d="M38.178,12.142H25.822v10.723c-1.605,2.67-2.461,6.529-2.461,11.406c0,9.473,4.748,17.587,8.637,17.587

8
 s8.641-8.114,8.641-17.587c0-4.881-0.854-8.744-2.461-11.412V12.142z"/>
9
<rect id="basefill" x="29.822" y="16.142" fill="#4D4B4C" width="4.355" height="4.273"/>
10
<path id="lightfill" fill="#FFFFFF" d="M31.998,47.768c-1.402-0.959-4.637-6.229-4.637-13.497c0-5.775,1.271-8.566,2.207-9.855

11
 h4.857c0.945,1.293,2.213,4.08,2.213,9.855C36.639,41.542,33.402,46.809,31.998,47.768z"/>
12
</svg>

Этот код был экспортирован из моего редактора, Adobe Illustrator. Он почти нечитабельный на первый взгляд. Ниже приведена та же разметка в упрощенном виде:

1
2
<svg class="svg-light" 
3
  viewBox="0 0 64 64" 
4
	xmlns="http://www.w3.org/2000/svg"
5
	>
6
7
	<path class="outline"
8
		d="M38.178,12.142H25.823v10.723c-1.606,2.67-2.461,6.529-2.461,11.406c0,9.473,4.748,17.587,8.636,17.587c3.889,0,8.641-8.114,8.641-17.587c0-4.881-0.854-8.744-2.461-11.412V12.142z"
9
		/>
10
11
	<rect class="base"
12
		x="29.822"
13
		y="16.142"
14
		width="4.355"
15
		height="4.273"
16
	 	/>
17
18
	<path class="bulb"
19
		d="M31.998,47.768c-1.402-0.959-4.637-6.229-4.637-13.497c0-5.775,1.272-8.566,2.207-9.856h4.858c0.945,1.293,2.213,4.081,2.213,9.856C36.639,41.542,33.402,46.809,31.998,47.768"
20
	 	/>
21
</svg>

Я значительно упростил этот код xml за счет удаления избыточного кода разметки, который программа выводит по умолчанию. Мой базовый элемент SVG содержит следующее:

  • Класс svg-light. Я воспользовался префиксом svg- для легкого обращения к элементам внутри конкретного элемента SVG.
  • Свойство viewbox. При помощи значения свойства viewbox задается соотношение размеров сторон документа, и оно является эквивалентом размера монтажной области в Illustrator.
  • Свойство xmnls. При помощи этого свойства задается пространство имен XML SVG и упрощается понимание разметки некоторыми агентами пользователя.

Я добавил классы внутри открывающих тегов элементов, содержащихся в внутри SVG, при помощи которых определяются фигуры, составляющие изображение, такие как пути, круги и прямоугольники. Все расположенные в линию свойства элементов, такие как их координаты, я перенес на новые строки. Также я добавил отступ для всех внутренних элементов так, чтобы они располагались справа от базового тега SVG.

Все это было сделано не случайно. Во-первых, благодаря этому код намного легче читать. Во-вторых, в предпочитаемом мною редакторе кода, Sublime Text 3, я запросто могу свернуть отдельные элементы в элементах SVG или сами элементы SVG полностью, в то время как имена классов по-прежнему помогают помнить контекст о том, чем являются те элементы.

Code folding of SVG in Sublime Text 3Code folding of SVG in Sublime Text 3Code folding of SVG in Sublime Text 3
Сворачивание кода SVG в Sublime Text 3

Рождественские огни

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

Взгляните на Pen (* фрагмент кода) Light, созданный Noah Blon (@noahblon) на CodePen

Мне нужно анимировать элемент path, которому я добавил класс bulb в SVG.

1
2
<path class="bulb"
3
	d="M31.998,47.768c-1.402-0.959-4.637-6.229-4.637-13.497c0-5.775,1.272-8.566,2.207-9.856h4.858c0.945,1.293,2.213,4.081,2.213,9.856C36.639,41.542,33.402,46.809,31.998,47.768"
4
	/>

При помощи CSS я задам для огонька цвет заливки и определю его свойства анимации.

1
2
.svg-light .bulb {
3
    fill: hsl(204, 70%, 23%);
4
    animation-name: glow-blue;
5
    animation-duration: 1s;
6
    animation-iteration-count: infinite;
7
    animation-timing-function: ease-in-out;
8
    animation-direction: alternate;
9
}

Свойство fill позволяет нам задать цвет элемента SVG. По возможности я люблю использовать модель HSL (hue, saturation, lightness) (* модель цветовоспроизведения «тон-насыщенность-яркость») для определения значений цветов, поскольку она легка для понимания. Здесь я задал синий цвет (hue 204) и оставил значение яркости низким, 23%, что значит, у нас получится темно-синий цвет.

Я настроил огонек так, чтобы он анимировался при помощи анимации по ключевым кадрам под названием glow-blue. Продолжительность этой анимации – 1 секунда. Анимация повторяется бесконечно долго, что значит, она будет выполняться всегда. Анимация распределена во времени таким образом, что она выполняется медленнее в начале и в конце ключевых кадров, благодаря чему получается более плавный переход в начальной и конечной точках анимации. Наконец, в качестве значения направления анимации установлено alternate (* чередование), что значит, она будет выполняться в ту и в другую сторону с начала до конца и опять обратно.

Совет: вы, вероятно, знаете, что имеется краткая форма записи правил CSS-анимации, однако я обычно предпочитаю разбивать правила, чтобы их было легче понимать, менять и повторно использовать в других анимациях при их сцеплении.

Теперь я определю анимацию по ключевым кадрам glow-blue:

1
2
@keyframes glow-blue {
3
    0% { fill: hsl(204, 80%, 23%); }
4
    100% { fill: hsl(204, 80%, 63%); }
5
}

Здесь я задал начальный и конечный цвета заливки элемента, для которого эта анимация применяется. Единственное значение, которое меняется, – яркость цвета (часть «l» в hsl), что означает, что огонек будет меняться от темной к светлой версии при той же самой насыщенности. Это интуитивный синтаксис, предоставляемый HSL.

Поскольку я настроил анимацию таким образом, что она будет менять направление бесконечно долго, огонек будет меняться от темной к светлой версии и никогда не остановится (* когда-то таки остановится )). Поэтому возникнет впечатление, что он мигает.

Анимируем множество огоньков

Что ж, теперь давайте обратимся к нашему внутреннему Clark W. Griswold (* персонаж «National Lampoon's Vacation (film series)», 1983 – 2015) и реализуем анимацию всех Рождественских огоньков. Вот что мы создадим:

Взгляните на Pen 540257e4a8b727e435c8e4033602ebb0, созданный Noah Blon (@noahblon) на CodePen

Я создал пять по-разному окрашенных огоньков. Каждый огонек обернут в div шириной 20%. Эти элементы div затем выровнены по левому краю, благодаря чему они располагаются на одной линии. Поскольку я не задал для элемента SVG высоты или ширины и оставил значение свойства viewbox тем же, размер элемента  SVG меняется в зависимости от размера его родительского элемента без нарушения соотношения размеров или качества. Последнее является одним из значительных преимуществ SVG.

1
2
<svg class="svg-light svg-light--red">

Для каждого элемента SVG я добавил расширение базового класса svg-light, для которого указывается суффикс цвета (например svg-light--red). Ниже приводится фрагмент правил, использованных мною для анимации множества огоньков:

1
2
.svg-light .bulb {
3
	animation-duration: 1s;
4
	animation-iteration-count: infinite;
5
	animation-timing-function: ease-in-out;
6
	animation-direction: alternate;
7
}
8
9
.svg-light--red .bulb {
10
	fill: hsl(6, 63%, 16%);
11
	animation-name: glow-red;
12
	animation-delay: .5s;
13
	animation-duration: 1.25s;
14
}
15
16
@keyframes glow-red {
17
	0% { fill: hsl(6, 63%, 16%); }
18
	100% { fill: hsl(6, 63%, 56%); }
19
}

Базовые свойства анимации по-прежнему применяются к базовому классу svg-light, за счет чего они могут быть использованы повторно во всех огоньках. Для каждой разновидности цвета я создал отдельную анимацию по ключевым кадрам вроде glow-red или glow-blue и установил для них различные задержки анимации и продолжительности. За счет этого огоньки будут мигать их соответственными цветами и не будут все мигать в одно и то же время.


Rudolph the Red-Nosed Reindeer

(* Rudolph the Red-Nosed Reindeer – Рудольф, 9-й северный олень Санты. Персонаж, созданный Robert Lewis May, со светящимся носом). Я воспользуюсь теми же принципами, описанными выше, для анимации наиболее известного северного оленя – Рудольфа. Ниже показан конечный результат:

Взгляните на Pen SVG Rudolph Icon Animated with CSS, созданный Noah Blon (@noahblon) на CodePen

Для начала я реализую анимацию красного носа:

1
2
.svg-rudolph .nose {
3
    animation-name: glow;
4
    animation-duration: 6s;
5
    animation-iteration-count: infinite;
6
    animation-timing-function: ease-in-out;
7
    animation-direction: alternate;
8
}
9
10
@keyframes glow {
11
    0% { fill: hsl(6, 93%, 16%); }
12
    50% { fill: hsl(6, 93%, 56%); }
13
    100% { fill: hsl(6, 93%, 56%); }
14
}

Код выглядит довольно подобно таковому для нашего Рождественского огонька. В анимации по ключевым кадрам я делаю так, чтобы анимация выполнялась сначала на 50%, а затем – на 100%. Поскольку продолжительность анимации составляет 6 секунд, то это означает, что через три секунды нос станет светло-красным и останется таковым в течение последующих трех секунд до конца анимации. Также, поскольку я настроил анимацию таким образом, чтобы она меняла свое направление, то далее она будет выполняться с конца к началу. Поэтому нос будет оставаться полностью красным в течение последующих трех секунд, перед тем как, наконец, потемнеть в последние три секунды. Понимание взаимосвязи между процентами, указанными в ключевых кадрах, и определениями анимации, такими как продолжительность, – ключ к созданию эффективных CSS-анимаций.

Также я реализовал анимацию для блика на носе Руди:

1
2
.svg-rudolph .nose-highlight {
3
    fill-opacity: 0;
4
    animation-name: highlight-fade;
5
    animation-duration: 6s;
6
    animation-iteration-count: infinite;
7
    animation-timing-function: ease-in-out;
8
    animation-direction: alternate;
9
}
10
11
@keyframes highlight-fade {
12
    0% { fill-opacity: 0; }
13
    25% { fill-opacity: 0; }
14
    100% { fill-opacity: 1; }
15
}

Здесь я анимирую другое свойство SVG, fill-opacity. В качестве значения этого свойства устанавливается значение между 0 и 1; при 0 заливка становится полностью прозрачной, при 1 – полностью непрозрачной. Наконец, я оживлю Руди еще немного, сделав так, чтобы его глаза мигали:

1
2
.svg-rudolph .eye {
3
    animation-name: blink;
4
    animation-duration: 8s;
5
    animation-iteration-count: infinite;
6
    transform-origin: 50%;
7
}
8
9
@keyframes blink {
10
    0% { transform: scaleX(1) scaleY(1); }
11
    1% { transform: scaleX(1.3) scaleY(0.1); }
12
    2% { transform: scaleX(1) scaleY(1); }
13
    60% { transform: scaleX(1) scaleY(1); }
14
    61% { transform: scaleX(1.3) scaleY(0.1);}
15
    62% { transform: scaleX(1) scaleY(1); }
16
    100% { transform: scaleX(1) scaleY(1); }
17
}

Я создал анимацию под названием blink. Эта анимация выполняется в течение 8 секунд и никогда не останавливается. Я не настраиваю анимацию в этот раз таким образом, чтобы она меняла свое направление, а вместо этого анимация будет выполняться от начала до конца и затем повторяться с начала. (* В качестве значения по умолчанию для направления используется normal, при котором анимация будет выполняться от начала до конца при каждом цикле).

В ключевых кадрах анимация мигания создается при помощи манипулирования масштабом глаз по осям X и Y. Например, по достижении отметки 1% глаза изменяются в 1.3 раза от их размера по оси Х и в 0.1 раза от их нормального размера по оси Y. Другими словами, они становятся немного шире и значительно короче. Спустя 1% от продолжительности анимации масштаб глаз возвращается к норме. Поэтому изменение масштаба происходит чрезвычайно быстро; 8 секунд / 100 = 8 сотых секунды.

Ключевым моментом при использовании трансформаций для анимирования элементов SVG является установка значения свойства transform-origin. В большинстве случаев для того, чтобы трансформация была корректно применена в SVG, мы должны установить в качестве начальных координат этой трансформации координаты центра элемента. В противоположность элементу HTML по умолчанию в качестве начальных координат трансформации элемента SVG используется его верхний левый угол, координаты (0,0). За счет указания в качестве координат transform-origin (50%, 50%) оси Х и Y трансформации будут начинаться в центре элемента, и трансформации затем будут применяться корректно.

Обратите внимание: в Firefox имеется проблема при установлении значений свойства transform-origin. К сожалению, при установлении в качестве значения transform-origin 50% происходит собственно сбрасывание значений координат X/Y элемента. Одним из решений этой проблемы является возвращение элемента в его исходную позицию.


Ding Dong Merrily on High

(* Ding Dong Merrily on High – рождественская песня). В этом примере я реализую анимацию звона колокольчика следующим образом:

Взгляните на Pen 63cdc3e8e785028deb35132d889b6090, созданный Noah Blon (@noahblon) на CodePen

Давайте взглянем на фрагмент разметки SVG:

1
2
	<svg class="svg-bell" viewBox="0 0 88 72" xmlns="http://www.w3.org/2000/svg">
3
		<g class="group-striker">
4
			<circle class="outline"
5
				cx="43.998" 
6
				cy="54.571" 
7
				r="7.99"
8
				/>
9
			<circle class="fill"
10
				cx="43.998" 
11
				cy="54.567" 
12
				r="3.99"
13
				/>
14
		</g>
15
		<g class="group-bell">
16
			<path class="outline"
17
				d="M71.5,38.184h-3.291l-6.213-21.879c-1.367-4.816-5.951-8.693-10.904-9.514C50.91,3.02,47.812,0,43.996,0c-3.812,0-6.91,3.018-7.092,6.787c-4.957,0.822-9.539,4.697-10.908,9.514l-6.211,21.883h-3.289l-4.498,15.85h19.251H36h15.994h3.963h20.041L71.5,38.184z M40.975,6.611C41.229,5.143,42.455,4,43.996,4c1.543,0,2.77,1.143,3.025,2.615L40.975,6.611z"
18
				/>
19
			<path class="fill"
20
				d="M29.844,17.395c1.045-3.678,5.156-6.783,8.975-6.783l10.355,0.004c3.82,0,7.93,3.105,8.975,6.783l5.902,20.785H23.943L29.844,17.395z"
21
				/>
22
			<polygon class="fill"
23
				points="19.52,42.184 68.477,42.184 70.705,50.033 17.291,50.033"
24
				/>
25
		</g>
26
	</svg>

Я обернул контур колокольчика и заливку в тег <g> (групповой тег). Этот тег очень полезен для организации элементов подобно тому, как вы могли бы обернуть несколько элементов HTML при помощи <div>. Анимации могут быть применены к группе. Поскольку в этом случае мне необходимо, чтобы поворачивался как контур, так и заполнение колокольчика, я могу просто повернуть группу, а не каждый элемент по отдельности.

1
2
.svg-bell .group-bell {
3
    animation-name: bell-ring;
4
    animation-duration: 3s;
5
    animation-iteration-count: infinite;
6
    animation-timing-function: ease-in-out;
7
    animation-delay: -1.5s;
8
    animation-direction: alternate;
9
    transform-origin: 50%;
10
}
11
12
@keyframes bell-ring {
13
    0% { transform: rotate(27deg); }
14
    100% { transform: rotate(-27deg); }
15
}

Этот код CSS должен быть вам уже знаком, однако здесь имеется несколько новых моментов. Для начала, в анимации по ключевым кадрам колокольчик трансформируется, однако вместо трансформации масштаба выполняется трансформация значения свойства rotation (* вращение; поворот) элемента. За счет этой анимации колокольчик колеблется между 27 и -27 градусами.

Еще я установил в качестве значения animation-delay отрицательное значение. Из-за этого анимация начинается по прошествии указанного времени анимации. В этом случае анимация начнется не после задержки длиной в 1.5 секунды, а собственно по прошествии 1.5 секунды анимации. За счет этого анимация колокольчика начнется с нейтральной позиции, в которой колокольчик находится по прошествии 1.5 секунды анимации, а не повернутой позиции, в которой колокольчик находится по прошествии 0 секунд анимации.

1
2
.svg-bell .striker {
3
    animation-name: striker-move;
4
    animation-duration: 3s;
5
    animation-iteration-count: infinite;
6
    animation-timing-function: linear;
7
    animation-delay: 1.5s;
8
    animation-direction: alternate;
9
    transform-origin: 50%;
10
}
11
12
@keyframes striker-move {
13
    0% { transform: translateX(3px); }
14
    100% { transform: translateX(-3px); }
15
}

Я применил подобную анимацию к группе, содержащей элементы языка колокольчика. В этот раз, однако, я переношу, или перемещаю, элементы вдоль оси Х, а не поворачиваю, так что язык будет колебаться вправо и влево.


"Let It Snow! Let It Snow! Let It Snow!"

(* «Let It Snow! Let It Snow! Let It Snow!», или «Let It Snow»; песня, написанная поэтом Sammy Cahn и композитором Jule Styne в Июле 1945 года). В этом примере мы реализуем анимацию падающего снега внутри стеклянного шара.

Взгляните на Pen 2addb5f98c757d61cec87bdcacb5870d, созданный Noah Blon (@noahblon) на CodePen

Я создал ряд элементов circle для представления снега и разместил эти элементы по периметру стеклянного шара, оборачивая их в тег <g>.

Снег не виден за пределами шара, поскольку я применил отсеченную область (* область, ограничивающая скрытый графический объект, воспроизводимый только при печати) для группы, содержащей снег. Отсеченная область – фигура, которую можно применить к элементам SVG, маскируя другие элементы внутри нее. В примере с нашим шаром я создал округлую отсеченную область, которая охватывает внутреннюю часть шара.

1
2
<defs>
3
	<clipPath id="globeClipPath">
4
  		<circle cx="32" cy="31" r="26.825"/>
5
	</clipPath>
6
</defs>

Тег <clipPath> – наш маскирующий элемент; чтобы им воспользоваться, мы должны добавить ему ID.

Я обернул отсеченную область в элемент defs. SVG позволяет нам создавать элементы, которые мы можем использовать позднее, такие как отсеченная область, фильтры или фигуры, которые мы можем штамповать. Оборачивание определений вроде отсеченных областей в элемент defs, благодаря чему код SVG становится более читабельным, относится к установившейся практике.

Для применения отсеченной области мы указываем ее url, которым в нашем случае является ее ID, перед которым указан символ решетки, во встроенном свойстве для указания отсеченной области элемента SVG:

1
2
<g class="group-snow" clip-path="url(#globeClipPath)">
3
    <circle class="snow" 
4
        cx="49.498" 
5
        cy="8.482" 
6
        r="2.5"
7
        />
8
    <circle class="snow" 
9
        cx="35.748" 
10
        y="2.783" 
11
        r="2.5"
12
        />
13
    <circle class="snow" 
14
        cx="21.001" 
15
        cy="4.728" 
16
        r="2.5"
17
        />
18
    <circle class="snow" 
19
        cx="28.25" 
20
        cy="2.783" 
21
        r="2.5"
22
        />
23
    <circle class="snow" 
24
        cx="42.997" 
25
        cy="4.728" 
26
        r="2.5"
27
        />
28
    <circle class="snow" 
29
        cx="14.502" 
30
        cy="8.482" 
31
        r="2.5"
32
        />
33
    <circle class="snow" 
34
        cx="9.194" 
35
        cy="13.793" 
36
        r="2.5"
37
        />
38
    <circle class="snow" 
39
        cx="54.806" 
40
        cy="13.793" 
41
        r="2.5"
42
        />
43
</g>

Теперь снег виден только внутри той округлой отсеченной области.

Анимация снега реализуется при помощи тех же приемов, которые я описал ранее; он переносится вдоль оси Y, и значение свойства fill-opacity приближается к нулю по окончании анимации.

1
2
.svg-snowglobe .snow { 
3
	animation-name: snowfall;
4
	animation-duration: 10s;
5
	animation-iteration-count: infinite;
6
	animation-timing-function: ease-in;
7
}
8
9
.svg-snowglobe .snow:nth-child(1) { animation-delay: 2s; }
10
.svg-snowglobe .snow:nth-child(2) { animation-delay: 4s; }
11
.svg-snowglobe .snow:nth-child(3) { animation-delay: 6s; }
12
.svg-snowglobe .snow:nth-child(4) { animation-delay: 8s; }
13
.svg-snowglobe .snow:nth-child(5) { animation-delay: 10s; }
14
.svg-snowglobe .snow:nth-child(6) { animation-delay: 12s; }
15
.svg-snowglobe .snow:nth-child(7) { animation-delay: 14s; }
16
.svg-snowglobe .snow:nth-child(8) { animation-delay: 16s; }
17
.svg-snowglobe .snow:nth-child(9) { animation-delay: 18s; }
18
.svg-snowglobe .snow:nth-child(10) { animation-delay: 20s; }

Да, селекторы CSS3 можно применять к элементам SVG! Здесь я задал для каждого элемента снежинки различные задержки, благодаря чему они не будут падать все одновременно (* псевдокласс :nth-child используется для добавления стиля к элементам на основе нумерации в дереве элементов).


Season's Greetings

(* Season's Greetings – поздравления с праздником). Наконец, я реализую анимацию некоторого текста на основе SVG для достижения результата вроде следующего:

Взгляните на Pen Message, созданный Noah Blon (@noahblon) на CodePen

SVG предоставляет нам возможность применения штрихов к элементам SVG при помощи CSS. В последнем примере я покажу вам, как постепенно прорисовать штрих текста элемента.

Для реализации этой анимации я воспользовался следующими свойствами штриха:

  • stroke-width: ширина штриха. Значение этого свойства определяется в зависимости от размера элемента SVG и поэтому отзывчиво реагирует на его изменения.
  • stroke: цвет штриха.
  • stroke-dasharray: пунктирный штрих. При помощи массива чередующихся значений определяется длина черточек пунктирной линии и промежутков между ними.
  • stroke-dashoffset: место начала штриха по отношению к длине пути.

Для получения текста, прорисовываемого штрихами, мне нужно немного поработать в графическом редакторе. Последовательность необходимых действий следующая:

  1. Создать текстовый элемент.
  2. Преобразовать тот текст в векторные пути.
  3. Объединить те пути в сложный путь.

Ниже приведен мой код CSS для настройки анимации:

1
2
.svg-message .text {
3
    stroke-width: 1px;
4
    stroke: hsl(6, 63%, 36%);
5
    stroke-dasharray: 1865.753px 1865.753px;
6
    stroke-dashoffset:  1865.753px ;
7
    fill-opacity: 0;
8
    fill: hsl(6, 63%, 36%);
9
    animation-name: stroke, fill;
10
    animation-duration: 1s;
11
    animation-delay: 0, 1s;
12
    animation-iteration-count: 1;
13
    animation-timing-function: ease-in-out;
14
    animation-fill-mode: forwards;
15
}
16
17
@keyframes fadeIn {
18
    0% { fill-opacity: 0; }
19
    100% { fill-opacity: 1; }
20
}
21
22
@keyframes drawStroke {
23
    100% { stroke-dashoffset: 0 }
24
}

Я задал в качестве значения свойства stroke-dasharray значение длины всего пути (вы можете найти это значение в Illustrator в панели Document Info, выбрав пункт Object). Затем я задал в качестве значения stroke-dashoffset значение всей длины пути, в результате чего весь текст становится невидимым. Затем при помощи анимации, за счет которой анимируется свойство stroke-dashoffset, текст будет постепенно прорисовываться штрихами на экране.

Если вы хотите познакомиться с этим приемом поближе, то ознакомьтесь с постом Jake Archibald Animated line drawing in SVG.

Также я сделал так, чтобы текст постепенно проявлялся после завершения прорисовки линий, при помощи свойства fill-opacity подобно тому, как я это сделал в примере со стеклянным шаром.


Дальнейшие шаги в области SVG и CSS

В этом руководстве я показал, что при помощи CSS и SVG вы можете создать довольно эффектные анимации. Если вы хотите разобраться со всем кодом, а также с некоторыми дополнительными анимациями, то можете скачать примеры с Github или ознакомиться с моей коллекцией на Codepen.

Если вам нужно что-нибудь посложнее, то вы могли бы попробовать разобраться с контролем CSS-анимаций при помощи JavaScript или дополнить ваши CSS-анимации более сложными JavaScript-анимациями, вроде тех, что поддерживаются великолепной библиотекой JS SVG Snap SVG.

Спасибо, что были со мной сегодня. Не могу дождаться придуманных вами творений.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Web Design tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.