Как стать автором
Обновить

Реализуем интересный эффект с помощью Anime.js

Время на прочтение3 мин
Количество просмотров6.8K


Доброго времени суток, друзья!

В этой статье, как следует из названия, мы займемся реализацией одного занимательного эффекта с использованием одной любопытной библиотеки (anime.js). Я не буду петь дифирамбы этой библиотеке, но тем, кто плотно занимается анимацией, определенно стоит обратить на нее внимание. Простой интерфейс + отличная документация, что еще нужно для творчества?

По материалам этой замечательной статьи.

Автор указанной статьи назвал свой эффект «Анимация следа из частиц» (Particle Trail Animation).



Мы возьмем код из статьи, подробно разберем его и немного улучшим.

Во-первых, сделаем частицы разноцветными. Потому что один цвет — это скучно.

Во-вторых, анимация будет запускаться по клику. Потому что бесконечная анимация раздражает.

В-третьих, привяжем центр анимации (спирали) к месту клика. Потому что пользовательский опыт прежде всего.

Мы не будем использовать холст (canvas). Анимироваться будет множество маленьких блоков (div).

Итак, поехали (как сказал Гагарин, отправляясь в космос).

Из чего состоит наш HTML? В нем мы подключаем библиотеку, наш скрипт и, собственно, все.

Стили также сложно назвать впечатляющими:

body {
    margin: 0;
    background: #333;
    overflow: hidden;
}

/* это частицы */
.dot {
    position: absolute;
    /* они круглые */
    border-radius: 50%;
}

Даешь JavaScript! As you wish.

Оборачиваем весь наш код в обработчик события «клик» объекта Window:

window.addEventListener('click', event => {  ... })

Создаем контейнер для частиц с классом «box»:

let box = document.createElement('div')
box.classList.add('box')
document.body.appendChild(box)

Определяем некоторые значения (не магические числа, don't worry, be happy):

// количество частиц для одного угла
let n = 10

// количество поворотов угла
// это количество определяет размер спирали
let a = 20

// количество углов
// это количество определяет количество витков спирали
let l = 110

Генерируем частицы с помощью двух циклов for:

for (let i = 0; i <= l; i++) {
    // меняем угол
    let angle = 0.1 * i

    // делаем место клика центром спирали
    let x = (a * angle) * Math.cos(angle) + event.clientX
    let y = (a * angle) * Math.sin(angle) + event.clientY

    // создаем n частиц для каждого угла
    for (let j = 0; j < n; j++) {
        // создаем частицу с классом "dot"
        let dot = document.createElement('div')
        dot.classList.add('dot')
        box.appendChild(dot)

        // определяем размер частицы с помощью метода "anime.random()"
        // позволяющего получать произвольные значения
        // в заданном диапазоне
        let size = anime.random(5, 10)

        // стилизуем частицу
        // добавляем атрибут "style"
        dot.setAttribute('style',
        // с помощью шаблонного (строкового) литерала определяем
        //ширину и высоту
        `width: ${size}px; height: ${size}px;

        // положение с помощью anime.random()
        top: ${y + anime.random(-15, 15)}px; left: ${x + anime.random(-15, 15)}px;

        // делаем частицу полностью прозрачной по умолчанию
        opacity: 0;

        // цвет фона с помощью функции получения произвольного цвета
        background: #${ функция получения произвольного цвета }`)
    }
}

Функция получения произвольного цвета может выглядеть так:

function getRandomColor() {
    let letters = '0123456789abcdef',
        color = '#'
    for (let i = 0; i < 6; i++) {
        color += letters[Math.trunc(Math.random() * 16)]
    }
    return color
}

Но мы не ищем легких путей, поэтому она будет выглядеть так:

(Math.random()*0xffffff<<0).toString(16)

Здесь используется побитовый сдвиг влево и приведение к шестнадцатиричной строке.

Далее созданные нами частицы анимируются с помощью «anime»:

anime({
    // цель анимации
    targets: document.querySelectorAll('.dot'),
    // повторение
    loop: false,
    // временная функция анимации
    // в нашем случае линейная (равномерная)
    easing: 'linear',

    // объекты анимации
    // прозрачность
    // эффект проявления и затухания
    opacity: [
        {
            value: 1,
            // продолжительность
            duration: 50,
            // задержка
            delay: anime.stagger(2)
        },
        {
            value: 0,
            duration: 1200
        }
    ],

    // эффект расширения (роста)
    // ширина
    width: {
        value: 2,
        duration: 500,
        delay: anime.stagger(2)
    },
    // высота
    height: {
        value: 2,
        duration: 500,
        delay: anime.stagger(2)
    },

    // дополнительный разброс
    // смещение по оси х
    translateX: {
        value: () => anime.random(-30, 30),
        duration: 1500,
        delay: anime.stagger(2)
    },
    // смещение по оси y
    translateY: {
        value: () => anime.random(-30, 30),
        duration: 1500,
        delay: anime.stagger(2)
    }
})

Last, but not least, добавляем в начало проверку наличия box:

if (document.querySelector(".box")) {
    document.body.removeChild(document.querySelector(".box"));
  }


Результат:


Код на GitHub.

That's all, folks! Благодарю за внимание.
Теги:
Хабы:
Всего голосов 7: ↑5 и ↓2+3
Комментарии2

Публикации

Истории

Работа

Ближайшие события

One day offer от ВСК
Дата16 – 17 мая
Время09:00 – 18:00
Место
Онлайн
Конференция «Я.Железо»
Дата18 мая
Время14:00 – 23:59
Место
МоскваОнлайн
Антиконференция X5 Future Night
Дата30 мая
Время11:00 – 23:00
Место
Онлайн
Конференция «IT IS CONF 2024»
Дата20 июня
Время09:00 – 19:00
Место
Екатеринбург
Summer Merge
Дата28 – 30 июня
Время11:00
Место
Ульяновская область