Анімація елементу Path в SVG

Цей пост хочу почати з SVG-картинок взятих з порталу thenounproject.com (до речі, на ньому ви знайдете величезну купу іконок на будь-який випадок життя) з додавання невеликої кількості магії.

Created by artworkbeanfrom the Noun Project
Created by Oliviu Stoianfrom the Noun Project




Вперше такою анімацією мене здивували Texty.org.ua у своїх роботах: тут та тут. Що тут скажеш: лідери в галузі журналістики даних в Україні, в розрізі інтерактивної візуалізації — так точно.

Статті з анімованими іконками виглядають живо, смачно, незвично та привертають увагу. З назви посту ви могли здогадатися, що даного ефекту можна досягнути зарахунок анімації старого доброго SVG. Рекомендую ознайомитися з плюшками формату Scalable Vector Gragphics на wiki та статті. Нижче спробую пояснити як отримати щось схоже, маніпулюючи елементом path, що входить до SVG.

Що таке Path в SVG

В SVG зображеннях існують 5 основних елементів: text (текст, як не дивно), line (лінія), rect (прямокутники), circle (кола), polygon, polyline (ламана) та path. Детальніше про кожен з елементів можна дізнатися тут.
Path можна вважати базовим елементом, оскільки він створений для визначення будь-якої фігури, тобто за допомогою нього можна отримати як лінію, так і коло, так і сегмент кола. Path має наступний формат запису:


< path d="M 100 100 L 300 100 L 200 300 z" fill="#000" 
    stroke="black" stroke-width="3" 
    stroke-dasharray="10 10" stroke-dashoffset="5" 
/>

Основним атрибутом path є d — як раз в ньому задається фігура: лінії, зміщення, криві Безьє тощо. Але увага цього посту буде приділена двом іншим атрибутам: stroke-dasharray та stroke-dashoffset, завдяки яким і досягається необхідний ефект анімації. Параметр stroke-dasharray="a b" задає довжину пунктиру a та проміжок між пунктиром b. В той же час параметром stroke-dashoffset="c" можна задавати зміщення початку пунктиру.

Для кращого розуміння, наведу інтерективну іграшку. (інтерпретація власна, ідея взята тут)

stroke-dasharray = «0 0»

stroke-dashoffset = «0»


Таким чином змінюючи значення stroke-dasharray в часі створюється ефект промальовки ліній — те, що ми звикли називати анімацією.

Додаємо анімацію до path

Для зручності роботи з DOM-елементами буду використовувати D3.js (більше про бібліотеку тут), хоча ви вільні викостовувати будь-що інше. Основна задача полягає у зміні з часом параметра stroke-dasharray, а точніше його першого значення, що відповідає за довжину пунктиру. Друге значення залишаємо без змін, та встановлюємо рівним довжині path.

Сам рабочий код для малюнків на початку статті виглядає наступним чином:


var s = d3.select("svg#pic"), s1 = d3.select("svg#pic1");

function transition(path){
  path.transition()
    .duration(5000)
    .attrTween("stroke-dasharray", tweenDash)
    .each("end", function() { d3.select(this).call(transition); }); // loop
}

function tweenDash() {
  var l = this.getTotalLength(),
      i = d3.interpolateString("0," + l, l + "," + l); // interpolation of stroke-dasharray attr
  return function(t) {
    return i(t);
  };
}
// add transition function to paths
var paths = s.selectAll("path").call(transition),
  paths1 = s1.selectAll("path").call(transition);

Фунція transition задає необхідний ефект зміни з часом атрибута stroke-dasharray, проте варто звернути на атрибут transition.attrTween(name, tween), який викликає інтерполятор з функції tweebDash() — він став для мене відкриттям в бібліотеці D3.js. Ще один інтерполятор d3.interpolateString задає зміну значення атрибута stroke-dasharray від (0, L) до (L, L), де L — довжина path. Більше про атрибути та інтерполятори D3.js можна дізнатися з документації.

Ось такими простими маніпуляціями можна створювати гарні, анімовані іконки.
Ви можете спитаєте: де можна намалювати свої svg-картинки? Варіанти відповіді: Adobe Illustrator, Inkscape — або шукайте на стоках.

————-

Для линівих варто звернути увагу на вже існуючі JS бібліотеки, що можуть спростити задачу анімації елементів SVG:

Список джерел: