Содержание
В предыдущей статье мы научились управлять элементами по клику, переключать состояния и менять содержимое. Всё это — предсказуемые реакции на предсказуемые действия. Теперь добавим случайность. С помощью Math.random() веб-плакат перестаёт быть одинаковым при каждом просмотре — элементы меняют позиции, цвета, размеры и порядок. Это то, что сближает формат с creative coding и делает каждое взаимодействие со страницей немного другим.
Math.random()
Всё начинается с одного метода. Math.random() возвращает случайное дробное число от 0 (включительно) до 1 (не включительно). Само по себе это число бесполезно, но из него строятся все остальные формулы.
Math.random() // 0.0 ... 0.999
Math.random() * 10 // 0.0 ... 9.999
Math.floor(Math.random() * 10) // 0, 1, 2 ... 9
/* Math.random() — дробное от 0 до 1 (не включая 1).
Умножаем на диапазон, Math.floor округляет вниз.
Это базовая формула для любой случайности. */
Три формулы, которые стоит запомнить.
Math.random() — дробное от 0 до 0.999. Полезно для прозрачности и пропорций.
Math.random() * N — дробное от 0 до N. Полезно для размеров и координат.
Math.floor(Math.random() * N) — целое от 0 до N−1. Полезно для индексов массива и дискретных значений.
Из этих трёх комбинаций строится вся случайность, которую мы будем использовать дальше.
Число в диапазоне от A до B: A + Math.random() * (B - A). Например, случайный размер от 20 до 80 пикселей: 20 + Math.random() * 60. Случайная прозрачность от 0.3 до 1: 0.3 + Math.random() * 0.7. Запомните эту формулу — она универсальна.
Случайный выбор из палитры
Самое частое применение рандома в веб-плакате — случайный цвет из заданной палитры. Вы определяете массив допустимых цветов и выбираете из него случайный элемент.
const colors = ['#fe3904','#9eff70','#82e1f1','#febbed','#3898e2']
box.addEventListener('click', () => {
const i = Math.floor(Math.random() * colors.length)
box.style.backgroundColor = colors[i]
box.style.borderRadius = Math.random() >0.5 ? '50%' : '8px'
box.style.transform = `scale(${0.8 + Math.random() * 0.5})`
})
/* Math.random() >0.5 — случайное условие,
монетка: true или false.
0.8 + Math.random() * 0.5 —
число в диапазоне от 0.8 до 1.3. */
Каждый клик задаёт квадрату случайный цвет, форму и масштаб. Обратите внимание на запись Math.random() >0.5 — это случайное условие, которое работает как бросок монетки: в половине случаев true, в половине false. Удобно для бинарных решений вроде «круг или квадрат».
Массив: список значений
Массив — это упорядоченный список значений, записанный в квадратных скобках. Каждый элемент имеет индекс, начиная с нуля. Свойство .length возвращает количество элементов. Формула Math.floor(Math.random() * arr.length) даёт случайный индекс, который гарантированно попадает в пределы массива.
const phrases = [
'Дизайн — это код',
'Ошибки — это прогресс',
'Браузер — это холст',
'CSS — это магия',
]
const i = Math.floor(Math.random() * phrases.length)
display.textContent = phrases[i]
/* Массив — список значений в [ ].
phrases.length — сколько элементов.
phrases[i] — элемент по индексу.
Формула Math.floor(Math.random() * arr.length)
даёт случайный индекс. Запомните её. */
Массив фраз, кнопка выбирает случайную и выводит на экран. Маленький штрих — opacity на мгновение сбрасывается до нуля и через setTimeout возвращается обратно, создавая лёгкий эффект смены. Массив можно заполнить чем угодно: цветами, координатами, URL-адресами, CSS-классами, HTML-тегами.
Случайное позиционирование
Когда вы умеете генерировать случайные числа, вы можете создавать элементы со случайными позициями, размерами и свойствами. Это уже ближе к тому, что в creative coding называется генеративной графикой.
.rand-dot {
position: absolute;
border-radius: 50%;
transition: all 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
}
/* transition делает перемешивание
анимированным — точки перелетают,
а не телепортируются. */
for (let i = 0; i < 12; i++) {
const dot = document.createElement('div')
const size = 10 + Math.random() * 30
dot.style.width = size + 'px'
dot.style.height = size + 'px'
dot.style.left = Math.random() * 90 + '%'
dot.style.top = Math.random() * 85 + '%'
root.appendChild(dot)
}
/* for создаёт 12 точек.
Каждая получает случайный размер (10–40px),
случайную позицию (в процентах от контейнера)
и случайный цвет из палитры. */
12 точек, каждая со случайным размером (10—40px), позицией и цветом из палитры. Клик перемешивает их — все точки перелетают на новые случайные позиции. CSS transition делает перемещение анимированным: точки не телепортируются, а плавно перелетают. Эта связка JS (вычислил новые координаты) + CSS (анимировал переход) — типичный паттерн для динамичных веб-плакатов.
Генерация элементов циклом
Следующий шаг — создавать элементы целиком через JavaScript, а не размечать их вручную в HTML. Цикл for позволяет создать десятки элементов с разными параметрами за несколько строк.
function generate() {
root.querySelectorAll('.gen-item').forEach(el => el.remove())
const count = 15 + Math.floor(Math.random() * 20)
for (let i = 0; i < count; i++) {
const el = document.createElement('div')
el.style.width = (10 + Math.random() * 60) + 'px'
el.style.height = (10 + Math.random() * 40) + 'px'
el.style.left = Math.random() * 95 + '%'
el.style.top = Math.random() * 85 + '%'
el.style.transform = `rotate(${Math.random() * 360}deg)`
root.appendChild(el)
}
}
/* Каждый вызов: удаляем старые, создаём новые.
Даже количество элементов случайное (15–35).
Размер, позиция, поворот — всё через Math.random().
Каждый клик — новая композиция. */
При каждом клике старые элементы удаляются remove(), и создаются новые — от 15 до 35 штук. Каждый со случайным размером, позицией, поворотом, цветом и прозрачностью. По сути, каждый клик создаёт новую абстрактную композицию. Именно так устроен плакат «Склянка» из нашей подборки — при каждой загрузке страница пересобирается.
document.createElement('div') создаёт элемент, но не добавляет его на страницу. Чтобы он стал видимым, нужно вставить его через root.appendChild(element). А чтобы удалить — element.remove(). Создание и удаление элементов на лету — это то, чего CSS не умеет и для чего нужен JavaScript.
Объект с набором свойств
Когда у случайного элемента много параметров (имя, цвет, размер, скорость), удобно описать их как объект — набор свойств с именами.
function makeCreature() {
return {
name: names[Math.floor(Math.random() * names.length)],
face: faces[Math.floor(Math.random() * faces.length)],
color: colors[Math.floor(Math.random() * colors.length)],
size: 40 + Math.floor(Math.random() * 40),
energy: Math.floor(Math.random() * 100)
}
}
/* Объект { } — набор свойств с именами.
Функция makeCreature() каждый раз
возвращает нового персонажа
со случайными параметрами.
Клик на каждом — перегенерация. */
Функция makeCreature() возвращает объект с пятью свойствами: имя, символ, цвет, размер и энергия. Каждое свойство выбирается случайно из своего массива или диапазона. Клик на любом существе пересоздаёт его с новыми параметрами.
Объект в JavaScript записывается в фигурных скобках: { name: 'Blob', color: '#fe3904', size: 60 }. Свойства читаются через точку: creature.name, creature.color. Это способ группировать связанные данные вместе, вместо того чтобы хранить их в отдельных переменных.
Перемешивание массива
Иногда нужно не выбрать один случайный элемент, а перемешать весь массив — изменить порядок элементов, как карты в колоде. Для этого существует алгоритм Фишера-Йейтса.
function shuffle(arr) {
const copy = [...arr]
for (let i = copy.length - 1; i >0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[copy[i], copy[j]] = [copy[j], copy[i]]
}
return copy
}
/* Алгоритм Фишера-Йейтса.
Проходим массив с конца, каждый элемент
меняем местами со случайным.
[...arr] — копия, чтобы не менять оригинал.
Результат — честное перемешивание. */
Шесть пронумерованных блоков. Кнопка перемешивает их порядок. Алгоритм проходит массив с конца и каждый элемент меняет местами со случайным из оставшихся. Запись [...arr] создаёт копию массива, чтобы не менять оригинал. Это важно, когда вам нужно перемешивать одни и те же данные многократно.
Собираем всё вместе
Финальный пример объединяет всё, что мы разобрали. Восемь фигур со случайными размерами, формами, позициями и прозрачностью. Клик перегенерирует всю композицию, а CSS transition анимирует переход — фигуры перелетают, морфятся и меняют цвет.
.comp-shape {
position: absolute;
transition: all 0.6s ease;
}
/* transition на фигурах — при перегенерации
они не телепортируются,
а плавно перелетают на новые места. */
function randomize() {
shapes.forEach(shape => {
const size = 20 + Math.random() * 120
const isCircle = Math.random() >0.4
shape.style.width = size + 'px'
shape.style.height = size + 'px'
shape.style.borderRadius = isCircle ? '50%' : '4px'
shape.style.left = Math.random() * 85 + '%'
shape.style.top = Math.random() * 75 + '%'
shape.style.opacity = (0.2 + Math.random() * 0.5).toFixed(2)
})
}
/* 8 фигур пересобираются при каждом клике.
Размер, форма, позиция, прозрачность —
всё случайное. CSS transition анимирует
переход между состояниями.
Каждый клик — новый плакат. */
Это, по сути, простейший генеративный плакат. Заголовок фиксирован, а фон каждый раз новый. Добавьте сюда setInterval — и композиция будет пересобираться автоматически каждые несколько секунд, без участия зрителя.
Случайность работает лучше всего в рамках ограничений. Пять цветов из палитры, а не бесконечный hsl(Math.random()*360, 70%, 50%). Размеры от 20 до 120 пикселей, а не от 1 до 1000. Чем уже диапазон случайности — тем целостнее результат. Полный хаос редко выглядит хорошо, а контролируемая случайность в заданных рамках создаёт живые и при этом гармоничные композиции.




