Bölünmüş harf ve kelime animasyonlarının nasıl oluşturulacağına dair temel bir genel bakış.
Bu yayında, web'de bölünmüş metin animasyonlarını ve etkileşimlerini minimum düzeyde, erişilebilir ve tarayıcılar arasında çalışan şekilde çözme yolları hakkındaki düşüncelerimi paylaşmak istiyorum. Demoyu deneyin.
Videoyu tercih ediyorsanız bu yayının YouTube sürümünü burada bulabilirsiniz:
Genel Bakış
Bölünmüş metin animasyonları şaşırtıcı olabilir. Bu yayında, animasyon potansiyelinin sadece küçük bir kısmını ele alacağız. Ancak bu, üzerine inşa edebileceğiniz bir temel sağlar. Amaç, animasyonu kademeli olarak gerçekleştirmektir. Metin, varsayılan olarak okunaklı olmalı ve animasyon üzerine yerleştirilmelidir. Bölünmüş metin hareket efektleri abartılı ve potansiyel olarak rahatsız edici olabilir. Bu nedenle, yalnızca HTML'yi değiştiririz veya kullanıcı hareketi kabul ediyorsa hareket stilleri uygularız.
Aşağıda, iş akışına ve sonuçlara genel bir bakış verilmiştir:
- CSS ve JS için azaltılmış hareket koşullu değişkenleri hazırlayın.
- JavaScript'te bölünmüş metin yardımcı programlarını hazırlayın.
- Sayfa yüklenirken koşullu ifadeleri ve yardımcı programları düzenleyin.
- Harfler ve kelimeler için CSS geçişleri ve animasyonları yazın (en heyecan verici kısım budur).
Hedeflediğimiz koşullu sonuçların önizlemesini aşağıda görebilirsiniz:
Kullanıcı hareketin azaltılmasını tercih ederse HTML dokümanı olduğu gibi bırakılır ve animasyon uygulanmaz. Hareket iyiyse videoyu parçalara ayırırız. JavaScript metni harfe göre böldükten sonra HTML'nin önizlemesi aşağıda verilmiştir.
Hareket koşullularını hazırlama
Bu projede, kolayca kullanılabilen @media
(prefers-reduced-motion: reduce)
medya sorgusu CSS ve JavaScript'den kullanılacaktır. Bu medya sorgusu, metni bölmeye karar verirken kullandığımız birincil koşuldur. CSS medya sorgusu, geçişleri ve animasyonları engellemek için kullanılırken JavaScript medya sorgusu, HTML'de yapılan değişiklikleri engellemek için kullanılır.
CSS koşullu ifadesi hazırlama
Bir medya sorgusu boole değerini bir değişkende saklayabileceğim Medya Sorguları 5. Seviye söz dizimini etkinleştirmek için PostCSS'yi kullandım:
@custom-media --motionOK (prefers-reduced-motion: no-preference);
JS koşullu ifadesi hazırlanıyor
JavaScript'te tarayıcı, medya sorgularını kontrol etmenin bir yolunu sağlar. Medya sorgusu kontrolünden elde edilen Boole sonucunu ayıklayıp yeniden adlandırmak için yapı bozma özelliğini kullandım:
const {matches:motionOK} = window.matchMedia(
'(prefers-reduced-motion: no-preference)'
)
Ardından motionOK
için test yapabilir ve yalnızca kullanıcı hareketi azaltma isteğinde bulunmadıysa dokümanı değiştirebilirim.
if (motionOK) {
// document split manipulations
}
İç İçe Sarma Taslağı 1'den @nest
söz dizimini etkinleştirmek için PostCSS'yi kullanarak aynı değeri kontrol edebilirim. Bu sayede, animasyonla ilgili tüm mantığı ve ana öğe ile alt öğeler için stil şartlarını tek bir yerde saklayabilirim:
letter-animation {
@media (--motionOK) {
/* animation styles */
}
}
PostCSS özel mülkü ve JavaScript doğru/yanlış değeriyle efekti koşullu olarak yükseltmeye hazırız. Bu bizi, dizelerin öğelere dönüştürülmesi için JavaScript'i ayrıntılı olarak incelediğim bir sonraki bölüme götürür.
Metni bölme
Metin harfleri, kelimeleri, satırları vb. CSS veya JS ile tek tek animasyonlu hale getirilemez. Bu efekti elde etmek için kutulara ihtiyacımız var. Her harfi animasyonlu hale getirmek istiyorsak her harfin bir öğe olması gerekir. Her bir kelimeyi animasyonlu hale getirmek istiyorsak her kelimenin bir öğe olması gerekir.
- Dizeleri öğelere bölme için JavaScript yardımcı işlevleri oluşturma
- Bu yardımcı programların kullanımını koordine etme
Harfleri bölme yardımcı programı işlevi
Başlamak için eğlenceli bir işlev, bir dize alan ve her harfi bir diziyle döndüren işlevdir.
export const byLetter = text =>
[...text].map(span)
ES6'taki yayma söz dizimi, bu işlemin hızlı bir şekilde yapılmasına yardımcı oldu.
Kelime bölme yardımcı programı işlevi
Harfleri bölme işlemine benzer şekilde bu işlev bir dize alır ve her kelimeyi bir diziyle döndürür.
export const byWord = text =>
text.split(' ').map(span)
JavaScript dizelerindeki split()
yöntemi, hangi karakterlerin dilimleneceğini belirtmemize olanak tanır.
Kelimeler arasında boşluk olduğunu belirten bir boşluk bıraktım.
Kutuları hizmet işlevi haline getirme
Bu efekt için her harf için kutu gerekir. Bu işlevlerde map()
işlevinin span()
işleviyle çağrıldığını görüyoruz. span()
işlevi aşağıda verilmiştir.
const span = (text, index) => {
const node = document.createElement('span')
node.textContent = text
node.style.setProperty('--index', index)
return node
}
Dizi konumuyla --index
adlı bir özel özelliğin ayarlandığını unutmayın. Harf animasyonları için kutulara sahip olmak harika bir özellik olsa da CSS'de kullanılacak bir dizinin olması, büyük etkisi olan küçük bir eklemedir.
Bu büyük etkide en dikkat çeken şey staggering.
--index
değerini, kademeli bir görünüm için animasyonların kaydırılmasını sağlamak amacıyla kullanabiliriz.
Yardımcı Araçlar sonucu
Tamamlanan splitting.js
modülü:
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)
Ardından bu byLetter()
ve byWord()
işlevlerini içe aktarıp kullanmalısınız.
Bölünmüş düzenleme
Bölme yardımcı programları kullanıma hazır olduğunda, tüm bunları bir araya getirmek şu avantajları sağlar:
- Bölünecek öğeleri bulma
- Bunları bölme ve metni HTML ile değiştirme
Ardından CSS devreye girer ve öğeleri / kutuları hareketlendirir.
Öğeleri bulma
İstenilen animasyon ve metnin nasıl bölüneceği hakkındaki bilgileri depolamak için özellikleri ve değerleri kullanmayı tercih ettim. Bu açıklayıcı seçenekleri HTML'ye koymayı sevdim. split-by
özelliği, öğeleri bulmak ve harfler veya kelimeler için kutular oluşturmak amacıyla JavaScript'de kullanılır. letter-animation
veya word-animation
özelliği, öğe alt öğelerini hedeflemek ve dönüştürme ile animasyon uygulamak için CSS'den kullanılır.
Aşağıda, bu iki özelliği gösteren bir HTML örneği verilmiştir:
<h1 split-by="letter" letter-animation="breath">animated letters</h1>
<h1 split-by="word" word-animation="trampoline">hover the words</h1>
JavaScript'ten öğe bulma
Metinlerinin bölünmesini isteyen öğelerin listesini toplamak için özellik varlığı için CSS seçici söz dizimini kullandım:
const splitTargets = document.querySelectorAll('[split-by]')
CSS'den öğe bulma
Ayrıca, tüm harf animasyonlarına aynı temel stilleri vermek için CSS'de özellik varlığı seçicisini kullandım. Daha sonra, bir efekt elde etmek için daha spesifik stiller eklemek üzere özellik değerini kullanacağız.
letter-animation {
@media (--motionOK) {
/* animation styles */
}
}
Metni yerinde bölme
JavaScript'te bulduğumuz bölünmüş hedeflerin her biri için metinlerini özelliğin değerine göre böler ve her dizeyi bir <span>
ile eşleriz. Ardından öğenin metnini, oluşturduğumuz kutularla değiştirebiliriz:
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)
}
})
Düzenleme sonucu
index.js
tamamlandı:
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 aşağıdaki İngilizce dilinde okunabilir:
- Bazı yardımcı yardımcı program işlevlerini içe aktarın.
- Bu kullanıcı için hareketin uygun olup olmadığını kontrol edin. Uygun değilse hiçbir işlem yapmayın.
- Bölünmek istenen her öğe için.
- Kullanıcıların nasıl bölünmek istediklerine göre bölün.
- Metni öğelerle değiştirin.
Animasyonları ve geçişleri bölme
Yukarıdaki dokümanı bölme işlemi, CSS veya JavaScript ile birçok olası animasyon ve efektin kilidini açtı. Bu makalenin alt kısmında, bölünme potansiyelinize ilham verecek birkaç bağlantı verilmiştir.
Bu fırsatı değerlendirin. 4 CSS destekli animasyon ve geçiş paylaşacağım. 🤓
Bölünmüş harfler
Bölünmüş harf efektleri için temel olarak aşağıdaki CSS'yi kullandım. Tüm geçişleri ve animasyonları hareketli medya sorgusunun arkasına koydum ve ardından her yeni alt harf span
'ye bir görüntüleme özelliği ve boşluklarla ne yapılacağıyla ilgili bir stil verdim:
[letter-animation] > span {
display: inline-block;
white-space: break-spaces;
}
Boşluk stili, yalnızca boşluk olan aralıkların düzen motoru tarafından daraltılmaması için önemlidir. Şimdi de durum bilgisine sahip eğlenceli konulara geçelim.
Geçiş için bölünmüş harf örneği
Bu örnekte, bölünmüş metin efekti için CSS geçişleri kullanılmaktadır. Geçişlerde, motorun animasyon oluşturması için aralarında geçiş yapacağı durumlara ihtiyacımız var. Ben üç durum seçtim: fareyle üzerine gelme yok, cümlede fareyle üzerine gelme, harfin üzerinde fareyle üzerine gelme.
Kullanıcı cümlenin (yani kapsayıcının) üzerine geldiğinde, tüm alt öğeleri kullanıcı onları uzaklaştırıyormuş gibi küçültüyorum. Ardından, kullanıcı fareyle bir harfin üzerine geldiğinde harfi öne çıkarıyorum.
@media (--motionOK) {
[letter-animation="hover"] {
&:hover > span {
transform: scale(.75);
}
& > span {
transition: transform .3s ease;
cursor: pointer;
&:hover {
transform: scale(1.25);
}
}
}
}
Bölünmüş harflere animasyon uygulama örneği
Bu örnekte, her harfi sonsuz olarak animasyonlu hale getirmek için önceden tanımlanmış bir @keyframe
animasyonu kullanılmakta ve satır içi özel mülk dizini, kademeli bir efekt oluşturmak için kullanılmaktadır.
@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;
}
}
Kelimeleri bölme
Flexbox, bu örneklerde benim için bir kapsayıcı türü olarak çalıştı ve ch
birimini sağlıklı bir boşluk uzunluğu olarak iyi bir şekilde kullandı.
word-animation {
display: inline-flex;
flex-wrap: wrap;
gap: 1ch;
}
Geçiş için kelimeleri bölme örneği
Bu geçiş örneğinde yine fareyle üzerine gelme özelliğini kullanıyorum. Etki, fareyle üzerine gelinene kadar içeriği başlangıçta gizlediğinden, etkileşimin ve stillerin yalnızca cihazda fareyle üzerine gelme özelliği varsa uygulandığından emin oldum.
@media (hover) {
[word-animation="hover"] {
overflow: hidden;
overflow: clip;
& > span {
transition: transform .3s ease;
cursor: pointer;
&:not(:hover) {
transform: translateY(50%);
}
}
}
}
Bölünmüş kelimelere animasyon uygulama örneği
Bu animasyon örneğinde, normal bir metin paragrafında kademeli sonsuz animasyon oluşturmak için tekrar CSS @keyframes
kullanıyorum.
[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;
}
}
Sonuç
Bunu nasıl yaptığımı öğrendiğinize göre, siz ne yapardınız? 🙂
Yaklaşımlarımızı çeşitlendirelim ve web'de uygulama geliştirmenin tüm yollarını öğrenelim. Codepen oluşturun veya kendi demonuzu barındırın, bana tweet atın. Ardından, demoyu aşağıdaki Topluluk remiksleri bölümüne ekleyeceğim.
Kaynak
Daha fazla demo ve ilham kaynağı
Topluluk remiksleri
- CodeSandbox'ta gnehcwu tarafından oluşturulan
<text-hover>
web bileşeni