Podstawowe informacje o tworzeniu animacji podzielonych liter i słów.
W tym poście przedstawię sposoby rozwiązywania problemów z interakcjami i animacjami podzielonego tekstu w internecie, które są jak najmniejsze, dostępne i działają w różnych przeglądarkach. Zobacz prezentację.
Jeśli wolisz film, oto wersja tego posta na YouTube:
Przegląd
Animacje podzielonego tekstu mogą być niesamowite. W tym poście nie omówimy potencjału animacji, ale stanowi podstawę do budowania. Celem jest stopniowa animacja. Domyślnie tekst powinien być czytelny, a animacja umieszczona na jego górze. Efekty ruchu podzielonego tekstu mogą być ekstrawaganckie i potencjalnie uciążliwe, dlatego będziemy modyfikować kod HTML lub stosować style ruchu tylko wtedy, gdy użytkownik zgadza się na ruch.
Poniżej znajdziesz ogólny opis przepływu pracy i wyników:
- Przygotuj zmienne warunkowe zmniejszonego ruchu dla CSS i JS.
- Przygotuj narzędzia do podziału tekstu w języku JavaScript.
- Uporządkuj warunki i narzędzia podczas wczytywania strony.
- Twórz przejścia i animacje CSS dla liter i słów (część rad).
Oto podgląd wyników warunkowych:
Jeśli użytkownik woli ruch z ograniczonym ruchem, pozostawiamy dokument HTML bez zmian i nie stosujemy animacji. Jeśli ruch jest w porządku, tniemy obraz na kawałki. Oto podgląd kodu HTML po tym, jak JavaScript podzieli tekst według liter.
Przygotowywanie warunków dotyczących ruchu
W tym projekcie używane będzie dostępne zapytanie o media @media
(prefers-reduced-motion: reduce)
z zasobów CSS i JavaScript. To zapytanie o media to nasz główny warunek
decyzji o rozdzieleniu tekstu. Zapytanie o media CSS będzie używane do pomijania przejść i animacji, a zapytanie o media JavaScript – do pominięcia manipulacji HTML.
Przygotowywanie warunku CSS
Udało mi się użyć narzędzia PostCSS, aby włączyć składnię zapytań o multimedia na poziomie 5, w której mogę zapisać wartość logiczną zapytania o media w zmiennej:
@custom-media --motionOK (prefers-reduced-motion: no-preference);
Przygotowywanie warunku JS
W kodzie JavaScript przeglądarka umożliwia sprawdzanie zapytań o multimedia. Za pomocą zniszczenia wyodrębniłam wynik logiczny z testu zapytania o multimedia i zmieniłam jego nazwę:
const {matches:motionOK} = window.matchMedia(
'(prefers-reduced-motion: no-preference)'
)
Mogę następnie przetestować działanie funkcji motionOK
i zmienić dokument tylko wtedy, gdy użytkownik nie poprosił o zmniejszenie ruchu.
if (motionOK) {
// document split manipulations
}
Mogę sprawdzić tę samą wartość za pomocą PostCSS i włączyć składnię @nest
w Nesting Draft 1. Dzięki temu mogę w jednym miejscu przechowywać wszystkie logiki animacji i wymagania dotyczące jej stylu w odniesieniu do elementów nadrzędnych i podrzędnych:
letter-animation {
@media (--motionOK) {
/* animation styles */
}
}
Używając niestandardowej właściwości PostCSS i wartości logicznej JavaScript, możemy warunkowo uaktualnić efekt. Teraz przechodzimy do kolejnej sekcji, w której omawiam kod JavaScriptu służący do przekształcania ciągów znaków w elementy.
Dzielenie tekstu
Litery tekstowe, słowa, wiersze itp. nie mogą być animowane oddzielnie za pomocą CSS lub JS. Aby uzyskać ten efekt, potrzebne są pudełka. Jeśli chcemy animować każdą literę, każda z nich musi być elementem. Jeśli chcemy animować każde słowo, każde słowo musi być elementem.
- Utwórz funkcje narzędziowe JavaScript do dzielenia ciągów znaków na elementy
- Administrowanie korzystaniem z tych narzędzi
Funkcja podziału liter
Najlepiej zacząć od funkcji, która pobiera ciąg znaków i zwraca każdą literę w tablicy.
export const byLetter = text =>
[...text].map(span)
Rozpowszechnianie treści z ES6 bardzo pomogło sprawnie wykonać to zadanie.
Funkcja dzielenia słów
Podobnie jak w przypadku dzielenia liter, funkcja ta pobiera ciąg znaków i zwraca każde słowo w tablicy.
export const byWord = text =>
text.split(' ').map(span)
Metoda split()
w ciągach tekstowych JavaScript pozwala nam określać, które znaki zostaną wycięte.
Podana przeze mnie pusta spacja oznacza rozdzielenie słów.
Funkcja tworzenia pól wyboru
W efekcie każda litera musi mieć ramkę. W tych funkcjach widzimy, że funkcja map()
jest wywoływana za pomocą funkcji span()
. Oto funkcja span()
.
const span = (text, index) => {
const node = document.createElement('span')
node.textContent = text
node.style.setProperty('--index', index)
return node
}
Pamiętaj, że właściwość niestandardowa o nazwie --index
jest ustawiana na podstawie pozycji tablicy. Choć pola z animacjami liter są przydatne, ale dodanie indeksu do użycia w CSS to pozornie mały dodatek o dużym wpływie.
Najbardziej charakterystyczne w przypadku tych efektów jest oszałamiające.
Będziemy mogli użyć atrybutu --index
jako sposobu kompensowania animacji i zwiększenia jej rozłożenia.
Wnioski dotyczące narzędzi
Ukończony moduł splitting.js
:
const span = (text, index) => {
const node = document.createElement('span')
node.textContent = text
node.style.setProperty('--index', index)
return node
}
export const byLetter = text =>
[...text].map(span)
export const byWord = text =>
text.split(' ').map(span)
Następnym krokiem jest importowanie i używanie tych funkcji byLetter()
i byWord()
.
Podział administracji
Gdy narzędzia do podziału są gotowe do użycia, połączenie wszystkich elementów w jedną całość oznacza:
- Znajdowanie elementów do podziału.
- Dzielenie ich i zastępowanie ich tekstem HTML.
Następnie kod CSS przejmuje elementy / pola i uruchamia ich animację.
Znajdowanie elementów
Do przechowywania informacji o pożądanej animacji
i sposobu podziału tekstu używam atrybutów i wartości. Podobało mi się umieszczanie
tych deklaratywnej opcji w kodzie HTML. Atrybut split-by
jest używany z JavaScriptu do znajdowania elementów i tworzenia pól z literami lub słowami. Atrybut letter-animation
lub word-animation
jest używany z CSS do kierowania elementów podrzędnych oraz stosowania przekształceń i animacji.
Oto przykładowy kod HTML, który przedstawia te 2 atrybuty:
<h1 split-by="letter" letter-animation="breath">animated letters</h1>
<h1 split-by="word" word-animation="trampoline">hover the words</h1>
Znajdowanie elementów z JavaScriptu
Użyłem składni selektora arkusza CSS do określania obecności atrybutu, aby zebrać listę elementów, w których ma zostać podzielony tekst:
const splitTargets = document.querySelectorAll('[split-by]')
Znajdowanie elementów z CSS
Użyłem też selektora obecności atrybutu w CSS, aby nadać wszystkim animacji liter ten sam styl podstawowy. Później użyjemy wartości atrybutu, by dodać bardziej szczegółowe style w celu osiągnięcia odpowiedniego efektu.
letter-animation {
@media (--motionOK) {
/* animation styles */
}
}
Dzielę tekst w odpowiednim miejscu
W przypadku każdego podzielonego elementu docelowego zapisanego w kodzie JavaScript podzielimy ich tekst na podstawie wartości atrybutu i zmapujemy każdy ciąg na element <span>
. Możemy wtedy zastąpić tekst utworzonymi polami:
splitTargets.forEach(node => {
const type = node.getAttribute('split-by')
let nodes = null
if (type === 'letter') {
nodes = byLetter(node.innerText)
}
else if (type === 'word') {
nodes = byWord(node.innerText)
}
if (nodes) {
node.firstChild.replaceWith(...nodes)
}
})
Podsumowanie konfiguracji
Ukończono index.js
:
import {byLetter, byWord} from './splitting.js'
const {matches:motionOK} = window.matchMedia(
'(prefers-reduced-motion: no-preference)'
)
if (motionOK) {
const splitTargets = document.querySelectorAll('[split-by]')
splitTargets.forEach(node => {
const type = node.getAttribute('split-by')
let nodes = null
if (type === 'letter')
nodes = byLetter(node.innerText)
else if (type === 'word')
nodes = byWord(node.innerText)
if (nodes)
node.firstChild.replaceWith(...nodes)
})
}
Kod JavaScript można odczytać w tym języku:
- Zaimportuj niektóre pomocnicze funkcje narzędziowe.
- Sprawdź, czy ruch jest odpowiedni dla tego użytkownika. Jeśli nie, nic nie rób.
- Dla każdego elementu, który chcesz podzielić.
- Podziel je w zależności od tego, jak chcesz je podzielić.
- Zastąp tekst elementami.
Dzielenie animacji i przejść
W ten sposób udało Ci się wydobyć mnóstwo potencjalnych animacji i efektów za pomocą CSS lub JavaScriptu. Na końcu tego artykułu znajdziesz kilka linków, które pomogą Ci w podjęciu decyzji.
Czas pokazać, na co Cię stać. Udostępnię 4 animacje i przejścia oparte na CSS. 🤓
Podziel litery
Jako podstawę do stosowania efektów podziału liter przydatny był poniższy arkusz CSS. Wszystkie przejścia i animacje umieszczam za zapytaniem o media ruchu, a każdą nową literę podrzędną span
nadaję właściwości wyświetlania i stylu, co oznacza, że odstępy mają być używane:
[letter-animation] > span {
display: inline-block;
white-space: break-spaces;
}
Styl spacji jest ważny, by rozpiętości, które są tylko spacjami, nie zostały zwinięte przez mechanizm układu. Przejdźmy do stanowych fajnych rzeczy.
Przykład podziału liter w punkcie przejścia
W tym przykładzie zastosowano przejścia CSS do efektu podzielonego tekstu. W przypadku przejść musimy określić, czy silnik będzie animował się między nimi. Wybrałem 3 stany: bez najechania kursorem, najedź kursorem w zdaniu, na literę.
Gdy użytkownik najedzie kursorem na zdanie (czyli kontener), odskaluję wszystkie elementy podrzędne tak, jakby użytkownik je odsunął. Następnie, gdy użytkownik najeżdża na literę, wyświetlam ją dalej.
@media (--motionOK) {
[letter-animation="hover"] {
&:hover > span {
transform: scale(.75);
}
& > span {
transition: transform .3s ease;
cursor: pointer;
&:hover {
transform: scale(1.25);
}
}
}
}
Animuj przykład rozdzielonych liter
W tym przykładzie użyto wstępnie zdefiniowanej animacji @keyframe
, aby każdą literę animować w nieskończoność, oraz wykorzystano wbudowany indeks właściwości niestandardowych do utworzenia efektu przesunięcia.
@media (--motionOK) {
[letter-animation="breath"] > span {
animation:
breath 1200ms ease
calc(var(--index) * 100 * 1ms)
infinite alternate;
}
}
@keyframes breath {
from {
animation-timing-function: ease-out;
}
to {
transform: translateY(-5px) scale(1.25);
text-shadow: 0 0 25px var(--glow-color);
animation-timing-function: ease-in-out;
}
}
Podziel słowa
W tych przykładach jako typ kontenera sprawdził się Flexbox, wykorzystując jednostkę ch
jako typ kontenera o odpowiedniej długości.
word-animation {
display: inline-flex;
flex-wrap: wrap;
gap: 1ch;
}
Przykład dzielenia słów przejścia
W tym przykładzie przejścia ponownie użyję najechania kursorem. Efekt początkowo ukrywa treść do momentu najechania, więc upewniłem się, że interakcja i style są stosowane tylko wtedy, gdy urządzenie umożliwia najechanie kursorem.
@media (hover) {
[word-animation="hover"] {
overflow: hidden;
overflow: clip;
& > span {
transition: transform .3s ease;
cursor: pointer;
&:not(:hover) {
transform: translateY(50%);
}
}
}
}
Animacja przedstawiająca przykład dzielenia słów
W tym przykładzie animacji ponownie używam CSS @keyframes
, aby utworzyć nieskończoną animację w zwykłym akapicie tekstu.
[word-animation="trampoline"] > span {
display: inline-block;
transform: translateY(100%);
animation:
trampoline 3s ease
calc(var(--index) * 150 * 1ms)
infinite alternate;
}
@keyframes trampoline {
0% {
transform: translateY(100%);
animation-timing-function: ease-out;
}
50% {
transform: translateY(0);
animation-timing-function: ease-in;
}
}
Podsumowanie
Skoro już wiesz, jak to udało mi się osiągnąć, to jak? 🙂
Stwórzmy różne metody i nauczmy się wszystkiego, jak rozwijać się w internecie. Utwórz program Codepen lub udostępnij własną prezentację i prześlij mi go na tweeta, a dodam ją do sekcji remiksów ze społeczności poniżej.
Źródło
Więcej prezentacji i inspiracji
Remiksy społeczności
- Komponent internetowy
<text-hover>
autorstwa gnehcwu w środowisku CodeSandbox