نظرة عامة أساسية حول كيفية إنشاء صور متحركة مجزّأة للكلمات والحروف
في هذه المشاركة، أريد مشاركة أفكار حول طرق حلّ الصور المتحركة للنص المُقسَّم والتفاعلات على الويب التي تكون بسيطة وسهلة الاستخدام وتعمل على جميع المتصفّحات. جرِّب العرض التوضيحي.
إذا كنت تفضّل الفيديو، يمكنك الاطّلاع على نسخة من هذه المشاركة على YouTube:
نظرة عامة
يمكن أن تكون الصور المتحرّكة للنص المُقسَّم رائعة. سوف نتناول بالكاد جزءًا من إمكانات الرسوم المتحركة في هذه المشاركة، ولكنها توفر أساسًا للبناء. الهدف هو التحريك بشكل تدريجي. يجب أن يكون النص مقروءًا بشكل تلقائي، مع إضافة الرسوم المتحركة فوقه. يمكن أن تصبح تأثيرات الحركة للنص المُقسَّم مفرطة وقد تتسبب في حدوث انقطاعات، لذا سنتعامل فقط مع لغة HTML أو سنطبّق أنماط الحركة إذا كان المستخدم لا يمانع ذلك.
إليك نظرة عامة على سير العمل والنتائج:
- احرِص على إعداد المتغيّرات المشروطة للحركة المنخفضة في CSS وJavaScript.
- احرِص على إعداد أدوات تقسيم النص في JavaScript.
- تنظيم الشروط والأدوات المساعدة عند تحميل الصفحة
- كتابة عمليات النقل والحركات في CSS للأحرف والكلمات (الجزء المثير)
في ما يلي معاينة للنتائج الشَرطية التي نسعى إليها:
إذا كان المستخدم يفضل الحركة المخفّضة، نترك مستند HTML وحده ولا نستخدم أي رسوم متحركة. إذا كانت الحركة جيدة، سنقطعها إلى أجزاء. في ما يلي معاينة HTML بعد أن قامت JavaScript بتقسيم النص بالحرف.
جارٍ تحضير الشرطات الشرطية للحركة
سيتم استخدام طلب البحث عن الوسائط @media
(prefers-reduced-motion: reduce)
المتاح بسهولة من CSS و
JavaScript في هذا المشروع. طلب البحث عن الوسائط هذا هو الشرط الأساسي لتحديد ما إذا كان سيتم تقسيم النص أم لا. سيتم استخدام استعلام وسائط CSS لحجب الانتقالات والرسوم المتحركة، بينما سيتم استخدام استعلام وسائط JavaScript
لحجب معالجة HTML.
تحضير الشرط في CSS
لقد استخدمتُ PostCSS لتفعيل بنية استعلامات الوسائط المستوى 5، حيث يمكنني تخزين استعلام عن وسائط منطقي في متغيّر:
@custom-media --motionOK (prefers-reduced-motion: no-preference);
تحضير الشرط في JavaScript
في JavaScript، يقدّم المتصفّح طريقة للتحقّق من طلبات البحث عن الوسائط، وقد استخدمت إعادة التشكيل لاستخراج النتيجة المنطقية وإعادة تسميتها من عملية التحقّق من طلب البحث عن الوسائط:
const {matches:motionOK} = window.matchMedia(
'(prefers-reduced-motion: no-preference)'
)
يمكنني بعد ذلك اختبار motionOK
، ولن أغيّر المستند إلا إذا لم يطلب المستخدِم
تقليل الحركة.
if (motionOK) {
// document split manipulations
}
يمكنني التحقّق من القيمة نفسها باستخدام PostCSS لتفعيل بنية @nest
من
مسودة "التداخل" 1. يتيح لي ذلك
تخزين كل منطق الرسوم المتحركة ومتطلبات أسلوبها في مكان واحد، سواءً بالنسبة إلى
الوالدَين أو الأطفال:
letter-animation {
@media (--motionOK) {
/* animation styles */
}
}
باستخدام خاصية PostCSS المخصصة والمنطقية في JavaScript، نحن على استعداد لترقية التأثير بشكل مشروط. ينقلنا ذلك إلى القسم التالي حيث سأشرح رمز JavaScript لتحويل السلاسل إلى عناصر.
تقسيم النص
لا يمكن إضافة تأثيرات متحركة بشكل فردي إلى أحرف النص أو الكلمات أو السطور أو غير ذلك باستخدام CSS أو JS. لتحقيق التأثير المطلوب، نحتاج إلى صناديق. إذا أردنا إضافة تأثيرات متحركة إلى كل حرف، يجب أن يكون كل حرف عنصرًا. إذا أردنا إضافة تأثيرات متحركة لكل كلمة، يجب أن تكون كل كلمة عنصرًا.
- إنشاء دوال أداة JavaScript لتقسيم السلاسل إلى عناصر
- تنظيم استخدام هذه المرافق
دالة خدمية لتقسيم الأحرف
يمكنك البدء باستخدام دالة تأخذ سلسلة وتُخرج كل حرف في صفيف.
export const byLetter = text =>
[...text].map(span)
ساعدت بنية الانتشار من ES6 حقًا في إنجاز هذه المهمة بسرعة.
دالة خدمية لتقسيم الكلمات
على غرار تقسيم الأحرف، تأخذ هذه الدالة سلسلة وتُعرِض كل كلمة في صفيف.
export const byWord = text =>
text.split(' ').map(span)
تسمح لنا طريقة
split()
في سلاسل JavaScript بتحديد الأحرف التي سيتم تقطيعها.
مررتُ على مسافة فارغة، ما يشير إلى تقسيم بين الكلمات.
استخدام مربّعات الأدوات
يتطلّب التأثير مربّعات لكل حرف، ونرى في هذه الدوالّ أنّه يتم استدعاء
map()
باستخدام دالة span()
. في ما يلي دالة span()
.
const span = (text, index) => {
const node = document.createElement('span')
node.textContent = text
node.style.setProperty('--index', index)
return node
}
من المهمّ ملاحظة أنّه يتمّ ضبط سمة مخصّصة باسم --index
باستخدام
موضع المصفوفة. من الرائع أن تتوفّر لك مربّعات للحركات المتحرّكة للحروف، ولكن
إنّ توفّر فهرس لاستخدامه في CSS هو إضافة صغيرة على ما يبدو لها تأثير كبير.
ومن أبرز التأثيرات الكبيرة التي نتجت عن ذلك هو
الانخفاض المفاجئ.
سنتمكن من استخدام --index
كطريقة لتقليل الرسوم المتحركة للحصول على شكل
متفاوت.
خاتمة حول الخدمات
وحدة 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)
الخطوة التالية هي استيراد الدالتين byLetter()
وbyWord()
واستخدامهما.
عملية التنسيق المُقسَّمة
مع توفّر أدوات التقسيم الجاهزة للاستخدام، يعني ذلك ما يلي:
- تحديد العناصر التي يجب تقسيمها
- تقسيم النص واستبدال النص بـ HTML
بعد ذلك، تتولى خدمة CSS عرض العناصر أو المربّعات بتأثيرات متحركة.
العثور على العناصر
اخترت استخدام السمات والقيم لتخزين معلومات عن المقصود
بالحركة وكيفية تقسيم النص. أحببتُ وضع هذه الخيارات التعريفية
في رمز HTML. يتم استخدام السمة split-by
من JavaScript للعثور على
العناصر وإنشاء مربّعات للحروف أو الكلمات. يتم استخدام السمة
letter-animation
أو word-animation
من CSS لاستهداف عناصر
الأبناء وتطبيق عمليات التحويل والحركات.
في ما يلي نموذج HTML يوضّح السمتَين:
<h1 split-by="letter" letter-animation="breath">animated letters</h1>
<h1 split-by="word" word-animation="trampoline">hover the words</h1>
العثور على العناصر من JavaScript
لقد استخدمت بنية محدد CSS لتحديد وجود السمة من أجل جمع قائمة بالعناصر التي يجب تقسيم نصها:
const splitTargets = document.querySelectorAll('[split-by]')
العثور على عناصر من CSS
لقد استخدمت أيضًا أداة اختيار مدى توفّر السمة في CSS لمنح جميع الرسومات المتحركة للرسائل الأنماط الأساسية نفسها. لاحقًا، سنستخدم قيمة السمة لإضافة مزيد من الأنماط المحدّدة لتحقيق تأثير معيّن.
letter-animation {
@media (--motionOK) {
/* animation styles */
}
}
تقسيم النص في مكانه
بالنسبة إلى كلّ استهداف من استهدافات التقسيم التي نعثر عليها في JavaScript، سنقسّم نصها
استنادًا إلى قيمة السمة ونربط كلّ سلسلة بعنصر <span>
. يمكننا
بعد ذلك استبدال نص العنصر بالمربّعات التي أنشأناها:
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)
}
})
خاتمة عملية التنسيق
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)
})
}
يمكن قراءة JavaScript باللغة الإنجليزية التالية:
- استورِد بعض الدوال المساعِدة.
- تحقّق مما إذا كانت الحركة مناسبة لهذا المستخدم، وإذا لم تكن كذلك، لا داعي لإجراء أيّ شيء.
- لكل عنصر تريد تقسيمه.
- تقسيمها حسب الطريقة التي يريدون تقسيمها بها
- استبدِل النص بعناصر.
تقسيم الحركات والانتقالات
من خلال معالجة المستندات أعلاه، أصبح بإمكانك استخدام CSS أو JavaScript لإنشاء العديد من الصور المتحركة والتأثيرات المحتملة. في أسفل هذه المقالة، يمكنك الاطّلاع على بعض الروابط التي تساعدك في التعرّف على فرص تقسيم المحتوى.
حان الوقت لإظهار ما يمكنك فعله باستخدام هذه الميزة. سأشارك 4 رسوم متحركة وانتقالات تعتمد على CSS. 🤓
تقسيم الحروف
لقد تبيّن لي أنّ ملف CSS التالي مفعّل
كقاعدة لتأثيرات تقسيم الأحرف. أضع كل الانتقالات والرسوم المتحركة وراء استعلام وسائط الحركة
ثم أعطي كل حرف فرعي جديد span
خاصية عرض بالإضافة إلى نمط لما
يجب فعله بالمساحات البيضاء:
[letter-animation] > span {
display: inline-block;
white-space: break-spaces;
}
إنّ أسلوب المساحات البيضاء مهمّ لكي لا يُدمج محرّك التنسيق الفواصل التي لا تحتوي إلا على مساحة. ننتقل الآن إلى الميزات الممتعة التي تتضمّن حالة.
مثال على تقسيم الأحرف في الانتقال
يستخدم هذا المثال انتقالات CSS إلى تأثير تقسيم النص. من خلال الانتقالات، نحتاج إلى حالات لكي يتحرك المحرك بينها، واخترتُ ثلاث حالات: لا تمرير، مرر الماوس فوق الجملة، مرر فوق حرف.
عندما يمرّر المستخدم مؤشر الماوس فوق الجملة، أي الحاوية، أُقلّل حجم كل العناصر التابعة كما لو أنّ المستخدم دفعها بعيدًا. بعد ذلك، عندما يمرِّر المستخدم مؤشر الماوس فوق أحد الأحرف، أُبرزه.
@media (--motionOK) {
[letter-animation="hover"] {
&:hover > span {
transform: scale(.75);
}
& > span {
transition: transform .3s ease;
cursor: pointer;
&:hover {
transform: scale(1.25);
}
}
}
}
مثال على تحريك الأحرف المقسّمة
يستخدم هذا المثال حركة @keyframe
مُحدَّدة مسبقًا لتحريك كل حرف
بشكلٍ لا نهائي، ويستفيد من فهرس السمة المخصّصة المضمّنة لإنشاء تأثير
تدرّج.
@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;
}
}
تقسيم الكلمات
عملت Flexbox كنوع حاوية بالنسبة لي هنا في هذه الأمثلة، مع الاستفادة بشكل جيد من وحدة ch
كطول فجوة سليمة.
word-animation {
display: inline-flex;
flex-wrap: wrap;
gap: 1ch;
}
مثال على تقسيم الكلمات الانتقالية
في مثال النقل هذا، أستخدم التمرير مرة أخرى. وبما أنّ التأثير يخفي المحتوى في البداية حتى التمرير فوقه، فقد تأكدتُ من تطبيق التفاعل والأنماط فقط إذا توفرت إمكانية التمرير في الجهاز.
@media (hover) {
[word-animation="hover"] {
overflow: hidden;
overflow: clip;
& > span {
transition: transform .3s ease;
cursor: pointer;
&:not(:hover) {
transform: translateY(50%);
}
}
}
}
مثال على كلمات متحرّكة مُقسَّمة
في مثال الحركة هذا، أستخدِم CSS @keyframes
مرة أخرى لإنشاء حركة متقطّعة
لانهائية على فقرة عادية من النص.
[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;
}
}
الخاتمة
الآن بعد أن عرفت كيف فعلت ذلك، كيف ستفعل ذلك؟ 🙂
لننوّع أساليبنا ونتعرّف على جميع الطرق لإنشاء تطبيقات على الويب. أنشئ نموذجًا على Codepen أو استضِف عرضًا توضيحيًا خاصًا بك، وشاركه معي على Twitter، وسأضيفه إلى قسم "الريمكسات التي أنشأها المجتمع" أدناه.
المصدر
المزيد من العروض التوضيحية والأفكار
الريمكسات التي أنشأها المستخدمون
- مكوّن ويب
<text-hover>
من gnehcwu على CodeSandbox