CSS-анимации для ротации изображений

CSS-анимации для ротации изображений

В процессе экспериментов с анимированными SVG-масками, мне пришлось как следует разобраться с алгоритмами CSS-анимаций.

Например, в этом демо используется две анимации: одна для маски, вторая — для смены изображений. Сейчас речь пойдет о второй (и её вариантах).

Такая анимация нужна, чтобы последовательно показывать и скрывать картинки, в то время, когда эффект их появления обеспечивается другой анимацией.

При использовании HTML-элементов это можно было бы сделать одной анимацией, но при использовании SVG-масок для всех элементов ротации используется одна маска, и ей нельзя задать задержку воспроизведения в зависимости от позиции элемента, к которому она применилась. Есть два решения: создавать для каждого шага по маске с нужной задержкой воспроизведения или просто скрывать элементы, которые не нужны в данный момент. Я выбрала второй вариант.

Мне не хотелось использовать JS, потому что простую анимацию можно сделать средствами CSS. Кроме того, использование переменных в SCSS позволяет легко синхронизировать между собой анимации масок и смены изображений.

Итак, первый вариант анимации.

Задача: сделать алгоритм последовательной смены произвольного количества изображений. Одно изображение должно сменять другое без плавных переходов. В один момент времени показывается одна картинка.

Вот как это должно работать:

Делаем разметку галереи:

В демо я добавила картинки фоном, но внутри элементов галереи может быть любое содержимое. Для демонстрации SVG-масок структура галереи переносится, соответственно, в SVG.

Теперь самое интересное: анимация. Создаем конфиг:

Нужно понимать как работает последний параметр. Для всех элементов задается одна и та же анимация: картинка показывается на короткий промежуток времени, и затем скрывается. Переменная $step-perc используется в коде анимации, и определяет как долго будет отображаться каждая картинка:

Например, в галерее из четырех элементов каждая картинка будет показываться 25% времени, а в остальное время будет скрыта.

Задаем анимацию элементам галереи:

Элементы исчезают и появляются одновременно, нужно добавить каждому из них задержку воспроизведения:

Первому элементу задержка не нужна, для остальных рассчитываем задержку, умножая длительность одного шага на позицию элемента минус 1. То есть второй элемент начнет воспроизводиться на шаг позже, третий — на два шага позже, и так далее.

Очевидно, что animation-delay будет удобнее рассчитывать в цикле:

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

Вот что получается в итоге:

Можно отредактировать заготовку, сделав простую ротацию:

А можно добавить спецэффектов с помощью анимированных SVG-масок, например:

Для этого демо структура галереи была перенесена в SVG.

Второй вариант анимации.

Задача: картинки появляются по очереди от нижних слоев к верхним, при этом одновременно видны две картинки: текущая и предыдущая под ней, это позволит используя маски сделать "перетекание" из одной картинки в другую.

Как это должно работать:

Анимация делается по тем же принципам, что и предыдущая, но имеет свои особенности.

Во-первых, под самым первым слоем тоже должно что-то быть, для этого немного меняем разметку и добавляем "дно":

Оно не участвует в ротации, а просто всегда там лежит. Изображение в этом слое должно быть таким же как в последнем слое, это позволит зациклить анимацию.

Во-вторых, чтобы каждый слой успевал послужить подложкой для следующего, удлиняем время показа каждого слоя, теперь оно равно двум шагам:

В течение первого шага слой появляется сам, а в течение второго служит фоном для следующего слоя.

Во-третьих, самому верхнему слою потребуется своя отдельная анимация.

Как уже говорилось выше, в этом варианте анимации каждый слой показывается по времени два шага.

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

Делаем переменную с половинной длительностью анимации:

Дублируем анимацию с новой длительностью:

Переопределяем анимацию для последнего шага:

Визуально результат практически не отличается от предыдущего варианта:

Но если к элементам галереи применить SVG-маски, получается интересное:

Синхронизация слоёных анимаций не самая простая задача, но результат того стоит.

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

📎📎📎📎📎📎📎📎📎📎