إنشاء صور متحركة مقسّمة باستخدام نص

نظرة عامة أساسية حول كيفية إنشاء صور متحركة حرفية ومقسّمة إلى كلمات.

أود في هذه المشاركة أن أشارككم أفكارًا حول طرق حل الرسوم المتحركة للنص المقسم للتفاعلات البسيطة على الويب والتي يمكن الوصول إليها وتعمل عبر المتصفحات. جرِّب العرض التوضيحي.

عرض توضيحي

إليك نسخة من هذه المشاركة على YouTube إذا كنت تفضّل ذلك:

نظرة عامة

يمكن أن تكون الرسوم المتحركة في النص المنقسم رائعة. سوف نتناول بالكاد سطح إمكانات الرسوم المتحركة في هذه المشاركة، ولكنها توفر أساسًا لإنشاء عليها. الهدف هو التحريك بشكل تدريجي. يجب أن يكون النص قابلاً للقراءة بواسطة افتراضيًا، مع إنشاء الرسوم المتحركة في الأعلى. يمكن لتأثيرات حركة النص المنقسمة تكون باهظة الثمن ومن المحتمل أن تكون مزعجة، لذلك سنقوم فقط بمعالجة HTML أو وتطبيق أنماط الحركة إذا كان المستخدم مناسبًا للحركة.

إليك نظرة عامة على سير العمل والنتائج:

  1. إعداد الحركة المشروطة للحركة المخفّضة متغيرات CSS وJS.
  2. إعداد برامج خدمات النص المقسّمة في JavaScript.
  3. تنظيم الشروط والأدوات المساعدة على الصفحة التحميل.
  4. كتابة الانتقالات والرسوم المتحركة في CSS للأحرف والكلمات (الجزء الأكبر!).

في ما يلي معاينة للنتائج الشرطية التي نريدها:

لقطة شاشة لأدوات مطوري البرامج في Chrome مع فتح لوحة "العناصر" وضبط الحركة المخفّضة على "تقليل" ويظهر خط h1 بدون تقسيم
يفضّل المستخدم الحركة المخفّضة: النص مقروء / غير مقسّم

إذا كان المستخدم يفضل الحركة المخفّضة، فنترك مستند HTML وحده ولا نفعل ذلك الرسوم المتحركة. إذا كانت الحركة على ما يرام، نمضي قدمًا ونقسمها إلى أجزاء. إليك معاينة HTML بعد أن تقسِّم JavaScript النص بحرف.

لقطة شاشة لأدوات مطوري البرامج في Chrome مع فتح لوحة "العناصر" وضبط الحركة المخفّضة على "تقليل" ويظهر خط h1 بدون تقسيم
المستخدم لا مانع من الحركة؛ نص مقسم إلى أقسام <span> متعددة العناصر

جارٍ تحضير الشرطات الشرطية للحركة

سيتم استخدام الاستعلام عن الوسائط @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، نحن على استعداد ترقية التأثير بشكل مشروط. هذا يقودنا إلى القسم التالي حيث تحليل جافا سكريبت لتحويل السلاسل إلى عناصر.

تقسيم النص

لا يمكن تحريك الأحرف النصية أو الكلمات أو السطور وما إلى ذلك بشكل فردي باستخدام CSS أو JS. لتحقيق التأثير، نحتاج إلى المربعات. إذا أردنا تحريك كل حرف، ينبغي أن يكون كل حرف عنصرًا. إذا أردنا تحريك كل كلمة، فإن كل ينبغي أن تكون الكلمة عنصرًا.

  1. إنشاء دوال أداة JavaScript لتقسيم السلاسل إلى عناصر
  2. تنظيم استخدام هذه المرافق

دالة تقسيم الأحرف

هناك مكان ممتع للبدء هو باستخدام دالة تأخذ سلسلة وترجع كل حرف في صفيف.

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() واستخدامهما.

تنسيق منفصل

عندما تصبح برامج التقسيم جاهزة للاستخدام، يعني تجميعها معًا:

  1. إيجاد العناصر المراد تقسيمها
  2. تقسيم النص واستبدال النص بـ 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 باللغة الإنجليزية التالية:

  1. استيراد بعض دوال الأدوات المساعدة
  2. تحقَّق مما إذا كانت الحركة مناسبة لهذا المستخدم، إن لم تفعل أي شيء.
  3. لكل عنصر تريد تقسيمه.
    1. يمكنك تقسيمها حسب نوعها.
    2. استبدال النص بعناصر.

تقسيم الرسوم المتحركة والانتقالات

لقد أدى التلاعب بالمستندات أعلاه إلى فتح قفل العديد من والرسوم المتحركة المحتملة والتأثيرات باستخدام 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;
}
أدوات مطوّري البرامج من Flexbox تُظهر الفجوة بين الكلمات

مثال على تقسيم الكلمات الانتقالية

في مثال النقل هذا، أستخدم التمرير مرة أخرى. نظرًا لأن التأثير يخفي في البداية المحتوى حتى التمرير، تأكدتُ من تطبيق التفاعل والأنماط فقط ما إذا كان الجهاز لديه إمكانية التمرير.

@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 أو استضافة عرضك التوضيحي، والتغريدة بها، وسأضيفها إلى يمكنك الاطّلاع على القسم أدناه حول الريمكسات التي أنشأها المنتدى.

المصدر

المزيد من العروض التوضيحية والإلهام

ريمكسات من إنشاء المنتدى