От автора: мы хотели рандомизировать радиус окружности. Это можно было бы подделать с помощью CSS, но давайте создадим по-настоящему псевдо случайные числа с помощью JS.
Мы говорим о SVG, вот наш базовый круг:
1 2 3 |
<svg viewBox="0 0 100 100"> <circle id="circle" cx="50" cy="50" r="50" /> </svg> |
Небольшая JS функция для генерации случайного целого числа в диапазоне:
1 2 3 |
function getRandomInt(min, max) { return Math.floor(Math.random() * (max - min + 1) + min); } |
Для рандомизации радиуса каждую секунду можно сделать:
1 2 3 4 |
var circle = document.querySelector("#circle"); setInterval(function() { circle.setAttribute("r", getRandomInt(5, 50)); }, 1000); |
Для красоты можно добавить плавный переход к новому размеру в браузеры с поддержкой:
1 2 3 |
circle { transition: r 0.2s; } |
См. демо
Все SVG формы построены из чисел, т.е. они поддаются рандомизации. Представьте форму с гранями, выстроенными в случайном порядке:
Скорее всего, это <polygon> (прямые линии), но такую форму также легко можно нарисовать с помощью <path>, а путь уже поддается плавной анимации (в Chrome). Давайте создадим эту форму, вот так может выглядеть путь:
1 |
<path d="M-4,-4 L1004,-4 L1004,100 L940,161 L617,186 L555,122 L306,179 L17,177 L-4,100 L-4,-4 Z"></path> |
Некоторые точки фиксированные, остальные случайные. Диаграмма:
Наша задача – сгенерировать эти случайные числа, собрать их в строку и заменить эту строку в DOM (атрибут d в теге <path>).
Напомним, у нас уже есть функция генерации случайных чисел getRandomInt(). Упрощенная концепция:
1 2 3 4 5 |
var a = getRandomInt(1, 100); var b = getRandomInt(1, 100); var c = getRandomInt(1, 100); var newString = `${a} ${b} ${c}`; |
Сложность состоит в том, чтобы сгенерировать и расположить их в формате, удовлетворяющем синтаксису path. Сделать это несложно, просто нужно сгенерировать много чисел. Покажу сразу весь код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
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 (просто мгновенная смена формы) производительность будет хорошая в любом браузере.
Автор: Chris Coyier
Источник: //mediatemple.net/
Редакция: Команда webformyself.