Иконки приложений на нашей главной странице, которые можно бросать
На нашей главной странице есть рамка с иконками наших приложений. Когда вы открываете страницу, они падают вниз, а потом их можно взять и бросить. Если нажать на иконку, не перетаскивая её, откроется страница этого приложения. Работа заняла один день, и некоторые детали оказались интереснее, чем мы ожидали.
Почему рамка
Сначала мы хотели, чтобы иконки летали по всей верхней части страницы. Но там находятся заголовок и кнопки, а иконка, упавшая на «Start a project», — слишком высокая цена за небольшую забаву. Рамка рядом с вводным блоком и подписью на краю удерживает игру в границах. Она также заполнила пустое место, которое там и так было: справа от вводного текста и кнопок на широком экране. На телефонах рамка расположена под кнопками.
Настоящая физика на Matter.js
Круги, сталкивающиеся друг с другом, легко написать самому. Но иконки приложений — это квадраты со скруглёнными углами, а квадрат, который катится как монета, сразу выглядит неправильно. Чтобы иконки красиво кувыркались и ложились друг на друга, нужен настоящий физический движок, поэтому мы взяли Matter.js. Каждая иконка — это прямоугольник со скруглёнными углами (chamfer), радиус которых равен 22% стороны иконки; все они находятся внутри четырёх неподвижных стен.
Движок весит 83 КБ, поэтому он загружается только на главной странице, только после того как страница уже открылась и только если посетитель не включил в системе уменьшение анимации.
Элементы DOM, а не canvas
Matter.js умеет рисовать на canvas, но мы используем его только для расчётов. Иконки — это обычные ссылки с изображениями, положение которых обновляется в каждом кадре через CSS transform:
st.setProperty("--x", (b.position.x - size / 2) + "px");
st.setProperty("--y", (b.position.y - size / 2) + "px");
st.setProperty("--a", b.angle + "rad");
Поэтому нажатие по иконке — это настоящий переход по ссылке, изображения остаются чёткими при любом масштабе, а рамка и стиль иконок такие же, как и везде на сайте.
Тень, которая остаётся на месте
В нашем стиле у всех элементов жёсткая тень, смещённая вниз и вправо. Если задать её элементу, который вращается, тень будет вращаться вместе с ним, и у крутящейся иконки она станет раскачиваться, как стрелка часов. Решение — в каждом кадре поворачивать смещение тени в обратную сторону:
// keep the shadow at (3px, 3px) in screen space while the icon turns by a
st.setProperty("--shadow-x", 3 * (Math.cos(a) + Math.sin(a)) + "px");
st.setProperty("--shadow-y", 3 * (Math.cos(a) - Math.sin(a)) + "px");
Захват и бросок
При нажатии мы прикрепляем пружину (ограничение, constraint, в Matter.js) между указателем и той точкой иконки, за которую вы её взяли, а не её центром. Поэтому, если держать иконку за угол, она естественно раскачивается. Когда вы отпускаете её, она сохраняет скорость, но с ограничением, чтобы резкий бросок не отправил её сквозь стену. Если указатель сдвинулся меньше чем на шесть пикселей, это считается нажатием, и ссылка открывается.
Пока иконки падают сверху, верх рамки открыт, а когда все они оказываются внутри, он закрывается, чтобы ни одна иконка не вылетела наружу при броске.
Мелочи
- Сильное падение пускает рябь по точечному фону страницы.
- Когда всё неподвижно, симуляция засыпает, а когда рамка не видна на экране, ставится на паузу, поэтому во время чтения она не расходует ресурсы.
- Иконки начинают падать только тогда, когда рамка появляется на экране. На телефоне это происходит, когда вы прокручиваете страницу до неё.
- Без JavaScript или при включённом уменьшении анимации иконки спокойно лежат аккуратной кучкой, и по ним по-прежнему можно перейти как по ссылкам.
Это мелочь, но она рассказывает о наших приложениях больше, чем любая фраза. Если вам нужно что-то подобное для вашего сайта, напишите нам.
Читайте также: Что потребовалось, чтобы подготовить наши сайты для ИИ-агентов или WordPress 7.2 выходит 8 декабря: что мы проверяем в наших плагинах.