Эта статья — перевод оригинальной статьи "Text Replace Transitions"
Также я веду телеграм канал “Frontend по-флотски”, где рассказываю про интересные вещи из мира разработки интерфейсов.
Вступление
Начнём с хорошего, финальная демка, как будто вы прочитали всё до конца.
https://codepen.io/argyleink/pen/KKBWwMr
Если вы видите ошибку поддержки, вот запись его работы в Chrome Canary (с включенным этим флагом ????.
tldr;
view-transition
позволяет мне с помощью CSS описать, как убрать старое текстовое состояние и показать новое текстовое состояние.
Вдохновение
Идея этой демонстрации пришла из игры Session Skate. В начальных титрах «SESSION» каждая буква быстро исчезает. Это выглядело довольно круто, и я сразу понял, что могу сделать это с помощью view-transition
, setInterval()
и .textContent
. Итак, я завёл себе задачу в todo, чтобы сделать это, потому что пришло время заняться фигнёй, а не работой.
Это превратилось в небольшой прототип. Взгляните на эти баребоны!
setInterval(() => {
document.startViewTransition(() => {
h1.textContent = word[index++]
if (index >= word.length) index = 0
})
}, 500)
Каждые полсекунды.
Сделай снепшот предыдущего состояния.
Задай новый текст.
Когда работа завершается в коллбэке функции startViewTransition
, браузер бесплатно интерполирует изменения для вас. В нашем случае была "V", теперь "i". Одна буква исчезла, одна буква появилась. Получаем кроссфейд!
https://codepen.io/argyleink/pen/BaPWpmQ
Оно. Мы сделали как в игре.
Настройка перехода
Кроссфейды — это круто (и вы все тоже), но что, если я захочу настроить, как будет меняться текст? Возможно, с чем-то типо Open Props?
Не проблема ????????
Во-первых, сделаем импорт easings и animation:
@import "https://unpkg.com/open-props/easings.min.css";
@import "https://unpkg.com/open-props/animations.min.css";
Затем, в качестве оптимизации, скажите всей странице расслабиться и не переходить, когда запрашивается снепшот перехода.
html {
view-transition-name: none;
}
Теперь, когда мы сказали, что мы не хотим переходить, давайте уточним, что следует делать, h1!
h1 {
/* be stable. fix that width. */
inline-size: 1em;
/* required for view-transitions
now it's not the whole page */
contain: layout;
/* yo browser; transition this! */
view-transition-name: replace-effect;
}
Запомните что view-transition-name
может ссылаться на своё состояния до и после в следующем этапе.
Теперь самое приятное
Используйте некоторые из этих пропсов, чтобы организовать появление и исчезновение буквы/снепшотов DOM. Начнем с того, как должна выйти предыдущая букву; давайте посмотрим, я хочу, чтобы она масштабировалась, например, от меня, и исчезала в то же время.
@media (prefers-reduced-motion: no-preference) {
html::view-transition-old(replace-effect) {
animation:
var(--animation-fade-out),
var(--animation-scale-down);
}
}
Восхитительная магия
Теперь для появления элемента; затемните его, сдвинув вверх!
@media (prefers-reduced-motion: no-preference) {
html::view-transition-new(replace-effect) {
z-index: 1;
animation:
var(--animation-fade-out) reverse,
var(--animation-slide-in-up);
}
}
анимация затухания инвертируется, поэтому непрозрачность не нужно устанавливать на 0.
Меняйте и подбирайте пропсы для анимации в этом Codepen и получайте удовольствие ????
https://codepen.io/argyleink/pen/KKBWwMr
Заключение
Внесите изменения в DOM, скажите как анимировать изменения. Влюбитесь.
madmandarin
Выглядит круто, но почему
setInterval
а неrequestAnimationFrame?
devlev
Я так понимаю setInterval здесь используется только чтобы менять непосредственно сами отображаемые буквы. А то как они будут перерисованы определяют правила на css. requestAnimationFrame вызывается на каждый кадр отрисовки - соответственно буквы будут так быстро меняться что мы просто не увидем анимацию их смены.