Рандомізація SVG форм

20

Від автора: ми хотіли випадково радіус кола. Це можна було б підробити з допомогою CSS, але давайте створимо по-справжньому псевдо випадкові числа з допомогою JS.

Ми говоримо про SVG, ось наш базовий коло:

Невелика JS функція для генерації випадкового цілого числа в діапазоні:

function getRandomInt(min, max) {
return Math.floor(Math.random() * (max — min + 1) + min);
}

Для рандомізації радіусу кожну секунду можна зробити:

var circle = document.querySelector(«#circle»);
setInterval(function() {
circle.setAttribute(«r», getRandomInt(5, 50));
}, 1000);

Для краси можна додати плавний перехід до нового розміру в браузер з підтримкою:

circle {
transition: r 0.2 s;
}

См. демо

Всі SVG форми побудовані з чисел, тобто вони піддаються рандомізації. Уявіть форму з гранями, збудованими у випадковому порядку:

Рандомизация SVG форм

Швидше за все, це (прямі лінії), але таку форму також легко можна намалювати за допомогою , а шлях вже піддається плавної анімації (Chrome). Давайте створимо цю форму, ось так може виглядати шлях:

Деякі фіксовані точки, інші випадкові. Діаграма:

Рандомизация SVG форм

Наше завдання – створити ці випадкові числа, зібрати їх в рядок і замінити цю рядок в DOM (атрибут d в тезі ).

Нагадаємо, у нас вже є функція генерації випадкових чисел getRandomInt(). Спрощена концепція:

var a = getRandomInt(1, 100);
var b = getRandomInt(1, 100);
var c = getRandomInt(1, 100);
var newString = `${a} ${b} ${c}`;

Складність полягає в тому, щоб згенерувати і розташувати їх в форматі, що задовольняє синтаксису path. Зробити це нескладно, просто потрібно згенерувати багато чисел. Покажу відразу весь код:

var csstricks = {
init: function() {
csstricks.randomizeBackgrounds();
},
generateRandomPoints: function(minSpread, maxSpread) {
let points = {};
points.a = `${getRandomInt(800, 1000)},${getRandomInt(minSpread, maxSpread)}`;
points.b = `${getRandomInt(600, 800)},${getRandomInt(minSpread, maxSpread)}`;
points.c = `${getRandomInt(400, 600)},${getRandomInt(minSpread, maxSpread)}`;
points.d = `${getRandomInt(200, 400)},${getRandomInt(minSpread, maxSpread)}`;
points.e = `${getRandomInt(0, 200)},${getRandomInt(minSpread, maxSpread)}`;
return points;
},
randomizeHeader: function() {
let newPoints = csstricks.generateRandomPoints(120, 190);
let downFacingPoints = `M-4,-4 L1004,-4 L1004,100 L${newPoints.a} L${newPoints.b} L${newPoints.c} L${newPoints.d} L${newPoints.e} L-4,100 L-4,-4 Z`;
$(«#jagged-top»).attr(«d», downFacingPoints);
},
randomizeBackgrounds: function() {
csstricks.randomizeHeader();
setInterval(function() {
csstricks.randomizeHeader();
}, 2000);
},
};
csstricks.init();
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max — min + 1) + min);
}

Для організації код розбито на декілька маленьких функцій. В кінцевій версії я також перейшов на більш продуктивну версію setInterval. Фінальне демо:

Можете подивитися шапку сайту CSS-Tricks від Chris Coyier (@chriscoyier) на CodePen.

Варто зазначити: SVG не має реального апаратного прискорення, яке є в деяких типах веб-графіки. Наприклад, якщо застосувати властивість transition до властивостей transform або opacity, вам не потрібно буде турбуватися про продуктивність, так як всі обчислення по можливості будуть передані на графічний процесор. SVG у цьому плані не пощастило, при зміні path не вийде задіяти графічний процесор. При перегляді демо Chrome можна спостерігати завантаження оперативної пам’яті і CPU через застосованого CSS властивості transition. Без transition (просто миттєва зміна форми) продуктивність буде добра у будь-якому браузері.