Простой пример анимации контуров в SVG
- 31 января 2023
SVG-графика поддаётся анимированию. В этой статье мы покажем, как анимировать отрисовку контуров.

Сначала мы разберём свойства SVG-анимации и синтаксис библиотеки Anime.js, а затем анимируем отрисовку котов. Если вы уже знакомы с теорией, можете сразу перейти к практике.
Для анимации нам понадобятся:
- элемент
path
— контур; - атрибуты обводки:
stroke
иstroke-dashoffset
; - библиотека Anime.js.
Контур и обводка в SVG
path
— это способ описать траекторию внутри векторного изображения. Далее эту траекторию можно отобразить, задав ей обводку. Как выглядит path
:
<svg xmlns="http://www.w3.org/2000/svg" width="205" height="118" viewBox="0 0 205 118" fill="none">
<path d="M3 55.5286C8.43655 49.2385 14.7452 43.6721 21.6476 39.052C23.1876 38.0129 25.4513 37.1037 26.6945 38.4768C27.381 39.2375 27.3995 40.3693 27.384 V45.43 C8.43 48.57" stroke="white" stroke-width="5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
Обводка задаётся с помощью атрибута stroke
или аналогичного CSS-свойства. За толщину отвечает stroke-width
, за скругление — stroke-linecap: round;
.
stroke-dashoffset
задаёт смещение обводки. Этот атрибут можно анимировать. Например, с его помощью создаётся примитивный индикатор загрузки.
Синтаксис библиотеки Anime.js
Мы будем использовать Anime.js, потому что с ней легко настроить анимацию — библиотека берёт на себя часть вычислений. Например, когда мы не можем посчитать длину контура, anime.setDashoffset
делает это за нас.
У библиотеки простой синтаксис. В примере ниже мы в первой строке находим все контуры, а внутри anime()
описываем параметры анимации. Последняя строка указывает на изменяемое свойство, а остальные являются параметрами и не затрагивают конкретных атрибутов или свойств элемента.
const paths = document.querySelectorAll('svg path');
anime({
targets: paths,
duration: 2000,
delay: 200,
easing: 'easeInOutExpo',
strokeDashoffset: [anime.setDashoffset, 0]
});
targets
— элементы, у которых будет меняться значение атрибута.
duration
— длительность анимации в миллисекундах.
delay
— задержка перед началом анимации.
easing
— временная функция. Здесь для примера приводим easeInOutExpo
, а полный список временных функций вы найдёте на сайте библиотеки.
strokeDashoffset
— изменяемый атрибут. Передаём туда массив с исходным и конечным значениями атрибута.
Мы не сможем вычислить длину каждого контура в SVG с котами, поэтому используем anime.setDashoffset
, чтобы получить длину.
В результате получаем нечто похожее на такую анимацию:

Можно воздействовать на любые свойства и атрибуты, которые поддаются анимированию. Например, opacity
, fill
, background-color
или transform
:
const circles = document.querySelectorAll('svg circle');
anime({
targets: circles,
duration: 1000,
easing: 'easeInOutExpo',
opacity: [0, 1],
scale: [0, 1]
});
В результате получится анимация плавного появления окружности из прозрачности.

💫 Научитесь создавать анимации
Приходите на наши курсы — мы показываем там самые популярные и интересные техники для создания эффектов на CSS и JavaScript.
Практика: создаём SVG-анимацию контуров
Соберём анимацию — отрисуем три изображения с котами. Используем для этого заготовку — SVG-файл.

Экспортируем каждое изображение в формате SVG и поместим в <div>
с классом wrapper
.
<div class='wrapper'>
//Сюда помещаем все <svg>
</div>
Найдём все контуры и анимируем так, как показывали выше:
const paths = document.querySelectorAll('svg path');
anime({
targets: paths,
duration: 2000,
delay: 200,
easing: 'easeInOutExpo',
strokeDashoffset: [anime.setDashoffset, 0]
});
See the Pen anime.js step 1 by Mikhail (@smfms) on CodePen.
Последовательная отрисовка картинок
Сейчас все изображения рисуются одновременно. Сделаем так, чтобы картинки появлялись последовательно. Используем для этого timeline
— временной отрезок, на котором расставляется анимация в определённом порядке и с нужной задержкой.
Синтаксис timeline
:
const timeline = anime.timeline({
duration: 3000,
easing: 'easeInOutExpo'
});
timeline.add({
targets: firstImagePaths,
strokeDashoffset: [anime.setDashoffset, 0]
});
timeline.add({
targets: secondImagePaths,
strokeDashoffset: [anime.setDashoffset, 0]
});
timeline.add({
targets: thirdImagePaths,
strokeDashoffset: [anime.setDashoffset, 0]
});
timeline
создаётся один раз. Он принимает параметры, общие для каждой анимации, которая будет на нём располагаться — в нашем случае duration
и easing
. Затем при помощи timeline.add()
добавляются анимации — они будут выполняться последовательно.
💡 Некоторые параметры можно переопределять — например, delay
, easing
, duration
. А вот loop
и direction
переопределить нельзя. Параметр loop
отвечает за бесконечное проигрывание, direction
— за направление анимации.
Задержка следующей анимации
Чтобы начать анимацию не сразу после окончания предыдущей, передайте второй аргумент со временем в миллисекундах:
timeline.add({
targets: firstImagePaths,
strokeDashoffset: [anime.setDashoffset, 0]
});
timeline.add({
targets: secondImagePaths,
strokeDashoffset: [anime.setDashoffset, 0]
}, ‘+=500’);
Вторая анимация начнётся спустя полсекунды после окончания предыдущей.
Если вместо знака +
поставить -
, анимация начнётся заранее — когда предыдущей останется проигрывать 500 миллисекунд. Так можно управлять композицией.
See the Pen anime.js step 2 by Mikhail (@smfms) on CodePen.
Стейджер
Напоследок рассмотрим ещё одну возможность управлять анимацией контура — стейджер. Каждый кот состоит из нескольких контуров — сделаем так, чтобы эти контуры рисовались последовательно.
Стейджер реализуется при помощи конструкции anime.stagger(<время задержки>)
.
timeline.add({
targets: firstImagePaths,
strokeDashoffset: [anime.setDashoffset, 0],
delay: anime.stagger(300)
});
Теперь каждый последующий контур начнёт анимироваться спустя 300 миллисекунд после начала анимирования предыдущего.
See the Pen anime.js step 3 by Mikhail (@smfms) on CodePen.
Итог
Мы рассмотрели лишь один из видов анимаций векторной графики, но есть и другие. Например, если совместить разобранную выше анимацию с SVG-масками, можно добиться такого эффекта:

Можно анимировать форму фигур. Такая анимация называется морфингом.

Ещё один эффект достигается при помощи SVG-фильтров:

Материалы по теме
«Доктайп» — журнал о фронтенде. Читайте, слушайте и учитесь с нами.
Читать дальше

Случайное число из диапазона
Допустим, вам зачем-то нужно целое случайное число от min
до max
. Вот сниппет, который поможет:
function getRandomInRange(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
- Math.random () генерирует случайное число между 0 и 1. Например, нам выпало число
0.54
. - (max — min + 1): определяет количество возможных значений в заданном диапазоне.
10 - 0 + 1 = 11
. Это значит, что у нас есть 11 возможных значений (0, 1, 2, ... 10). - Math.random () * (max — min + 1): умножает случайное число на количество возможных значений:
0.54 * 11 = 5.94
. - Math.floor (): округляет число вниз до ближайшего целого. Так,
Math.floor(5.94) = 5
. - ... + min: смещает диапазон так, чтобы минимальное значение соответствовало
min
. Но в нашем примере, так какmin = 0
, это не изменит результат. Пример:5 + 0 = 5
. - Итак, в нашем примере получилось случайное число 5 из диапазона от 0 до 10.
Чтобы протестировать, запустите:
console.log(getRandomInRange(1, 10)); // Тест
- 7 сентября 2023

В чём разница между var и let
Если вы недавно пишете на JavaScript, то наверняка задавались вопросом, чем отличаются var
и let
, и что выбрать в каждом случае. Объясняем.
var
и let
— это просто два способа объявить переменную. Вот так:
var x = 10;
let y = 20;
Переменная, объявленная через var
, доступна только внутри «своей» функции, или глобально, если она была объявлена вне функции.
function myFunction() {
var z = 30;
console.log(z); // 30
}
myFunction();
console.log(z); // ReferenceError
Это может создавать неожиданные ситуации. Допустим, вы создаёте цикл в функции и хотите, чтобы переменная i
осталась в этой функции. Если вы используете var
, эта переменная «утечёт» за пределы цикла и будет доступна во всей функции.
Переменные, объявленные с помощью let
доступны только в пределах блока кода, в котором они были объявлены.
if (true) {
let a = 40;
console.log(a); // 40
}
console.log(a); // ReferenceError
В JavaScript блок кода — это участок кода, заключённый в фигурные скобки {}
. Это может быть цикл, код в условном операторе или что-нибудь ещё.
if (true) {
let blockScoped = "Я виден только здесь";
console.log(blockScoped); // "Я виден только здесь"
}
// здесь переменная blockScoped недоступна
console.log(blockScoped); // ReferenceError
Если переменная j
объявлена в цикле с let
, она останется только в этом цикле, и попытка обратиться к ней за его пределами вызовет ошибку.
- 30 августа 2023

Быстрый гайд по if, else, else if в JavaScript
Допустим, вы собираетесь идти на прогулку. Если на улице солнечно, вы возьмёте с собой солнечные очки.
Это можно описать с помощью оператора if
.
let weather = "sunny";
if (weather === "sunny") {
console.log("Возьму солнечные очки");
}
А если погода не солнечная, а, скажем, дождливая, вы возьмете зонт.
Этот сценарий можно описать с помощью if-else
.
let weather = "rainy";
if (weather === "sunny") {
console.log("Возьму солнечные очки");
} else {
console.log("Возьму зонт");
}
Условный оператор if-else if-else
Теперь представим, что у вас есть несколько вариантов транспорта для дороги на работу: машина, велосипед, общественный транспорт. Выбор будет зависеть от различных условий, например, погоды и времени суток. Логично, что в дождь безопаснее ехать на автобусе, а в хорошую погоду можно прокатиться на машине или велосипеде, если утро и пробки. То есть схема такая:
И всё это очень легко описывается кодом:
let weather = "sunny";
let time = "morning";
if (weather === "rainy") { // если дождь, то только так
console.log("Еду на автобусе");
} else if (time === "morning") { // если не дождь и утро
console.log("Еду на велике мимо пробок");
} else { // если второе не дождь и не утро
console.log("Еду на машине");
}
Ветвление только может показаться сложным, но вообще оно очень логичное, если понять, какие действия после каких условий выполняются. Разберитесь один раз и поймёте на всю жизнь, 100%.
🐈
- 30 августа 2023

Как исправить ошибки SyntaxError в JavaScript
Ошибки SyntaxError появляются, если разработчик нарушил правила синтаксиса JavaScript, например, пропустил закрывающую скобку или точку с запятой. Давайте посмотрим, что означает каждая ошибка и в чём может быть проблема.
- 14 июля 2023

Ошибка TypeError: что это и как её исправить
Ошибки TypeError появляются, когда разработчики пытаются выполнить операцию с неправильным типом данных. Давайте разберём несколько примеров: почему появилась ошибка и как её исправить.
- 7 июля 2023

3 способа объявить функцию в JavaScript
Функции в JavaScript можно объявить тремя способами: через декларативное объявление, функциональное выражение или с помощью стрелок. Звучит сложно, но на самом деле всё совсем не так.
- 30 июня 2023

Как сделать простой слайдер на HTML и JavaScript
Вы сверстали сайт и сделали его красивым с помощью CSS. Осталось добавить интерактива, и можно добавлять проект в портфолио.
«Оживить» на сайте можно что угодно: меню, модальные окна, корзину, пагинацию… В этой статье мы разберём слайдер — посмотрим, как его сделать на чистом JavaScript. Слайдер пригодится для раздела с отзывами, фотографиями сотрудников, изображениями товаров или чего-нибудь ещё — всё зависит только от вашей фантазии и проекта.
☝ Мы покажем лишь один из возможных вариантов. Это не эталонное решение, да в разработке и не бывает единственно верного способа решить задачу. Но код точно работает, поэтому можете скопировать его в свой проект.
- 20 июня 2023

Полезные команды для работы с Node.js
Перед тем как рассматривать полезные команды при работе с Node.js, её необходимо установить.
Команды помогают узнать версию Node.js,
node -h
— показывает список всех доступных команд Node.js.
node -v
, node --version
— показывает установленную версию Node.js.
npm -h
— показывает список всех доступных команд пакетного менеджера npm
.
npm -v
, npm --version
— показывает установленную версию npm
.
Команда npm update npm -g
позволяет обновить версию npm
.
npm list --depth=0
показывает список установленных пакетов.
Команда npm outdated --depth=0
покажет список установленных пакетов, которые требуют обновления. Если все пакеты обновлены, список будет пустым.
npm install package
— позволяет установить любой пакет по его имени. Если при этом к команде добавить префикс -g
пакет будет установлен глобально на весь компьютер.
Команда npm i package
является укороченной альтернативой предыдущей команды.
Если вы хотите установить конкретную версию пакета, воспользуйтесь префиксом @
с номером версии. Например, npm install package@1.0.1
.
npm uninstall package
— удаляет установленный пакет по имени.
Команда npm list package
— покажет версию установленного пакета, а команда npm view package version
— последнюю версию пакета, которая существует.
Для работы с пакетным менеджером также пригодится файл package.json
, который должен лежать в директории, с которой происходит работа в консоли.
Он содержит различные мета-данные, например, имя проекта, версия, описания и автор. Также он содержит список зависимостей, которые будут установлены, если вызвать из этой папки команду npm install
.
Кроме этого он ещё имеет скрипты, которые вызывают другие команды консоли. Например, для этого файла вызов команды npm start
вызовет запуск задачи Grunt с именем dev
. А команда npm run build
вызовет скрипт build
, который запустит задачу в Grunt с именем build
.
Во время работы часто возникает необходимость установить некоторые пакеты. Если установить пакет с префиксом --save
, то он автоматически запишется в package.json
в раздел dependencies
. Такая же команда с префиксом --save-dev
запишет пакет в раздел devDependencies
.
Что такое nvm
nvm (илиNode Version Manager) — утилита, которая позволяет быстро менять версии Node.js.
Чтобы её установить, достаточно запустить скрипт
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.31.0/install.sh | bash
Теперь можно установить последнюю версию Node.js, например,5.0
с помощью команды nvm install 5.0
. Чтобы начать использовать её, введите команду nvm use 5.0
. Таким образом, можно быстро переключаться между версиями, например, для тестирования.
- 8 июня 2023

Как составлять регулярные выражения
Регулярное выражение — это последовательность символов (селекторов). Оно используется для поиска и обработки строк, слов, чисел и других текстовых данных.
Регулярные выражения выручают при решении разных задач. Например, с их помощью легко искать и менять строки в коде. Но чаще всего регулярные выражения используют для валидации форм. Давайте посмотрим, как это делать.
- 5 июня 2023

Проверка типа интерфейса в TypeScript
Проверка типов интерфейса — одна из ключевых возможностей TypeScript. Она помогает убедиться, что объект или класс содержат необходимый набор свойств и методов, указанных в интерфейсе. Благодаря проверке типов вы можете писать более надёжный код, ведь часть ошибок будет найдена ещё на этапе компиляции.
- 30 мая 2023