Ringkasan dasar tentang cara membuat animasi huruf dan kata terpisah.
Dalam posting ini saya ingin berbagi pemikiran tentang cara memecahkan animasi teks terpisah dan interaksi untuk web yang minimal, dapat diakses, dan berfungsi di seluruh browser. Coba demo.
Jika Anda lebih suka menonton video, berikut versi YouTube untuk postingan ini:
Ringkasan
Animasi teks terpisah bisa sangat menarik. Kita tidak akan membahas potensi animasi dalam postingan ini, tetapi hal ini memberikan fondasi untuk membangun pada saat yang sama. Tujuannya adalah untuk menganimasikan secara progresif. Teks harus dapat dibaca oleh secara default, dengan animasi yang dibuat di atasnya. Efek gerakan teks terpisah bisa terlalu berlebihan dan berpotensi mengganggu, jadi kita hanya akan memanipulasi HTML, atau menerapkan gaya gerakan jika pengguna setuju dengan gerakan.
Berikut ini ringkasan umum tentang alur kerja dan hasilnya:
- Siapkan pengurangan kondisi gerakan variabel untuk CSS dan JS.
- Prepare aplikasi teks terpisah di pada JavaScript.
- Orkestrasi kondisional dan utilitas di halaman memuat halaman.
- Menulis transisi dan animasi CSS untuk huruf dan kata (bagian rad!).
Berikut adalah pratinjau hasil kondisional yang akan kita dapatkan:
Jika pengguna menginginkan pengurangan gerakan, kita biarkan dokumen HTML saja dan tidak animasi. Jika {i>motion <i}dapat dilakukan, kita akan lanjutkan dan memotongnya menjadi beberapa bagian. Berikut adalah pratinjau HTML setelah JavaScript membagi teks menurut huruf.
Menyiapkan kondisional gerakan
Kueri media @media
(prefers-reduced-motion: reduce)
yang tersedia dengan mudah akan digunakan dari CSS dan
JavaScript di project ini. Kueri media ini adalah
kondisional utama kita untuk
memutuskan untuk memisahkan
teks atau tidak. Kueri media CSS akan digunakan untuk menahan
transisi dan animasi, sedangkan kueri media JavaScript akan digunakan untuk
menahan manipulasi HTML.
Menyiapkan kondisional CSS
Saya menggunakan PostCSS untuk mengaktifkan sintaksis Kueri Media Level 5, tempat saya dapat menyimpan boolean kueri media ke dalam variabel:
@custom-media --motionOK (prefers-reduced-motion: no-preference);
Menyiapkan kondisional JS
Di JavaScript, {i>browser<i} menyediakan cara untuk memeriksa kueri media, saya menggunakan penguraian untuk mengekstrak dan mengganti nama hasil boolean dari pemeriksaan kueri media:
const {matches:motionOK} = window.matchMedia(
'(prefers-reduced-motion: no-preference)'
)
Kemudian saya dapat menguji motionOK
, dan hanya mengubah dokumen jika pengguna belum melakukannya
diminta untuk mengurangi gerakan.
if (motionOK) {
// document split manipulations
}
Saya dapat memeriksa nilai yang sama menggunakan PostCSS untuk mengaktifkan sintaksis @nest
dari
Draf Bertingkat 1. Hal ini memungkinkan saya untuk
menyimpan semua logika tentang animasi dan persyaratan gayanya untuk
orang tua dan anak, di satu tempat:
letter-animation {
@media (--motionOK) {
/* animation styles */
}
}
Dengan properti khusus PostCSS dan boolean JavaScript, kita siap untuk mengupgrade efek secara bersyarat. Selanjutnya kita akan membahas bagian berikutnya, di mana saya memecah JavaScript untuk mengubah {i>string<i} menjadi elemen.
Memisahkan Teks
Huruf teks, kata, baris, dll. tidak dapat dianimasikan satu per satu dengan CSS atau JS. Untuk mencapai efek ini, kita membutuhkan kotak. Jika kita ingin menganimasikan setiap huruf, maka setiap huruf harus menjadi elemen. Jika kita ingin menganimasikan setiap kata, maka kata harus menjadi elemen.
- Membuat fungsi utilitas JavaScript untuk memisahkan string menjadi elemen
- Orkestrasikan penggunaan utilitas ini
Fungsi utilitas huruf terpisah
Tempat yang menyenangkan untuk memulai adalah dengan fungsi yang mengambil string dan menampilkan masing-masing huruf dalam array.
export const byLetter = text =>
[...text].map(span)
Tujuan penyebaran {i>syntax<i} dari ES6 benar-benar membantu menjadikannya tugas yang cepat.
Fungsi utilitas kata pemisahan
Mirip dengan memisahkan huruf, fungsi ini mengambil string dan menampilkan setiap kata dalam array.
export const byWord = text =>
text.split(' ').map(span)
Tujuan
split()
pada {i>string<i} JavaScript memungkinkan kita untuk menentukan karakter mana yang akan diiris.
Saya melewati ruang kosong, yang menunjukkan pemisahan di antara kata.
Membuat fungsi utilitas box
Efeknya membutuhkan kotak untuk setiap huruf, dan
kita lihat di fungsi itu, bahwa
map()
dipanggil dengan fungsi span()
. Berikut adalah fungsi span()
.
const span = (text, index) => {
const node = document.createElement('span')
node.textContent = text
node.style.setProperty('--index', index)
return node
}
Penting untuk diperhatikan bahwa properti khusus yang disebut --index
sedang ditetapkan dengan
posisi array. Memiliki kotak-kotak untuk animasi huruf
itu bagus, tapi
memiliki indeks untuk digunakan dalam CSS adalah tambahan yang
tampak kecil dengan dampak yang besar.
Yang paling terkenal dalam
dampak besar ini adalah
sangat mengejutkan.
Kita akan dapat menggunakan --index
sebagai cara untuk mengalihkan animasi untuk
lihat.
Kesimpulan utilitas
Modul splitting.js
telah selesai:
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)
Berikutnya adalah mengimpor dan menggunakan fungsi byLetter()
dan byWord()
ini.
Orkestrasi pemisahan
Dengan utilitas terpisah yang siap digunakan, menyatukan semuanya berarti:
- Menemukan elemen yang akan dipisahkan
- Memisahkan dan mengganti teks dengan HTML
Setelah itu, CSS akan mengambil alih dan akan menganimasikan elemen / kotak.
Elemen Temuan
Saya memilih menggunakan atribut dan nilai untuk menyimpan informasi tentang
animasi dan cara
memisahkan teks. Saya suka menggunakan opsi deklaratif
di dalam HTML. Atribut split-by
digunakan dari JavaScript untuk menemukan
elemen dan membuat kotak untuk huruf atau kata. Atribut
letter-animation
atau word-animation
digunakan dari CSS, untuk menargetkan elemen
turunan dan menerapkan transformasi dan animasi.
Berikut adalah contoh HTML yang menunjukkan kedua atribut tersebut:
<h1 split-by="letter" letter-animation="breath">animated letters</h1>
<h1 split-by="word" word-animation="trampoline">hover the words</h1>
Menemukan elemen dari JavaScript
Saya menggunakan sintaks pemilih CSS untuk keberadaan atribut guna mengumpulkan daftar elemen yang ingin teksnya terpisah:
const splitTargets = document.querySelectorAll('[split-by]')
Menemukan elemen dari CSS
Saya juga menggunakan pemilih kehadiran atribut di CSS untuk memberikan semua animasi huruf gaya dasar yang sama. Nanti, kita akan menggunakan nilai atribut untuk menambahkan nilai yang lebih spesifik gaya untuk memperoleh suatu efek.
letter-animation {
@media (--motionOK) {
/* animation styles */
}
}
Memisahkan teks di tempatnya
Untuk setiap target pemisahan yang ditemukan di JavaScript, kita akan membagi teksnya
berdasarkan nilai atribut dan petakan setiap string ke <span>
. Kita dapat
kemudian ganti teks elemen dengan kotak yang kita buat:
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)
}
})
Kesimpulan orkestrasi
index.js
dalam proses:
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)
})
}
JavaScript dapat dibaca dalam bahasa Inggris berikut:
- Impor beberapa fungsi utilitas bantuan.
- Periksa apakah gerakan diperbolehkan untuk pengguna ini, jika tidak, jangan lakukan apa pun.
- Untuk setiap elemen yang ingin dipisah.
- Memisahkannya berdasarkan cara pemisahannya.
- Ganti teks dengan elemen.
Memisahkan animasi dan transisi
Manipulasi pemisahan dokumen di atas baru saja membuka banyak animasi dan efek yang potensial dengan CSS atau JavaScript. Ada beberapa tautan di bagian bawah artikel ini untuk membantu menginspirasi potensi pemisahan Anda.
Saatnya menunjukkan apa yang bisa Anda lakukan dengan ini! Saya akan membagikan 4 animasi berbasis CSS dan transisi. 🤓
Pisahkan huruf
Sebagai fondasi untuk efek huruf terpisah, saya menemukan bahwa CSS berikut
membantu. Saya meletakkan semua transisi dan animasi
di belakang kueri media {i>motion<i} dan
lalu beri setiap huruf turunan baru span
properti tampilan dan gaya untuk
dilakukan dengan spasi putih:
[letter-animation] > span {
display: inline-block;
white-space: break-spaces;
}
Gaya spasi putih penting supaya bentang yang hanya merupakan sebuah spasi, tidak diciutkan oleh mesin tata letak. Sekarang, kita masuk ke hal-hal menyenangkan yang stateful.
Contoh huruf terpisah transisi
Contoh ini menggunakan transisi CSS ke efek teks terpisah. Dengan transisi, kita memerlukan status untuk dianimasikan mesin, dan saya memilih tiga status: tidak arahkan kursor, arahkan kursor ke kalimat, arahkan kursor ke huruf.
Saat pengguna mengarahkan kursor ke kalimat, yang disebut juga penampung, saya anak-anak seolah-olah pengguna mendorong mereka semakin jauh. Lalu, saat pengguna mengarahkan kursor saya, saya akan meneruskannya.
@media (--motionOK) {
[letter-animation="hover"] {
&:hover > span {
transform: scale(.75);
}
& > span {
transition: transform .3s ease;
cursor: pointer;
&:hover {
transform: scale(1.25);
}
}
}
}
Menganimasikan contoh huruf terpisah
Contoh ini menggunakan animasi @keyframe
yang telah ditentukan untuk animasi tanpa batas
dan memanfaatkan indeks properti khusus inline untuk membuat
pengaruh tersebut.
@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;
}
}
Pisahkan kata
Flexbox berfungsi sebagai jenis kontainer bagi saya
dalam contoh-contoh ini, dengan baik
memanfaatkan unit ch
sebagai panjang gap yang sehat.
word-animation {
display: inline-flex;
flex-wrap: wrap;
gap: 1ch;
}
Contoh kata terpisah transisi
Dalam contoh transisi ini, saya menggunakan arah kursor lagi. Karena efek mula-mula menyembunyikan konten hingga kursor diarahkan, saya memastikan bahwa interaksi dan gaya hanya diterapkan jika perangkat memiliki kemampuan untuk mengarahkan kursor.
@media (hover) {
[word-animation="hover"] {
overflow: hidden;
overflow: clip;
& > span {
transition: transform .3s ease;
cursor: pointer;
&:not(:hover) {
transform: translateY(50%);
}
}
}
}
Menganimasikan contoh kata terpisah
Dalam contoh animasi ini, saya menggunakan CSS @keyframes
lagi untuk membuat
animasi tak terbatas pada paragraf teks reguler.
[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;
}
}
Kesimpulan
Sekarang setelah Anda tahu cara saya melakukannya, bagaimana Anda akan melakukannya?! 🙂
Mari kita diversifikasi pendekatan kami dan mempelajari semua cara untuk membangun di web. Buat Codepen atau host demo Anda sendiri, kirim tweet kepada saya, dan saya akan menambahkannya ke Bagian remix komunitas di bawah ini.
Sumber
Lebih banyak demo dan inspirasi
Remix komunitas
- Komponen web
<text-hover>
oleh gnehcwu di CodeSandbox