Podstawowe omówienie tworzenia animacji liter i słów.
W tym poście chcę podzielić się z Wami sposobami na tworzenie animowanych tekstów i interakcji w internecie, które są minimalne, dostępne i działają we wszystkich przeglądarkach. Wypróbuj wersję demonstracyjną.
Jeśli wolisz film, oto wersja tego posta w YouTube:
Omówienie
Animacje tekstu podzielonego mogą być niesamowite. W tym poście przedstawimy tylko ułamek potencjału animacji, ale pozwoli on Ci zbudować solidne podstawy. Celem jest animacja stopniowa. Domyślnie tekst powinien być czytelny, a animacja powinna być na nim umieszczona. Efekty animacji tekstu mogą być ekstrawaganckie i potencjalnie uciążliwe, dlatego będziemy manipulować tylko HTML-em lub stosować style animacji, jeśli użytkownik wyrazi na to zgodę.
Oto ogólne omówienie procesu i jego wyników:
- Przygotuj zmienne warunkowe z ograniczonym ruchem dla plików CSS i JS.
- Przygotuj narzędzia do dzielenia tekstu w JavaScript.
- Zorganizuj warunki i elementy pomocnicze podczas wczytywania strony.
- Napisz przejścia i animacje CSS dla liter i słów (to najlepsza część).
Oto podgląd wyników warunkowych, które chcemy uzyskać:
Jeśli użytkownik woli ograniczone ruchy, nie zmieniamy dokumentu HTML i nie animujemy go. Jeśli ruch jest OK, dzielimy go na części. Oto podgląd kodu HTML po podzieleniu tekstu na litery za pomocą kodu JavaScript.
Przygotowywanie warunków ruchowych
W tym projekcie zapytanie o multimedia @media
(prefers-reduced-motion: reduce)
będzie używane z CSS i JavaScriptu. To zapytanie o multimedia jest naszym głównym warunkiem warunkowym, który decyduje o tym, czy tekst ma zostać podzielony. Zapytanie o media CSS będzie używane do blokowania przejść i animacji, a zapytanie o media JavaScript – do wstrzymania manipulacji HTML.
Przygotowywanie reguły usługi porównywania cen
Użyłem PostCSS, aby włączyć składnię zapytań o media na poziomie 5, gdzie mogę zapisać wartość logiczną zapytania o media w zmiennej:
@custom-media --motionOK (prefers-reduced-motion: no-preference);
Przygotowywanie warunku JS
W JavaScript przeglądarka udostępnia sposób sprawdzania zapytań medialnych. Aby wyodrębnić i zmienić nazwę wyniku logicznego z zapytania medialnego, użyłem destrukturyzacji:
const {matches:motionOK} = window.matchMedia(
'(prefers-reduced-motion: no-preference)'
)
Następnie mogę przetestować motionOK
i zmienić dokument tylko wtedy, gdy użytkownik nie poprosił o zmniejszenie ruchu.
if (motionOK) {
// document split manipulations
}
Mogę sprawdzić tę samą wartość, używając PostCSS do włączenia składni @nest
z Nesting Draft 1. Dzięki temu mogę zapisać w jednym miejscu całą logikę animacji i jej wymagania dotyczące stylu dotyczące elementów nadrzędnych i podrzędnych:
letter-animation {
@media (--motionOK) {
/* animation styles */
}
}
Dzięki właściwości niestandardowej PostCSS i wartości logicznej JavaScript możemy warunkowo uaktualniać efekt. W następnej sekcji omówię kod JavaScript służący do przekształcania ciągów tekstowych w elementy.
Dzielenie tekstu
Litery, słowa, linie tekstu itp. nie mogą być animowane za pomocą CSS ani JS. Aby uzyskać ten efekt, potrzebujemy pudełek. Jeśli chcemy animować każdą literę, każda litera musi być elementem. Jeśli chcemy animować każde słowo, każde słowo musi być elementem.
- Tworzenie funkcji pomocniczych JavaScript do dzielenia ciągów znaków na elementy
- sterować korzystaniem z tych narzędzi;
Funkcja dzielenia liter
Ciekawym punktem wyjścia jest funkcja, która przyjmuje ciąg znaków i zwraca każdy znak w tablicy.
export const byLetter = text =>
[...text].map(span)
Dzięki składni spread z ES6 udało mi się to zrobić bardzo szybko.
Funkcja użytkowa dzielenia słów
Podobnie jak w przypadku dzielenia liter, ta funkcja przyjmuje ciąg znaków i zwraca każdy wyraz w tablicy.
export const byWord = text =>
text.split(' ').map(span)
Metoda split()
w przypadku ciągów znaków JavaScriptu umożliwia nam określenie, na których znakach ma być wykonywany podział.
Przeszedłem przez pustą przestrzeń, co wskazuje na podział między słowami.
Funkcja narzędziowa skrzynek
Efekt wymaga umieszczenia ramki na każdą literę. 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 przypadku właściwości niestandardowej o nazwie --index
jest ustawiana pozycja tablicy. Pole z animowanymi literami to świetna rzecz, ale indeks do użycia w CSS to pozornie małe uzupełnienie, które ma duży wpływ.
Najbardziej zauważalny w tym przypadku jest rozkład czasu.
Będziemy mogli użyć elementu --index
, aby zrównoważyć animacje w celu rozłożenia animacji.
Wnioski dotyczące narzędzi
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ępnie importujesz i używasz funkcji byLetter()
i byWord()
.
Administracja podziałem
Po przygotowaniu narzędzi do dzielenia plików możesz je połączyć w ten sposób:
- Wybieranie elementów do podzielenia
- Podziel je i zastąp tekst kodem HTML.
Następnie CSS przejmuje kontrolę i animuje elementy / pola.
Wyszukiwanie elementów
Wykorzystałem atrybuty i wartości do przechowywania
informacji o wybranej animacji i sposobu podziału tekstu. Spodobało mi się umieszczanie tych opcji deklaratywnych w kodzie HTML. Atrybut split-by
jest używany w JavaScripcie do znajdowania elementów i tworzenia pól dla liter lub słów. Atrybut letter-animation
lub word-animation
jest używany w CSS do kierowania na elementy potomne i stosowania przekształceń oraz animacji.
Oto przykładowy kod HTML, który demonstruje 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 w JavaScript
Użyłem składni selektora CSS do obecności atrybutu, aby zebrać listę elementów, w których tekst ma być podzielony:
const splitTargets = document.querySelectorAll('[split-by]')
Znajdowanie elementów z CSS
Użyłem też w CSS selektora obecności atrybutu, aby nadać wszystkim animacjom liter tym samym stylom podstawowym. Później użyjemy wartości atrybutu, aby dodać bardziej szczegółowe style, które pomogą uzyskać pożądany efekt.
letter-animation {
@media (--motionOK) {
/* animation styles */
}
}
Dzielenie tekstu na miejscu
W przypadku każdego podzielonego celu w języku JavaScript podzielimy tekst na podstawie wartości atrybutu i zmapujemy każdy ciąg na obiekt <span>
. Następnie możemy zastąpić tekst elementu utworzonymi przez nas 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 administracji
index.js
ukończone:
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)
})
}
Fragment kodu JavaScript można odczytać w języku angielskim:
- importować niektóre pomocnicze funkcje pomocnicze.
- Sprawdź, czy ruch jest ok dla tego użytkownika, jeśli nie, nic nie rób.
- W przypadku każdego elementu, który chcesz podzielić.
- podzielić je na podstawie tego, jak użytkownicy chcą je podzielić.
- Zastępowanie tekstu elementami.
Dzielenie animacji i przejść
Powyższa manipulacja dokumentem odblokowała wiele potencjalnych animacji i efektów za pomocą CSS lub JavaScriptu. Na końcu tego artykułu podajemy kilka linków, które mogą Cię zainspirować.
Czas na pokazanie, co możesz zrobić z tą funkcją. Pokażę 4 animacje i przejścia oparte na CSS. 🤓
Dzielenie liter
Jako podstawę efektów litery podzielonej na części wykorzystałem następujący kod CSS. Wszystkie przejścia i animacje umieszczam w zapytaniu dotyczącego mediów animowanych, a następnie każdemu nowemu podrzędnemu elementowi span
przypisuję właściwość wyświetlania oraz styl dotyczący białych przestrzeni:
[letter-animation] > span {
display: inline-block;
white-space: break-spaces;
}
Styl białych spacji jest ważny, aby elementy, które są tylko spacją, nie były zwijane przez mechanizm układu. Teraz o ciekawostkach związanych ze stanem.
Przykład litery z podzieleniem na części
W tym przykładzie przejścia CSS są używane do efektu podzielonego tekstu. Przejścia wymagają określonych stanów, między którymi animuje się mechanizm. Wybrałem 3 stany: brak najechania, najechanie kursorem, najechanie kursorem na literę.
Gdy użytkownik najedzie kursorem na zdanie, czyli kontener, zmniejszam wszystkie elementy podrzędne, tak jakby użytkownik przesunął je dalej. Gdy użytkownik najedzie na literę, wysuwam ją do przodu.
@media (--motionOK) {
[letter-animation="hover"] {
&:hover > span {
transform: scale(.75);
}
& > span {
transition: transform .3s ease;
cursor: pointer;
&:hover {
transform: scale(1.25);
}
}
}
}
Przykład animowania podzielonych liter
W tym przykładzie do nieskończonej animacji każdego znaku używana jest wstępnie zdefiniowana animacja @keyframe
, a do tworzenia efektu przesunięcia wykorzystywany jest indeks właściwości niestandardowych w ramce.
@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 na słowa
Flexbox w tych przykładach sprawdza się jako rodzaj kontenera – dobrze wykorzystano w nim jednostkę ch
, która zapewnia odpowiednią długość luki.
word-animation {
display: inline-flex;
flex-wrap: wrap;
gap: 1ch;
}
Przykład dzielenia słów w tłumaczeniu
W tym przykładzie przejścia używam ponownie kursora. Początkowo efekt ukrywania treści do momentu najechania kursorem sprawiał, że interakcje i style były stosowane tylko wtedy, gdy urządzenie mogło najechać kursorem.
@media (hover) {
[word-animation="hover"] {
overflow: hidden;
overflow: clip;
& > span {
transition: transform .3s ease;
cursor: pointer;
&:not(:hover) {
transform: translateY(50%);
}
}
}
}
Przykład animacji dzielenia słów
W tym przykładzie animacji ponownie używam CSS @keyframes
, aby utworzyć stopniowo przechodzącą animację nieskończoną na 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
Teraz, gdy już wiesz, jak to zrobić, jak Ty to zrobisz? 🙂
Zróżnicujemy nasze podejścia i poznamy wszystkie sposoby tworzenia stron internetowych. Utwórz Codepen lub opublikuj własne demo, tweetuj je, a ja dodam je do sekcji Remixe społeczności poniżej.
Źródło
Więcej wersji demonstracyjnych i inspiracji
Remiksy utworzone przez społeczność
<text-hover>
komponent internetowy autorstwa gnehcwu na CodeSandbox