Від автора: на днях я зіткнувся з цікавою проблемою. Я хотів анімувати елемент з випадковим значенням animation-duration. Почав я з звичайної версії.
CSS код анімації:
@keyframes flicker {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
#red {
animation: flicker 2s ease alternate infinite;
}
В принципі, все добре працює. Але даний спосіб не рандомізованих, тут задані фіксовані 2 секунди. Я хотів зробити так, щоб тривалість анімації була довільною. По суті, я хотів написати так:
.element {
animation: flicker $randomNumber alternate infinite;
}
Де $randomNumber випадкове значення, обчислене програмно. В CSS препроцессорах типу Sass є функція random().
$randomNumber: random(5);
.thing {
animation-duration: $randomNumber + s;
}
Для вас, може бути, функція нормальна, проте не для мене. У цій функції є великий недолік. Іншими словами, як тільки обробляється CSS, рандомізація закінчується. Кількість обмежена цим значенням навіки (тобто поки наново не буде запущений препроцесор).
Тут принцип не як у генерації через JS (Math.random()), де генерується випадкове число при запуску JS.
Після громчайшего подиху я зрозумів, що це чудова можливість скористатися рідними CSS змінними (корисними властивостями)! Самі по собі змінні не спростять генерацію випадкових чисел, однак вони можуть допомогти нам, і ми в цьому переконаємося.
Якщо ви не чули про CSS змінні, не лякайтеся. За фактом, це рідні змінні, вбудовані в CSS, проте вони відрізняються від тих змінних, які ви знаєте в препроцессорах типу Sass і Less. Кріс навів багато переваг:
їх можна використовувати без препроцесора;
вони розподіляються. Щоб переписати поточне значення або задати його, можна створити змінну всередині будь-якого селектора;
при зміні значення (наприклад, через медіа запити або інші стани), браузер перемальовує елемент;
CSS змінними можна маніпулювати через JS.
Нам дуже важливий останній пункт. Ми будемо генерувати випадкове число в JS і переміщати його в CSS за допомогою користувацьких властивостей.
Задайте CSS змінну зі значенням за замовчуванням (зручно, якщо JS раптово не спрацює):
/* час переходу за замовчуванням */
:root {
–animation-time: 2s;
}
Тепер цю змінну можна використовувати в нашому CSS:
#red {
animation: flicker var(–animation-time) ease alternate infinite;
}
Ми прийшли рівно до того, з чого почали. Це демо візуально нічим не відрізняється від попереднього, однак у цей раз у SVG анімації використовуються CSS змінні. Перевірити, що все працює, можна, змінивши значення змінної в CSS. Анімація повинна оновитися.
Все готово для пошуку і маніпулювання користувальницьким властивістю через JS.
var time = Math.random();
Звідси ми можемо знайти червоний круг в SVG і змінити CSS змінну —animation-time за допомогою методу setProperty:
var red = document.querySelector(‘#red’);
red.style.setProperty(‘–animation-time’, time +’s’);
І от і все! Випадково згенероване число в CSS, використовуване в SVG анімації:
Вже краще, генерується випадкове число при запуску JS, тому воно завжди різне. Це майже те, що ми хотіли, але давайте ще трохи ускладнимо завдання: будемо періодично випадково animation-duration під час роботи.
На щастя, ми працюємо з JS, ми можемо оновлювати власну властивість, коли захочемо. Приклад з оновленням animation-duration кожну секунду:
var red = document.querySelector(‘#red’);
function setProperty(duration) {
red.style.setProperty(‘–animation-time’, duration +’s’);
}
function changeAnimationTime() {
var animationDuration = Math.random();
setProperty(animationDuration);
}
setInterval(changeAnimationTime, 1000);
Саме цього я і хотів домогтися:
Важливо знати, що підтримка CSS змінних (споживчих властивостей) все ще неоднорідна. До цієї анімації можна було застосувати техніку прогресивного поліпшення:
#red {
animation: flicker .5s ease alternate infinite;
animation: flicker var(–animation-time) ease alternate infinite;
}
Якщо підтримка CSS змінних відсутній, ми побачимо хоч якусь анімацію, нехай і не точно таку ж.
Потрібно сказати, що випадково animation-duration можна не тільки з допомогою CSS змінних. Можна також отримувати DOM елемент через JS і безпосередньо вставляти випадкове значення у style:
var red = document.querySelector(‘#red’);
red.style.animationDuration = Math.floor(Math.random() * 5 + 1) + “s”;
Можна навіть чекати, коли закінчиться анімація, і ставити нове значення тривалості:
var red = document.querySelector(‘#red’);
function setRandomAnimationDuration() {
red.style.animationDuration = Math.floor(Math.random() * 10 + 1) + “s”;
}
red.addEventListener. (“animationiteration”, setRandomAnimationDuration);
Покажу ще один спосіб. Можна генерувати випадкові числа з допомогою EQCSS.
@element ‘#animation’ {
.element {
animation-duration: eval(‘rand’)s;
}
}
var rand = Math.random();
EQCSS.apply();
А ви хочете, щоб генерація випадкових чисел була доступна прямо в CSS? Не впевнений, що на цю тему ведуться хоч якісь обговорення. Навіть якщо вони і були, нам доведеться почекати, перш ніж використовувати метод. Філіп Уолтон нещодавно писав про те, як складно написати хороший полифил для генерації випадкових чисел в CSS. Набагато простіше це робити в JS!