اذهب إلى المحتوى

البحث في الموقع

المحتوى عن 'تحريك'.

  • ابحث بالكلمات المفتاحية

    أضف وسومًا وافصل بينها بفواصل ","
  • ابحث باسم الكاتب

نوع المحتوى


التصنيفات

  • الإدارة والقيادة
  • التخطيط وسير العمل
  • التمويل
  • فريق العمل
  • دراسة حالات
  • التعامل مع العملاء
  • التعهيد الخارجي
  • السلوك التنظيمي في المؤسسات
  • عالم الأعمال
  • التجارة والتجارة الإلكترونية
  • نصائح وإرشادات
  • مقالات ريادة أعمال عامة

التصنيفات

  • مقالات برمجة عامة
  • مقالات برمجة متقدمة
  • PHP
    • Laravel
    • ووردبريس
  • جافاسكربت
    • لغة TypeScript
    • Node.js
    • React
    • Vue.js
    • Angular
    • jQuery
    • Cordova
  • HTML
  • CSS
    • Sass
    • إطار عمل Bootstrap
  • SQL
  • لغة C#‎
    • ‎.NET
    • منصة Xamarin
  • لغة C++‎
  • لغة C
  • بايثون
    • Flask
    • Django
  • لغة روبي
    • إطار العمل Ruby on Rails
  • لغة Go
  • لغة جافا
  • لغة Kotlin
  • لغة Rust
  • برمجة أندرويد
  • لغة R
  • الذكاء الاصطناعي
  • صناعة الألعاب
  • سير العمل
    • Git
  • الأنظمة والأنظمة المدمجة

التصنيفات

  • تصميم تجربة المستخدم UX
  • تصميم واجهة المستخدم UI
  • الرسوميات
    • إنكسكيب
    • أدوبي إليستريتور
  • التصميم الجرافيكي
    • أدوبي فوتوشوب
    • أدوبي إن ديزاين
    • جيمب GIMP
    • كريتا Krita
  • التصميم ثلاثي الأبعاد
    • 3Ds Max
    • Blender
  • نصائح وإرشادات
  • مقالات تصميم عامة

التصنيفات

  • مقالات DevOps عامة
  • خوادم
    • الويب HTTP
    • البريد الإلكتروني
    • قواعد البيانات
    • DNS
    • Samba
  • الحوسبة السحابية
    • Docker
  • إدارة الإعدادات والنشر
    • Chef
    • Puppet
    • Ansible
  • لينكس
    • ريدهات (Red Hat)
  • خواديم ويندوز
  • FreeBSD
  • حماية
    • الجدران النارية
    • VPN
    • SSH
  • شبكات
    • سيسكو (Cisco)

التصنيفات

  • التسويق بالأداء
    • أدوات تحليل الزوار
  • تهيئة محركات البحث SEO
  • الشبكات الاجتماعية
  • التسويق بالبريد الالكتروني
  • التسويق الضمني
  • استسراع النمو
  • المبيعات
  • تجارب ونصائح
  • مبادئ علم التسويق

التصنيفات

  • مقالات عمل حر عامة
  • إدارة مالية
  • الإنتاجية
  • تجارب
  • مشاريع جانبية
  • التعامل مع العملاء
  • الحفاظ على الصحة
  • التسويق الذاتي
  • العمل الحر المهني
    • العمل بالترجمة
    • العمل كمساعد افتراضي
    • العمل بكتابة المحتوى

التصنيفات

  • الإنتاجية وسير العمل
    • مايكروسوفت أوفيس
    • ليبر أوفيس
    • جوجل درايف
    • شيربوينت
    • Evernote
    • Trello
  • تطبيقات الويب
    • ووردبريس
    • ماجنتو
    • بريستاشوب
    • أوبن كارت
    • دروبال
  • الترجمة بمساعدة الحاسوب
    • omegaT
    • memoQ
    • Trados
    • Memsource
  • برامج تخطيط موارد المؤسسات ERP
    • تطبيقات أودو odoo
  • أنظمة تشغيل الحواسيب والهواتف
    • ويندوز
    • لينكس
  • مقالات عامة

التصنيفات

  • آخر التحديثات

أسئلة وأجوبة

  • الأقسام
    • أسئلة البرمجة
    • أسئلة ريادة الأعمال
    • أسئلة العمل الحر
    • أسئلة التسويق والمبيعات
    • أسئلة التصميم
    • أسئلة DevOps
    • أسئلة البرامج والتطبيقات

التصنيفات

  • كتب ريادة الأعمال
  • كتب العمل الحر
  • كتب تسويق ومبيعات
  • كتب برمجة
  • كتب تصميم
  • كتب DevOps

ابحث في

ابحث عن


تاريخ الإنشاء

  • بداية

    نهاية


آخر تحديث

  • بداية

    نهاية


رشح النتائج حسب

تاريخ الانضمام

  • بداية

    نهاية


المجموعة


النبذة الشخصية

تم العثور على 11 نتائج

  1. يمكن أن تقوم SVG بأكثر بكثير من مجرد عرض الصور الثابتة، إذ تعد إمكانياتها الحركيّة واحدة من أكثر مميزاتها قوةً، مما يعطيها مزايا فريدة عن صيغ الصور الأخرى، وهي أحد الأسباب العديدة التي تجعل SVG أفضل من الصور النقطية، بما فيها GIF. ولكن هذا، بالطبع، ينطبق فقط على الصور التي تعد مرشحةً جيدةً لتكون SVG، مثل: table { width: 100%; } thead { vertical-align: middle; text-align: center; } td, th { border: 1px solid #dddddd; text-align: right; padding: 8px; text-align: inherit; } tr:nth-child(even) { background-color: #dddddd; } الشعارات، الصور غير المعقدة، المعتمدة على الأشعة، أدوات التحكم بواجهة المستخدم، الرسوم البيانية، والأيقونات. بالطبع، إذا كان لديك صورة أكثر ملاءمةً للصيغة النقطية – مثل الصور الفوتوغرافية أو الرسومات المعقدة جدًا المعتمدة على الأشعة (والتي من الطبيعي أن تكون كبيرة الحجم جدًا مثل صور SVG)، فعليك استخدام صيغة الصور النقطية بدلاً منها. لا يجب أن تكون الصورة مرشّحاً جيداً لـ SVG فقط، ولكن يجب أن يكون SVG مرشّحاً جيداً للصورة. فمثلًا، إذا كان حجم الصورة صغير جداً كصور PNG، يجب استخدام PNG، وتقديم إصدارات/معاملات دقة مختلفة للصورة باستخدام srcset أو <picture>، بالاعتماد على ما تعمل عليه وتحاول تحقيقه. عمومًا، الصور المذكورة أعلاه هي عادةً مرشّحات مثالية لـ SVG. وإذا كنت ستحرّك أيًا منها، فإنّ الطريقة المعقولة للقيام بذلك هي إنشاء صورك المتحركة عن طريق تحريك شيفرة SVG. ومع ذلك، في الأسبوع الماضي، ظهر رابطًا منبثقًا في يوميات حسابي على التويتر يشير إلى مجموعة من الأيقونات المتحركة كـ GIF. إنّ أول ما مرّ في ذهني عندما رأيتهم بأنّهم كانوا مرشحين مثاليين لـ SVG ويجب أن يتم إنشاؤهم كصور SVG، وليس صور GIF. في العديد من الحالات يمكنك استبدال صور GIF بصور SVG بالفعل، تمامًا كما يمكن أن تستبدلها بتنسيقات الصور النقطية الأخرى لمرشّحين مثل تلك المذكورة أعلاه. إنّ القدرة على تحريك صور SVG هي ما يمنحها هذه الميزة والقدرة. وهذا ينطبق على عناصر أكثر من الأيقونات المتحركة. لذا، لهذا السبب أعتقد أنّه يجب عليك استخدام SVG بدلًا من صور GIF كلما استطعت. جودة الصورة الميزة الأولى لاستخدام SVG بدلًا من GIF - أو أية صيغة صورة لهذه المسألة - هي - كما هو متوقع - ميزة SVG الأولى: استقلالية الدقة. ستبدو صورة SVG فائقة الوضوح عند أي دقة للشاشة، بغض النظر عن حجمها. في حين أن صور GIF - صيغة الصورة النقطية - لا تظهر كذلك. حاول تكبير الصفحة التي تحتوي على صورة GIF وشاهد كيف ستبدو صورة الـ GIF منقطة ومحتوياتها غير واضحة. مثلّا، يبدو تسجيل GIF التالي لحركة صورة SVG جيدًا بهذا الحجم الصغير: يؤدي تكبير الصفحة عدّة مرات إلى جعل الصورة غيرَ واضحةٍ وتصبح حواف ومنحنيات العناصر الداخلية مسننةً، كما تشاهد في الصورة أدناه: بينما إذا قمت بالتحقق من عرض SVG التجريبي وتكبير الصفحة، فإن محتوى SVG سيبقى واضحًا وصافيًا بغض النظر عن مقدار التكبير. لتوفر صورًا واضحةً للشاشات عالية الدقة عند استخدام صيغة صورة نقطية مثل GIF، تحتاج إلى استخدام <picture> أو srcset وتشغيل الصور بسياقات مختلفة. بالطبع، كلما زادت دقة الصورة، زاد حجم الملف. مع صور GIF، سيصل حجم الملف لحجمٍ كبير بشكلٍ هائل. لكننا سنصل إلى ذلك في غضون دقيقة، كذلك، فإنّ استخدام صور GIF عالي الدقة وعرضها بحجمٍ أصغر للهواتف المحمولة يعد أمرًا سيئًا بالنسبة للأداء، لذا لا تفعل ذلك. عندما تنشئ أيقونات أو صور GIF متحركة، أبعادها ثابتةٌ. غيّر الأبعاد أو كبّر وصغّر الصفحة، وستحصل على صورة غير واضحة. أمّا مع SVG، ستتخلص من مشكلة الحجم، وستحصل على وضوحٍ دائم. يمكنك إنشاء صور SVG صغيرة وتغيير أبعادها وفق احتياجاتك دون التضحية بوضوح الصورة. نتيجة صورة GIF صورة SVG متحركة GIF مثل تنسيقات الصور الأخرى تمامًا، غير مستقلة الدقة، ولذا ستبدو غير واضحة عند تغيير حجمها أو عرضها بدقة أعلى صورة SVG قابلة لتغيير الحجم ومستقلة الدقة، وستبدو واضحةً بأي دقة شاشة الألوان والشفافية ربما يكون السبب الأول لتبتعد عن التعامل مع صور GIF هو الطريقة التي يتعامل بها مع الشفافية، خاصةً عندما يتم عرض الصورة على خلفية غير الخلفية البيضاء. هذه مشكلة تظهر غالبًا عند استخدام أيقونات GIF (سواءً كانت متحركة أم لا)، عندما يتم إنشاء الأيقونات عادةً بخلفيات شفافة. مثلًا، فكر مليّا بالدائرة التالية المحاطة بحدّ، أُنشئت كصورة SVG (يسار) وGIF بخلفية شفافة (يمين). المشكلة واضحة بمجرد النظر إلى الصورتين: تحتوي دائرة GIF على حواف رمادية حول حدّها. إذا كنت لا تعاينها في المتصفح، فقد لا يكون التأثير مرئيًا لك لأنّه من الممكن ألا يتم تطبيق أنماط الشكل. فيما يلي لقطة توضح المشكلة (على اليمين): يحدث هذا لأن الشفافية في صور GIF ثنائية. هذا يعني أن كل بكسل إما يعمل أو لا يعمل؛ البكسل سيظهر إما شفافًا أو ممتلئًا بشكلٍ كامل. وهذا بدوره يعني أنّ الانتقال بين اللون الأمامي ولون الخلفية ليس سلسًا، والتشوهات الناتجة تظهر بسبب تردد العينات غير المناسب، والمعروفة باسم التعرج. عندما لا يكون الخط مستقيمًا تمامًا، فإنّه يتسبب بأن تكون بعض البكسلات (حول الحواف) شفافة جزئيًا وممتلئة جزئيًا ، لذلك يحتاج البرنامج إلى معرفة اللون الذي يجب استخدامه لهذه البكسلات. تأثير الهالة "ناتج عن كل البكسلات التي كانت ممتلئة أكثر من 50٪ امتلاءً كاملاً وتحمل لون الخلفية بدلاً من اللون الذي تم تنقيطه" كريس ليلي. لذلك يكون هذا التأثير عادةً ناتجًا عن تلوث البكسل من لون الخلفية التي تتكون الصورة على أساسه مقارنةً بما هي عليه عند إنشائها/حفظها في محرر الرسومات. عادةً ما يحاط التعرج بمكافح تعرج، ولكن هذا ليس بالأمر البسيط عندما تكون الشفافية ثنائية: حلّ هذه المشكلة هو الشفافية المتغيرة، والمعروفة باسم قناة ألفا، والتي تسمح بدرجات متفاوتة من الشفافية وبالتالي انتقالًا أكثرَ سلاسةٍ بين اللون الأمامي ولون الخلفية، وهذا غير متوفر في GIF؛ وبالتالي، هذا يسبب مشكلة تأثير الهالة. تظهر الصور ذات تأثير الهالة أفضل عادةً عند استخدامها مع خلفيات بيضاء؛ أي لون خلفية آخر عالي التباين سيجعلها تبدو مشوهةً. لست متأكدةً تمامًا مما إذا كانت هناك طريقة لحل هذه المشكلة، لكنني لم أجد بعد صورة GIF ذات خلفية شفافة وحواف منحنية لم تكن بها هذه المشكلة. لقد رأيت الأشكال المستطيلة تعاني منها أيضًا. إذا كنت ترغب في استخدام صورتك/أيقونتك على خلفية غير بيضاء - مثلًا، على خلفية تذييل داكنة، قد يكون هذا لوحده يبعدك عن التعامل مع GIF، ولكن هناك أسباب أخرى تجعل استخدام SVG أفضل من GIF أيضًا، والتي سنغطيها في الأقسام التالية. ملاحظة: إذا كنت تقرأ هذه المقالة باستخدام المتصفح ولكنك لا ترى الحواف في الصورة الأولى على شاشة أصغر، فحاول تكبير الصفحة لترى التأثير. لماذا من الممكن ألا تكون قادرًا على رؤية الحواف على أحجام أصغر؟ الإجابة هي: ينعّم المتصفح الحواف كجزءٍ من عملية تغيير حجم الصورة. هل هذا يعني أنّه يمكنك استخدام هذا للتخلص من الحواف والاستمرار باستخدام GIF؟ نعم تستطيع. ولكن للقيام بذلك، يجب عليك استخدام صور GIF بحجم أكبر بكثير من الحجم الذي تريد أن تكون الصورة به، ثم تغيير حجمها. هذا يعني أيضًا أنك ستعرض صورًا للمستخدمين أكبر بكثير مما يحتاجون إليه، وبالتالي استهلاك المزيد من النطاق الترددي على الهاتف المحمول، بالإضافة إلى الإضرار بالحجم العام للصفحة وأدائها. رجاءً لا تفعل ذلك. نتيجة صورة GIF صورة SVG متحركة صور GIF قادرة على الشفافية الثنائية فقط. يسبب هذا التشوهات، المعروفة باسم تأثير الهالة التي تظهر كلما تمّ استخدام الصورة أو الأيقونة مع خلفية غير بيضاء كلما كان تباين لون الخلفية مع الصورة أعلى، كان تأثير الهالة أكثر وضوحًا مما يجعل الأيقونات غير قابلة للاستخدام عمليًا. تأتي صور SVG مع قناة ألفا ولا تعاني من أيّة مشاكل عند استخدامها مع ألوان خلفية مختلفة. تقنيات الصور المتحركة وأداؤها يمكنك تحريك صور SVG باستخدام CSS أو جافاسكربت أو SMIL، وتمنحك كلٌّ منها مستوىً مختلفًا من التحكم يمكنك الاستفادة منه لإنشاء جميع أنواع الصور المتحركة على عناصر SVG. لا توجد "تقنيات" لتحريك صور GIF. يتم تحريكها من خلال عرض سلسلة من الصور - صورة لكل إطار - بشكلٍ تسلسلي، بأسلوبٍ ثابتٍ وسرعةٍ ثابتةٍ. تعلم أنّ هذه الطريقة التي تعمل بها صور GIF فقط. ومن المؤكد أنّه يمكنك الإبداع مع أيقوناتك قبل تحويلها إلى صور GIF ثم "تسجيل" الحركات وتحويلها إلى GIF، ولكن ما مدى جودة مظهرها؟ وما مدى السيطرة على وقت الحركة التي ستحصل عليها بعد ذلك؟ لا شيء. لن تبدو الحركة سلسةً ما لم تتأكد من أن لديك 60 إطارًا على الأقل - أي 60 صورة - في الثانية لإنشاء صورتك الـ GIF. بينما مع SVG، فإنّ الحصول على صورٍ متحركةٍ سلسةٍ أسهل وأبسط بكثير من خلال الاستفادة من تحسينات المتصفح. حجم صور GIF أكبر من حجم صور PNG أو JPEG، وكلما طالت مدة حركة صورتك، زاد حجمها. ماذا لو أردت الآن تشغيل صورتك المتحركة لمدة 5 إلى 6 دقائق على الأقل؟ ماذا لو أردت تشغيلها لفترة أطول؟ ستحصل على الصورة. لنلقِ نظرةً أكثر تحديدًا على مثالٍ بسيط. يوجد أدناه صورتان: صورة SVG متحركة على اليسار وصورة GIF متحركة على اليمين. يتغير لون المستطيل في كلتا الصورتين بفترة ست ثوانٍ. يوجد العديد من الأشياء لملاحظتها هنا: تبدو صور GIF المتحركة سلسةً، لكن إذا ألقيت نظرةً قريبةً ستلاحظ أنّ مستطيل SVG يمر بمجموعة أكبر من الألوان عندما ينتقل من اللون الأولي إلى اللون النهائي. عدد الألوان التي يمر بها GIF محدودًا بعدد الإطارات. في الصورة أعلاه، تمر صورة الـ GIF بـ 60 إطارًا، أي 60 لونًا، بينما يمر SVG عبر الطيف بأكمله بين ظل اللون الوردي المستخدم واللون الأخضر النهائي. بالنسبة لتكرار الصور المتحركة مثل هذه، من الأفضل عمومًا تجنب قفزة اللون الظاهرة في الصورة المتحركة أعلاه، وإنشاء الصورة المتحركة بحيث تنعكس ما إن تصل إلى اللون الأخضر؛ بهذه الطريقة، ستنتقل بسلاسة إلى اللون الوردي ثم تبدأ الجولة الثانية من الصورة المتحركة من هناك أيضًا، مع تجنب قفزة الألوان القبيحة. مع CSS، يمكنك عكس حركة الصورة باستخدام قيمة اتجاه الحركة alternate. ولكن مع GIF، ستحتاج إلى العمل على عدد إطاراتك وربما ينتهي بك الأمر إلى مضاعفتهم لتحقيق ذلك؛ سيؤدي هذا بالطبع إلى زيادة حجم الصورة أيضًا. أحجام الصورتين الظاهرتين في الأعلى: حجم صورة GIF هو 21.23 كيلوبايت حجم صورة SVG هو 0.355 كيلوبايت هذا ليس فرقًا بسيطًا. ولكننا نعلم جميعًا أنه يمكننا تحسين صورنا. لذلك دعونا نفعل ذلك. يؤدي تحسين SVG باستخدام واجهة المستخدم الرسومية SVGO بالسحب والإفلات إلى تقليل حجم ملف الـ SVG إلى 0.249 كيلوبايت. لتحسين صورة الـ GIF، يمكنك استخدام واحدة من العديد من أدوات تحسين GIF عبر الإنترنت. لقد استخدمت ezgif.com لتحسين الصورة أعلاه. (توجد أدوات أخرى أيضًا؛ مثل gifsicle.) انخفض حجم الملف إلى 19.91 كيلوبايت. هناك العديد من الخيارات التي يمكنك الاختيار من بينها عند تحسين صور GIF. قمت بتحسين الصورة أعلاه بحيث يبقى عدد الإطارات نفسه، باستخدام ضغط Lossy GIF، الذي "يمكن أن يقلل من حجم ملف GIF المتحرك بنسبة 30 ٪ - 50 ٪ بتكلفة بعض التدرج / التشويش". يمكنك أيضًا تحسينها عن طريق إزالة كل إطار ذو الرقم n؛ مما يمكن أن يقلل من حجم الملف إلى أبعد حد، ولكن على حساب حركة الصورة التي لم تعد سلسةً بعد الآن. وفي حالة الصور المتحركة مثل الحالة المدروسة الآن، فإن إزالة الإطارات سيجعل التغيير في اللون "سريعًا" وملاحظًا. تتوفر أيضًا خيارات أخرى للتحسين مثل تقليل الألوان (الذي لن يكون مناسبًا للصور المتحركة المعتمدة على الألوان هنا) وخفض الشفافية. يمكنك معرفة المزيد حول هذه الخيارات في صفحة التحسين في موقع ezgif.com. للتلخيص: إذا كنت أردت أن تكون صورك الـ GIF المتحركة سلسةً، ستحتاج إلى المزيد من الإطارات في الثانية، وسيؤدي ذلك بالتالي إلى زيادة حجم الملف كثيرًا. بينما مع SVG، من المحتمل أن تحتفظ بحجم ملف أصغر بكثير. المثال أعلاه صغيرٌ، وأنا متأكد من وجود أمثلة أفضل، ولكني أردت أن يوضح المثال البسيط الفرق بين الصيغتين. حتى إذا كنت تحرّك المستطيل أعلاه باستخدام جافاسكربت أو حتى إطار عمل جافاسكربت — نظرًا لأن الصور المتحركة SVG لا تعمل في متصفح IE، مثلًا، من المحتمل أن يكون حجم ملف إطار العمل المقترن بحجم SVG أصغر أو يساوي على الأقل حجم صورة GIF. مثلًا، باستخدام GreenSock’s TweenLite، سيكون حجم SVG مع المكتبة المدمجة أقل من 13 كيلو بايت (والذي لا يزال أقل من حجم GIF)، إذ انّ حجم TweenLite المصغر هو 12 كيلو بايت. إذا انتهى بك الأمر إلى حجمٍ مساوٍ لحجم GIF، فإن الفوائد الأخرى لـ SVG ستزيد من الحجم وستحصل على المزيد منه. توجد بعض مكتبات جافاسكربت الأخرى التي تركز على مهام حركة معينة في وقت واحد، وتأتي بأحجام ملفات صغيرة بشكلٍ ممتاز (أصغر من 5 كيلوبايت)، مثل Segment التي تستخدم لتحريك مسارات SVG لإنشاء تأثيرات رسم خطية. حجم Segment المصغر هو 2.72 كيلو بايت. هذا ليس سيئًا للغاية، أليس كذلك؟ يمكن أن يكون هناك استثناءات، لذلك يجب عليك دائمًا الاختبار. ولكن بالنظر إلى طبيعة صور GIF وكيفية عملها، فمن المحتمل أن تجد أن SVG يُعدُّ خيارًا أفضل في معظم الحالات. ملاحظة: أداء SVG ليس في أفضل حالاته اليوم، ولكن نأمل أن يتغير هذا في المستقبل. توفر متصفحات IE/MS Edge أفضل أداء لعرض SVG بين جميع المتصفحات اليوم. على الرغم من ذلك، ستظل صور SVG المتحركة تبدو أفضل من صور GIF المتحركة، خاصةً عند التعامل مع الصور ذات الحركة الطويلة، لأنّ حجم ملف GIF - بافتراض تسجيلها بمعدل 60 إطارًا في الثانية - سيكون له تأثيرًا سلبيًا على الأداء العام للصفحة. تقدم المكتبات مثل GreenSock أداءً رائعًا أيضًا. نتيجة صورة GIF صورة SVG متحركة - صور GIF أكبر حجمًا عمومًا من صور SVG. حركة الصورة الأكثر تعقيدًا والأطول مدةً، تتطلّب عدد إطارات أكبر لإنشائها ولهذا يكون حجم الملف أكبر ويؤثر سلبًا على الأداء - ما لم تعمل حركة الصورة بمعدل 60 إطارًا في الثانية، فإنّ الحركة ستصبح مسننة وغير سلسة. أيضًا زيادة عدد الإطارات في الثانية سيؤدي إلى زيادة حجم الملف خاصةً للحركات الطويلة نتيجة: سيكون هناك حل بسيط يجب القيام به. إمّا أن تكون حركة صورة GIF ناعمة وسيتأثر الأداء وحجم الملف الكلي وحجم الصفحة بشكلٍ سلبي، أو ستعاني الصورة المتحركة GIF من إطارات أقل. سيتم المخاطرة بأحد أشكال الأداء في كلا الحالتين تستفيد صور SVG من تحسينات المتصفح عند تحريك العناصر. على الرغم من أنّ أداء المتصفح على عناصر SVG لا تزال في أفضل حالاتها، إلا أنّ الصور المتحركة ستبقى تعمل بشكلٍ جيد بدون الحاجة لتقديم تنازلات في أداء الصفحة لا يزال حجم ملف SVG معقولًا جدًا، إن لم يكن صغيرًا جدًا، مقارنةً بـ GIF، حتى عندما قد نحتاج إلى مكتبات معينة للصور المتحركة لإنشاء صور متحركة عابرة للمتصفحات إصلاح وتعديل الصور المتحركة إنّه من المحزن أن تستخدم صور GIF. ستحتاج إلى استخدام محرر رسومات مثل Photoshop أو Illustrator أو After Effects، على سبيل المثال لا الحصر. وإذا كنت مثلي، فلن يكون محرر الرسومات المكان الذي تصقل فيه مهاراتك، وستشعر أكثر أنّك في مكانك الصحيح أكثر عند إجراء تعديلات في الشيفرة، وليس في برامج تحرير الرسومات. ما الذي يحدث إذا كنت ترغب في تغيير توقيت صورتك المتحركة؟ أو إذا كنت تريد تغيير وظائف التوقيت لعنصرٍ واحدٍ أو عدة عناصر داخل صورتك؟ أو إذا كنت ترغب في تغيير الاتجاه الذي يتحرك فيه عنصرٍ ما؟ ماذا لو كنت تريد تغيير التأثير بالكامل وجعل العناصر في صورتك تفعل شيئًا مختلفًا تمامًا؟ ستحتاج إلى إعادة إنشاء الصورة أو الأيقونة مرةً أخرى. يتطلب منك أي تغيير الانتقال إلى محرر الرسومات والعمل مع الإطارات وواجهة المستخدم المعتمدة على الإطار. سيكون ذلك بمثابة تعذيب للمطورين، ومهمةً مستحيلةً لأولئك الذين لا يعرفون طريقتنا بالتعامل مع هذه المحررات بشكلٍ كافٍ لإجراء هذه التغييرات. مع SVG، فإن إجراء أي نوع من التغيير على الصورة المتحركة (الصور المتحركة) لا يُعدُّ سوى بضعة أسطر من الشيفرة. نتيجة (من وجهة نظر المطور) صورة GIF صورة SVG متحركة إصلاح وتعديل الصور المتحركة GIF يتطلّب إعادة إنشاء الصورة أو اللجوء إلى واجهة المستخدم في محرر الرسومات المعتمد على الإطارات للقيام بذلك، ويعدّ هذا مشكلة للمطورين في مواجهة التصميم عادةً، يمكن أن تتغير صور SVG ويتم التحكم بها بشكلٍ صحيح داخل شيفرة SVG - أو في أي مكان تم تعريف الصور المتحركة به، باستخدام عدة سطور من الشيفرة. حجم الملف، ووقت تحميل الصفحة والأداء في القسم السابق، ركزنا على أداء الصور المتحركة نفسها. في هذا المثال، أريد إلقاء بعض الضوء على أداء الصفحة ككل وكيفية تأثرها باختيار صيغة الصورة الذي تقوم به. في الحقيقة: كلما زاد حجم الملف، زاد التأثير السلبي على وقت تحميل الصفحة والأداء. بأخذ ذلك بالحسبان، لنرى كيف يمكن أن يساعد استخدام SVG بدلاً من GIF في تحسين إجمالي وقت تحميل الصفحة من خلال النظر إلى مثالٍ أكثر واقعيةٍ وعمليةٍ. في حديثي الأول عن SVG، منذ 18 شهرًا، ذكرت كيف يمكن استخدام SVG لاستبدال صور GIF المتحركة وكيف تؤدي إلى تحسين أداء الصفحة بشكلٍ عام. في ذلك الحديث، قدمت مثالًا واقعيًا لصفحة ويب واقعية استفادت مما توفره SVG وحصلت على الفوائد: الصفحة الرئيسية لـ Sprout. تحتوي صفحة الرئيسية لـ Sprout على صورتين متحركتين تم إنشاؤهما في البداية وعرضهما بشكل صور GIF. قبل عامين، كتب Mike Fortress مقالًا في مدونة Oak، يوضح فيه كيف قاموا بإعادة إنشاء صور GIF متحركة، خاصةً مخطط GIF (انظر الصورة أدناه) كصورة SVG متحركة. يشارك Mike في مقالته بعض الأفكار المثيرة للاهتمام حول أدائهم الجديد للصفحة كنتيجةٍ للتغيير إلى SVG: إنّه بالفعل فرقٌ كبيرً. مخطط Sprout هو المرشّح المثالي لـ SVG. لا يوجد سبب لتحريكها عن طريق تحويل الصور المتحركة إلى تسجيل GIF، عندما يمكن لـ SVG أن تحقق الكثير من الفوائد. يدرك Jake Archibald قوة صور SVG المتحركة أيضًا ، ويستخدمها لإنشاء الرسوم التوضيحية التفاعلية وتحريكها لاستكمال مقالاته. مقاله كتاب الطبخ دون اتصال يعتبر مثالًا ممتازًا (وبالمناسبة مقالًا ممتازًا). هل كان بإمكانه استخدام صور GIF للقيام بذلك؟ بالتأكيد. ولكن بالنظر إلى عدد الصور التي استخدمها، كان من الممكن أن تزيد صور GIF بسهولة الحجم الكلي للصفحة إلى 2 ميغابايت أو أكثر، بحيث يكون حجم كل GIF على الأقل مئات الكيلوبايت؛ في حين أن صفحة الويب بأكملها تبلغ حاليًا 128 كيلو بايت فقط مع جميع صور SVG المضمنة داخليًا، لأنّه يمكنك إعادة استخدام العناصر في SVG، لذا فإن أيّة عناصر متكررة لن تتسبب فقط في أن الصفحة بأكملها ستستعمل برنامج gzip كثيرًا، ولكن لكل صفحة سيصبح الحجم الكلي لصور SVG أصغر. الآن هذا رائع! سأبقي حالتي حول تحميل الصفحة والأداء هنا. ولكن لا يزال من المهم الإشارة إلى أنّه يمكن أن يكون هناك استثناءات. مرةً أخرى، في معظم الحالات، من المحتمل أن تجد أن SVG أفضل من GIF، لكنك ستحتاج دائمًا إلى الاختبار على أي حال. نتيجة صورة GIF صورة SVG متحركة صور GIF أكبر حجمًا بشكلٍ عامٍ من صور SVG مع الحركات المضافة لهم. وهذا يؤثر سلبًا على حجم الصفحة الكلّي ووقت التحميل والأداء. يمكن أن تُستعمل صور SVG وأن يُعاد استخدامها، مما يجعل حجم الملف أصغر عمومًا من GIF وهذا يحسّن من وقت تحميل الصفحة والأداء دعم المتصفح ربما تكون الميزة الوحيدة المتفوقة لصور GIF على صور SVG هي دعم المتصفح. تعمل صور GIF إلى حدٍ كبير في كل مكان، في حين أن دعم SVG أقل انتشارًا. على الرغم من أن لدينا العديد من الطرق لتوفير النسخ الاحتياطية للمتصفحات غير الداعمة - ويجب ألا يعوق دعم المتصفح الحالي أي شخص عن استخدام SVG، إنّ الصور الاحتياطية، إذا تم توفيرها كـ PNG أو JPG، ستكون ثابتة وبدون حركة. بالطبع ، يمكنك دائمًا تقديم GIF كخطوة احتياطية لـ SVG، ولكن يجب مراعاة الاعتبارات والعيوب المذكورة سابقًا. نتيجة صورة GIF صورة SVG متحركة تعمل صور GIF تقريبًا في كل مكان صور SVG يدعمها عدد أقل من المتصفحات، لكنها تأتي مع طرق كثيرة لتوفير صور احتياطية للمتصفحات التي لا تدعمها مخاوف سهولة الوصول (a11y#) انقل شيئًا ما إلى صفحة، أو أيّ مكان، لهذه القضية، لقد أضفت للتو تسليةً - شيءٌ ما من المؤكد أنّه سيجذب انتباه المستخدم بمجرد أن يبدأ التحرك. هكذا يعمل الدماغ البشري ببساطة. يعدُّ هذا أيضًا أحد الأسباب التي تركز عليها لافتات الإعلانات - وهي مبنية على - تركيزٍ قوي على الصور المتحركة. وهذا هو السبب في أنّ لافتات الإعلانات المتحركة مزعجةٌ للغاية. إنها تشتت الانتباه، خاصةً عندما تحاول أداء مهمة على صفحة تتطلب اهتمامك بالكامل، مثل قراءة مقال. تخيّل الآن صفحة بها مجموعة من الأيقونات المتحركة (أو الصور) التي لن تتوقف عن الحركة بغض النظر عما تفعله. لم نعد نتحدث عن صورة أو صورتين على الصفحة الرئيسية أو داخل مقالة هنا؛ نحن نتحدث عن متحكمات وعناصر واجهة المستخدم، والأيقونات الأصغر التي من المحتمل أن تكون موجودة في أماكن متعددة على الصفحة، وعلى صفحات متعددة. ما لم يكن من المفترض أن تكون الأيقونة عبارة عن رسوم متحركة بشكلٍ غير محدود - مثلًا، إذا كانت عبارة عن دوران متحرك أثناء مرحلة انتظار غير نشطة للمستخدم، فمن المحتمل أن تسبب مشكلة، وتصبح مصدر إزعاجٍ أكثر من كونها "شيئًا جميلًا". في الواقع، يمكن أن يصبح الأمر أكثر إزعاجًا لبعض الناس، لأن الحركة المستمرة يمكن أن تجعل بعض الناس حرفيًا يشعرون بالمرض. تناقش المصممة ومستشارة صور الويب المتحركة Val Head في مقالتها "تصميم رسوم متحركة للويب أكثر أمانًا من أجل حساسية الحركة" تأثيرات الصور المتحركة المفرطة الاستخدام في الويب على الأشخاص الذين يعانون من اضطرابات الدهليزية المتسببة بصريًا (منجم التركيز): تخيّل الآن ما إذا كانت الصور المتحركة لا تنتهي … مضاعفات مزدوجة. تشرح مقالة Val المشكلة بمزيدٍ من التفصيل، حيث تجمع ردود فعل من شخصين يواجهان هذه المشاكل بالفعل ويشاركان تجربتهما مع الصور المتحركة بأمثلةٍ مختلفةٍ. أحد الحلول التي يمكن أن تساعد في تجنب هذه المشاكل هو تزويد المستخدم بالقدرة على التحكم في الصور المتحركة حتى يتمكنوا من إيقافها عندما تصبح مزعجةً. يمكنك القيام بذلك باستخدام SVG. يمكنك التحكم بشكلٍ كاملٍ في الصور المتحركة وتشغيلها مرةً واحدة أو مرتين عند تحميل الصفحة - إذا كنت تحتاج حقًا إلى تشغيلها بمجرد قيام المستخدم "بالدخول" إلى صفحتك، ثم إظهارها عند تمرير مؤشر الفأرة لمرات متتالية، باستخدام سطورٍ قليلةٍ من الـ CSS أو جافاسكربت. لا تحتاج إلى المئات أو الآلاف من أسطر CSS أو جافاسكربت لإنشاء صورةٍ متحركةٍ للأيقونة، إلا إذا كانت أيقونتك مشهدًا معقدًا بالفعل فيها الكثير من المكونات المتحركة. لكنني أعتقد أنّه في هذه الحالة، لم تعد تمثل "أيقونةً" بعد الآن، وأنّها أصبحت عبارةً عن صورةٍ عاديةٍ أكثر. يمكنك الوصول إلى أقصى قدر من التحكم في إعادة التشغيل، والسرعة لكل تشغيلٍ لاحقٍ، وأكثر من ذلك بكثير، بفرض، بالطبع، أنّك تستخدم جافاسكربت للحصول على هذا المستوى من التحكم. أو يمكنك إضافة تبديل لمنح المستخدم القدرة على إيقاف تشغيل الصور المتحركة بلا حدود. لا يمكنك فعل ذلك باستخدام GIF … إلا إذا اخترت استبدال GIF بصورة ثابتة عند إجراء تبديلٍ معينٍ. قد يجادل البعض بأنّه يمكنك عرض نسخة ثابتة من الصورة – مثل صورة PNG مثلًا، ثم توفير إصدار GIF عند تمرير مؤشر الفأرة. ولكن هذا يسبب بعض المشاكل: إذا كانت الصورَ مضمنةٌ، فستحتاج إلى استبدال هذه الصور باستخدام جافاسكربت. هذا الإجراء لا يتطلب أي جافا سكربت إذا كنت تستخدم SVG. إذا كانت الصور عبارة عن صور أمامية (مضمنة في HTML باستخدام <img>)، وتحتاج إلى استبدال هذه الصور، فسينتهي بك الأمر إلى مضاعفة كمية طلبات HTTP لكلّ صورة. وإذا كانت صور الخلفية مضمنة في صفحة الأنماط (هذا غير مستحسن)، فإنّ الصور (خاصةً صور GIF) ستزيد حجم صفحة الأنماط وبالتالي تزيد الوقت الإجمالي لحظر عرض الصفحة. إذا كنت تبدّل/ عندما تبدّل مصادر الصورة عند تمرير مؤشر الفأرة، فهناك وميض ملحوظ بين الصورة الأولى والثانية في الاتصالات البطيئة. اتصالي بطيء؛ أحيانًا اتصال 3G بطيء، ولم أتذكر بعد وقتًا تم فيه استبدال صورة بأخرى عند تمرير مؤشر الفأرة، أو تم تغيير حجم منفذ العرض، أو أي شيء آخر، ولم أشاهد هذا الوميض. يزداد هذا الموقف سوءًا عندما تكون الصورة الثانية (GIF التي تحمّل عند تمرير مؤشر الفأرة) كبيرة الحجم إلى حدٍ ما — سيكون هناك وميض، تتبعه صورةً متحركةٌ بطيئةٌ غير متقنةٍ لـ GIF أثناء تحميلها بالكامل. هذا ليس جذابًا أبدًا. لذا، نعم، يمكنك تبديل مصادر الصورة للتحكم إذا أو عندما تشتغل الصور المتحركة GIF أو متى يتم ذلك، لكنك تفقد التحكم الدقيق في GIF وتؤثر على تجربة المستخدم مع واجهة المستخدم. يمكنك أيضًا التحكم في عدد المرات التي يتم فيها تشغيل الصور المتحركة في GIF - وهو أمرٌ رائعٌ، لكن هذا يعني أن الصور المتحركة ستعمل فقط عددًا محددًا من المرات. ثم لإعادة تشغيل الصور المتحركة عند تفاعل المستخدم، ستحتاج إلى اللجوء إلى الأسلوب أعلاه مع صور متعددة. يمكن تحقيق الصور المتعددة التي تحتاج إلى إصلاح، وطلبات HTTP المتعددة، والحل العام المُستهلَك غير الأمثل بصورة SVG واحدة. ضمّن صورة SVG واحدة على الصفحة. أنشئ الصورة المتحركة بالطريقة التي تريدها/تحتاجها. (أو أنشئ الحركة قبل تضمين الصورة.) شغّل وأوقف وتحكّم بالصورة المتحركة. وأمنح المستخدم القدرة على التحكم فيها أيضًا. لا توجد طلبات HTTP إضافية لكل صورة، ولا صيانة معقدة للخط الزمني للصورة المتحركة في محرر الرسومات، ولا توجد أي مخاوف تتعلق بسهولة الوصول أو مشاكل لا يمكن تجنبها ببضعة سطور من التعليمات البرمجية. نتيجة صورة GIF صورة SVG متحركة صور GIF لا يمكن إيقافها من قبل المستخدم بدون طلب صور إضافية وطلبات HTTP إضافية. لا تتم السيطرة بشكلٍ كاملٍ حتى يتم ذلك يمكن تخصيص صور SVG المتحركة بشكلٍ كامل لذا يمكن تفعيلهم وتعطيلهم والتحكم بهم من قبل المستخدم بدون الحاجة إلى طرق مستهلَكة سهولة الوصول إلى المحتوى صورة GIF صورة SVG متحركة صور GIF سهلة الوصول مثل صور PNG وJPEG باستخدام قيمة الخاصية `alt` لوصفهم. لا يمكن تمييز المحتوى الموجود داخل الصورة أو إتاحته مباشرةً لقارئات الشاشة بما يتجاوز الوصف العام للصورة يمكن الوصول إلى صور SVG ودلالتها. يمكن أيضًا وصف المحتوى المتحرك داخل الصورة وجعله قابلًا للقراءة من قِبل قارئات الشاشة باستخدام عناصر سهولة الوصول المدمجة في SVG، كما يمكن تحسينها باستخدام أدوار ARIA وخاصيّاتها أيضًا. (يمكنك أن تقرأ [هنا](https://www.sitepoint.com/tips-accessible-svg/) كل شيء عن جعل SVG قابلة للوصول) التفاعل لا يوجد الكثير لإضافته هنا، ولكن الحقيقة أنّه يمكنك التفاعل مع العناصر الفردية داخل SVG، أثناء أو قبل أو بعد تحريك الصورة، لكن هذا غير ممكن مع GIF. لذا، إذا كنت تستخدم GIF، فستفقد القدرة على فعل أي شيء يتجاوز تشغيل الصور المتحركة أو إيقافها، وحتى هذا لم يتم تنفيذه فعلاً باستخدام الـ SVG، كما رأينا، ولكن يتم تحقيق ذلك عن طريق مبادلة GIF بالخارج ببديلٍ ثابت. حتى تغيير ألوان العناصر داخل GIF سيتطلب صورًا إضافية للقيام بذلك. هذه ميزة أخرى لاستخدام SVG بدلاً من GIF. نتيجة صورة GIF صورة SVG متحركة لا يمكن أن تكون الحركات المحددة في صور GIF تفاعلية، لا يمكنك التفاعل مع العناصر الفردية داخل عنصر GIF، ولا يمكنك إنشاء روابط خارج العناصر الفردية أيضًا. محتوى SVG تفاعلي بالكامل. يمكنك إنشاء التفاعلات مثل تمرير ماوس الفأرة والضغط (والمزيد) التي تستجيب لها العناصر الفردية داخل صورة SVG. استجابة وتكيّف الصور المتحركة إنّ القدرة على تحريك صورة SVG مباشرةً من الشيفرة، بالإضافة إلى معالجة العديد من خاصياتها، تعطي وتضيف ميزةً أخرى على الصور المتحركة المعتمدة على GIF: القدرة على إنشاء صور متحركة جيدة الأداء، سريعة الاستجابة وقابلة للتكيّف، دون إضافة أي طلبات HTTP إضافية باستخدام بضعة أسطر من الشيفرة وبأحجام ملفات أصغر. كتبت سارة دراسنر مقالةً في مجلة Smashing Magazine تُظهر طرقًا مختلفة لتحريك SVG sprites. تتمثل إحدى هذه الطرق في وجود "مشاهد" متعددة داخل الـ SVG، وتحريكها باستخدام CSS، ثم تغيير "عرض" الـ SVG - عن طريق تغيير قيمة خاصية الـ viewBox - لإظهار مشهدٍ واحدٍ في وقتٍ واحدٍ، اعتمادًا على حجم منفذ العرض الحالي ومساحة الشاشة المتاحة. إذا كنت ترغب في إنشاء نفس الحركات باستخدام صور GIF، فستفقد إمكانيات التحكم في الصور المتحركة، كما ستحتاج إلى صور متعددة ربما تكون أكبر (في حجم الملف) من صورة الـ SVG الواحدة. ولكن إذا كنت لا ترغب في استخدام شيفرة SVG المتحركة، فيمكنك دائمًا إنشاء SVG sprite وتحريكه بالطريقة التي يمكنك بها تحريك أي صيغة صورة آخرى - باستخدام ()steps وعدة أسطر CSS. تتحدث سارة أيضًا عن هذه التقنية في مقالتها. لا يحتاج تحريك صور SVG أن يكون معقدًا، وهو يقدم أداءً أفضل بشكلٍ عام. نتيجة صورة GIF صورة SVG متحركة بما أنّه لا يمكن التحكم بالمحتوى داخل صورة GIF بالشيفرة، فلا يمكن جعل الصور المتحركة تتكيف أو تستجيب لتغيّرات منفذ العرض أو السياق بدون اللجوء إلى فصل الصور. بما أنّه يمكن تحريك محتوى SVG بشكلٍ مباشر باستخدام الشيفرة، فإنّه يمكن تعديل المحتوى والحركات بحيث يستجيب و/أو يتكيّف مع سياقات وأحجام منافذ عرض مختلفة، بدون الحاجة إلى اللجوء إلى أي أصول إضافية. كلمات أخيرة تتمتع صور GIF بدعم جيد جدًا للمتصفح، نعم، ولكن مزايا صور SVG تفوق مزاياها في جميع الجوانب تقريبًا. قد تكون هناك استثناءات، وفي هذه الحالات، تستخدم صور GIF بالتأكيد أو أي صيغة صور آخرى تقدم عملًا أفضل من SVG. قد تستخدم حتى فيديو أو HTML5 Canvas أو أيًا كان. يمكن أن توفر SVG الكثير من مزايا الأداء إلى القائمة عند موازنتها مع صيغ الصور الأخرى، وخاصةً GIF. وبالتالي، وبالنظر إلى كل ما سبق، أوصي بأنه في أي مكان يمكن استخدام SVG للصور المتحركة، يجب تجنّب استخدام صور GIF. أنت حر بالطبع في تجاهل توصيتي لكنك ستتخلى عن المزايا الكثيرة التي توفرها صور SVG المتحركة. ما لم توفر صور GIF الكثير من المزايا على صور SVG التي لا تحقق دعم المتصفح IE8 وأقل منه، فإنني أعتقد أن صور SVG ينبغي أن تكون هي السبيل للانطلاق. بعض المصادر لمساعدتك على البدء مع صور SVG المتحركة: عالم الصور المتحركة SVG. عدة طرق مختلفة لاستخدام SVG sprites في الصور المتحركة. إنشاء الصور المتحركة مع SVG. لدى GreenSock مجموعة من المقالات المفيدة حول تحريك SVG. Snap.svg ويُعرف أيضًا بأنّه "مكتبة jQuery للـ SVG". الصور المتحركة SVG باستخدام CSS وSnap.SVG. تصميم وتحريك صور SVG مع CSS. رسم خط متحرك في SVG. أرجو أن تكون قد وجدت هذه المقالة مفيدةً. شكرًا للقراءة. ترجمة -وبتصرف- للمقال Animated SVG vs GIF [CAGEMATCH]‎ لصاحبته Sara Soueidan
  2. يمكن استخدام لغة الأنماط الانسيابية CSS في إنشاء رسوم متحركة بسيطة، دون الحاجة إلى شيفرة JavaScript إطلاقًا، لكن يمكننا بالطبع استخدام JavaScript للتحكم برسوم CSS المتحركة وجعلها أفضل بكتابة القليل من الشيفرة. الحركة الانتقالية في CSS إنّ فكرة الحركة الانتقالية transition في CSS بسيطة جدًا، حيث نصف خاصيةً محددةً وآليةً لإظهار التغيرات فيها على شكل رسوم متحركة، فعندما تتغير قيمة الخاصية سيُظهر المتصفح هذا التغيير في حركة، وبالتالي كل ما علينا فعله هو تغيير الخاصية، وسينفذ المتصفح دفقًا من التغيرات المتتالية فيها. تُحرّك شيفرة CSS التغييرات في الخاصية background-color لمدة ثلاث ثوان: .animated { transition-property: background-color; transition-duration: 3s; } فلو كان لأي عنصر الصنف CSS الذي سميناه animated، فستظهر أي تغيرات على الخاصية background-color في هذا العنصر في حركة لمدة 3 ثوان. انقر على الزر الذي ستُظهره الشيفرة التالية لتحريك الخلفية: <button id="color">Click me</button> <style> #color { transition-property: background-color; transition-duration: 3s; } </style> <script> color.onclick = function() { this.style.backgroundColor = 'red'; }; </script> See the Pen JS-P3-03-Fetch-Download-progress-ex8 by Hsoub (@Hsoub) on CodePen. توصف الحركة الانتقالية في CSS بأربعة خصائص، هي: transition-property. transition-duration. transition-timing-function. transition-delay. سنشرح هذه الخصائص بعد قليل، لكن دعونا نلاحظ أنّ الخاصية transition ستسمح بالتصريح عن الخصائص الأربعة السابقة معًا وفق الترتيب التالي:property duration timing-function delay، بالإضافة إلى قدرتها على إظهار الحركة الانتقالية على عدة خصائص معًا. يُظهر النقر على الزر في الشيفرة التالية الحركة الانتقالية للخاصيتين color وfont-size: <button id="growing">Click me</button> <style> #growing { transition: font-size 3s, color 2s; } </style> <script> growing.onclick = function() { this.style.fontSize = '36px'; this.style.color = 'red'; }; </script> See the Pen JS-P3-05-CSS-animations-ex2 by Hsoub (@Hsoub) on CodePen. سنشرح الآن خصائص الحركة الانتقالية. الخاصية transition-property نكتب ضمن هذه الخاصية قائمةً بخصائص CSS التي نريد إظهار تغييراتها على شكل حركة انتقالية، مثل left وmargin-left وheight وcolor وغيرها، أو يمكن أن نختار all التي تعني تحريك كل الخصائص . توجد خصائص لا يمكن تحريكها، لكن معظم الخصائص شائعة الاستعمال وقابلة للتحريك. الخاصية transition-duration يمكن أن نحدد في هذه الخاصية المدة التي ستجري فيها الحركة الانتقالية، وينبغي أن يكون التوقيت بتنسيق CSS ومقدرًا بالثانية s أو بالميلي ثانية ms. الخاصية transition-delay نحدد في هذه الخاصية فترة الانتظار قبل عرض الحركة الانتقالية، فلو كانت قيمتها ثانيةً واحدةً وقيمة الخاصية transition-duration ثانيتن، فستُعرض الحركة الانتقالية بعد ثانية من تغيّر الخاصيّة، وستستمر لمدة ثانيتين، كما يمكن استخدام قيم سالبة أيضًا، وعندها ستبدأ الحركة مباشرةً، إلا أنّ نقطة البداية ستنسحب قليلًا، فلو كانت قيمة الخاصية transition-delay هي "-1" ثانية وقيمة الخاصية transition-duration هي "2" ثانية، فستبدأ الحركة من المنتصف، ولمدة ثانية واحدة. لاحظ تغير الأعداد من 0 إلى 9 في الرسم المتحرك التالي باستخدام الخاصية translate في CSS: شيفرة الملف script.js: stripe.onclick = function() { stripe.classList.add('animate'); }; شيفرة الملف style.css: #digit { width: .5em; overflow: hidden; font: 32px monospace; cursor: pointer; } #stripe { display: inline-block } #stripe.animate { transform: translate(-90%); transition-property: transform; transition-duration: 9s; transition-timing-function: linear; } شيفرة الملف index.html: <!doctype html> <html> <head> <meta charset="UTF-8"> <link rel="stylesheet" href="style.css"> </head> <body> Click below to animate: <div id="digit"><div id="stripe">0123456789</div></div> <script src="script.js"></script> </body> </html> وستكون النتيجة: تجري الحركة الانتقالية للخاصية transform بالشكل التالي: #stripe.animate { transform: translate(-90%); transition-property: transform; transition-duration: 9s; } تضيف شيفرة JavaScript السابقة الصنف animate إلى العنصر، وتبدأ الحركة عند تنفيذ الأمر: stripe.classList.add('animate'); يمكن أن نبدأ التحريك انطلاقًا من نقطة ما من الحركة الانتقالية، أي من رقم محدد -وقد يكون متعلقًا بالثانية الحالية مثلًا- وباستخدام قيمة سالبة للخاصية transition-delay. لو نقرت على الرقم في المثال التالي، فستبدأ الحركة من الثانية الحالية: شيفرة الملف script.js: stripe.onclick = function() { let sec = new Date().getSeconds() % 10; stripe.style.transitionDelay = '-' + sec + 's'; stripe.classList.add('animate'); }; شيفرة الملف style.css: #digit { width: .5em; overflow: hidden; font: 32px monospace; cursor: pointer; } #stripe { display: inline-block } #stripe.animate { transform: translate(-90%); transition-property: transform; transition-duration: 9s; transition-timing-function: linear; } شيفرة الملف index.html: <!doctype html> <html> <head> <meta charset="UTF-8"> <link rel="stylesheet" href="style.css"> </head> <body> Click below to animate: <div id="digit"><div id="stripe">0123456789</div></div> <script src="script.js"></script> </body> </html> وستكون النتيجة: يمكن تنفيذ ذلك باستخدام JavaScript لكن بإضافة سطر آخر من الشيفرة: stripe.onclick = function() { let sec = new Date().getSeconds() % 10; // مثلًا تعني القيمة -3 هنا أن الحركة ستبدأ من الثانية الثالثة stripe.style.transitionDelay = '-' + sec + 's'; stripe.classList.add('animate'); }; الخاصية transition-timing-function تصف دالة التوقيت هذه كيفية توزيع الحركة الانتقالية أثناء فترة العرض، كأن تبدأ ببطء ثم تسرع، أو العكس. ستبدو هذه الخاصية في البداية معقدة، لكنها ستغدو بسيطةً إذا فهمناها، كما ستقبل نوعين من القيم هما منحني بيزيه Bezier curve، أو الدالة steps، لنبدأ مع المنحني كونه الأكثر استخدامًا. منحني بيزيه يمكن إعداد منحنى بيزيه بأربعة نقاط حاكمة تحقق الشروط التالية: إحداثيات النقطة الأولى (0,0). إحداثيات النقطة الأخيرة (1,1). ينبغي أن يكون الإحداثي x لنقطتي المنتصف بين 0 و1، بينما يمكن أن نختار أي قيمة للإحداثي y. إن صيغة منحني بيزيه هي: (cubic-bezier(x2, y2, x3, y3، إذًا علينا فقط أن نحدد النقطتين الحاكمتين الثانية والثالثة، لأنّ الأولى والأخيرة ثابتتان. تحدد دالة التوقيت سرعة تحريك عملية تشكيل المنحني: يمثل المحور x محور الزمن الذي يبدأ بالنقطة "0"، وينتهي بالنقطة "1" لقيمة transition-duration. يمثل المحور y مقدار اكتمال العملية، ويبدأ بالنقطة "0" وينتهي بالنقطة "1" لقيمة الخاصية التي نريد إظهار الحركة الانتقالية لها. المثال الأبسط هو التحريك المنتظم، أي الخطي، وذلك باستخدام المنحني (cubic-bezier(0, 0, 1, 1، الذي سيبدو بالشكل التالي: عندما يمر الوقت (x) ستكتمل عملية التحريك (y) بثبات وتناغم من القيمة 0 إلى 1. وفي مثالنا التالي ستتحرك صورة القطار من اليسار إلى اليمين بسرعة ثابتة، إذا نقرت عليه: شيفرة الملف style.css: .train { position: relative; cursor: pointer; width: 177px; height: 160px; left: 0; transition: left 5s cubic-bezier(0, 0, 1, 1); } شيفرة الملف index.html: <!doctype html> <html> <head> <meta charset="UTF-8"> <link rel="stylesheet" href="style.css"> </head> <body> <img class="train" src="https://js.cx/clipart/train.gif" onclick="this.style.left='450px'"> </body> </html> وستكون النتيجة: إليك شيفرة استخدام الخاصية transition بناءً على منحني بيزيه: .train { left: 0; transition: left 5s cubic-bezier(0, 0, 1, 1); /* JavaScript sets left to 450px */ } لكن كيف سنرى القطار وهو يُبطئ؟ يمكن استعمال منحني بيزيه آخر من الشكل (cubic-bezier(0.0, 0.5, 0.5 ,1.0، وفي المقال التالي سنرى كيفية بدء العملية بسرعة، حيث يتحرك القطار سريعًا ثم يتباطأ. شيفرة الملف style.css: .train { position: relative; cursor: pointer; width: 177px; height: 160px; left: 0px; transition: left 5s cubic-bezier(0.0, 0.5, 0.5, 1.0); } شيفرة الملف index.html: <!doctype html> <html> <head> <meta charset="UTF-8"> <link rel="stylesheet" href="style.css"> </head> <body> <img class="train" src="https://js.cx/clipart/train.gif" onclick="this.style.left='450px'"> </body> </html> وستكون النتيجة: شيفرة CSS: .train { left: 0; transition: left 5s cubic-bezier(0, .5, .5, 1); /* JavaScript sets left to 450px */ } يمكنك استخدام العديد من المنحنيات الجاهزة، مثل linear أو ease أو ease-in أو ease-out أو ease-in-out، وإليك جدولًا بالمنحنيات الموافقة لها: وفي ملاحظة هامة، تجدر الإشارة إلى أن * تستخدَم ease قيمةً افتراضيةً إذا لم نحدد دالة توقيت timing-function. وكما هو واضح يمكن استعمال ease-out في حالة القطار الذي يُبطئ حركته: .train { left: 0; transition: left 5s ease-out; /* transition: left 5s cubic-bezier(0, .5, .5, 1); */ } لكنه يبدو مختلفًا نوعًا ما. قد تتجاوز الحركة الانتقالية المدى عند استخدام منحني بيزيه. ويمكن أن تحمل النقاط الحاكمة في منحني بيزيه أي قيمة للإحداثي y حتى القيم السالبة أو الضخمة، وبهذا قد يمتد المنحني على مساحة ضيقة جدًا أو واسعة جدًا، وقد تتجاوز الرسوم المتحركة مداها الطبيعي. لاحظ الشيفرة التالية: .train { left: 100px; transition: left 5s cubic-bezier(.5, -1, .5, 2); /* JavaScript sets left to 400px */ } ينبغي إظهار حركة انتقالية للخاصية left بين القيمتين 100px و400px، لكنك بالنقر على صورة القطار سترى ما يلي: أولًا سيتراجع القطار إلى الخلف، وستغدو قيمة left أقل من 100px. يتقدم بعدها القطار إلى الأمام لتتجاوز left القيمة 400px بقليل. ثم يعود مجددًا إلى القيمة 400px للخاصية left. شيفرة الملف style.css: .train { position: relative; cursor: pointer; width: 177px; height: 160px; left: 100px; transition: left 5s cubic-bezier(.5, -1, .5, 2); } شيفرة الملف index.html: <!doctype html> <html> <head> <meta charset="UTF-8"> <link rel="stylesheet" href="style.css"> </head> <body> <img class="train" src="https://js.cx/clipart/train.gif" onclick="this.style.left='400px'"> </body> </html> وستكون النتيجة على النحو الآتي: ما جرى واضح جدًا إذا نظرنا إلى رسم منحني بيزيه لهذه الحركة، فقد نقلنا قيمة الإحداثي y للنقطة الثانية تحت الصفر، وجعلنا قيمته بالنسبة للنقطة الثالثة تتجاوز 1، لذا سيخرج شكل المنحني عن الشكل النظامي للمنحني من الدرجة الرابعة، فقيمة y خارج المجال المعياري بين 0 و1. وكما نعرف، تقيس y مدى اكتمال الحركة الانتقالية، حيث تتطابق القيمة y = 0 مع بداية الحركة، والقيمة y = 1 مع نهايتها. إذًا ستنقل القيمة y<0 نقطة البدء إلى ما قبل البداية، والقيمة y>1 إلى ما بعدها. يُعَد هذا التغيير بسيطًا طبعًا، فلو ضبطنا y على القيمة 99 أو -99، فسيقفز القطار بسرعة أكبر بكثير خارج المجال، لكن كيف سننشئ منحني بيزيه من أجل مهمة معينة؟ هنالك أدوات كثيرة، كما يمكن تنفيذه ضمن مواقع عديدة على الإنترنت. دالة التوقيت steps تسمح دالة التوقيت ([steps(number of steps[, start/end بتقسيم الحركة الانتقالية إلى خطوات، لنرى ذلك من خلال مثال قائمة من الأرقام التي لا تبدي أي حركة: شيفرة الملف style.css: #digit { border: 1px solid red; width: 1.2em; } #stripe { display: inline-block; font: 32px monospace; } شيفرة الملف index.html: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <link rel="stylesheet" href="style.css"> </head> <body> <div id="digit"><div id="stripe">0123456789</div></div> </body> </html> وستكون النتيجة: سنُظهر الأرقام منفصلة، وذلك بجعلها غير مرئية خارج النافذة الحمراء، بعدها سنحرك القائمة نحو اليسار في كل خطوة، وبالتالي سنحتاج إلى 9 خطوات لتنفيذ الأمر: #stripe.animate { transform: translate(-90%); transition: transform 9s steps(9, start); } شيفرة الملف style.css: #digit { width: .5em; overflow: hidden; font: 32px monospace; cursor: pointer; } #stripe { display: inline-block } #stripe.animate { transform: translate(-90%); transition-property: transform; transition-duration: 9s; transition-timing-function: steps(9, start); } شيفرة الملف index.html: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <link rel="stylesheet" href="style.css"> </head> <body> Click below to animate: <div id="digit"><div id="stripe">0123456789</div></div> <script> digit.onclick = function() { stripe.classList.add('animate'); } </script> </body> </html> وستكون النتيجة: يُمثّل الوسيط الأول للدالة (steps(9, start عدد الخطوات، أي ستقسم الحركة الانتقالية إلى 9 أجزاء -10% لكل خطوة-، كما سيُقسم الفاصل الزمني تلقائيًا إلى 9 أجزاء أيضًا، فلو كانت قيمة الخاصية transition تعادل 9 ثوان، فسيظهر كل رقم لمدة ثانية؛ أما الوسيط الثاني فيأخذ إحدى القيمتين start أو end، حيث تعني القيمة start أننا نريد تنفيذ الخطوة الأولى مباشرةً عند بداية الحركة، ويمكنك ملاحظة ذلك خلال الحركة، فعندما ننقر على الرقم سيتغير إلى "1" -أي الخطوة الأولى- مباشرةً، ثم يكمل ثانيةً وهكذا. تتقدم العملية كالتالي: -10% - 0s: يحدث التغيير الأول في بداية الثانية الأولى مباشرةً. 1s – -20%. … 8s – -80%. تُظهر الثانية الأخيرة القيمة الأخيرة. بينما تعني القيمة end وجوب تطبيق التغيير في نهاية كل ثانية، ويكتمل في نهاية الثانية المعدودة. وتتقدم العملية كالتالي: 0s – 0: لا يتغير شيء في الثانية الأولى. 1s – -10%: يحدث التغير الأول عند نهاية الثانية الأولى مباشرةً. 2s – -20%. … 9s – -90%. إليك مثالًا نموذجيًا عن استخدام الدالة (steps(9, start. شيفرة الملف style.css: #digit { width: .5em; overflow: hidden; font: 32px monospace; cursor: pointer; } #stripe { display: inline-block } #stripe.animate { transform: translate(-90%); transition-property: transform; transition-duration: 9s; transition-timing-function: steps(9, end); } شيفرة الملف index.html: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <link rel="stylesheet" href="style.css"> </head> <body> Click below to animate: <div id="digit"><div id="stripe">0123456789</div></div> <script> digit.onclick = function() { stripe.classList.add('animate'); } </script> </body> </html> وستكون النتيجة: إليك بعض القيم المختصرة: step-start: تماثل (steps(1, start. step-end: تماثل (steps(1, end. لا تستخدم هذه القيم إلا نادرًا لأنها لا تُصنَّف حركات فعلًا، بل تغيرات تحدث بالخطوة. الحدث transitionend يقع الحدث transitionend عندما تنتهي الحركة المبنية على خصائص CSS، ويستخدم لتنفيذ عمل ما بعد انتهاء الحركة، حيث يمكننا مثلًا ضم حركات مختلفة، فالسفينة في المثال التالي ستبدأ رحلتها وتستمر بالعودة عند النقر، وفي كل مرة تبتعد نحو اليمين أكثر: تبدأ الحركة نتيجة تنفيذ الدالة go، التي يُعاد تنفيذها في كل مرة تنتهي فيها الحركة، وتغير اتجاه الحركة: boat.onclick = function() { //... let times = 1; function go() { if (times % 2) { // sail to the right boat.classList.remove('back'); boat.style.marginLeft = 100 * times + 200 + 'px'; } else { // sail to the left boat.classList.add('back'); boat.style.marginLeft = 100 * times - 200 + 'px'; } } go(); boat.addEventListener('transitionend', function() { times++; go(); }); }; لكائن الحدث transitionend عدة خصائص مميزة، هي: event.propertyName: يعيد اسم الخاصية التي أنهت حركتها الانتقالية، وتظهر فائدتها عند تحريك عدة خصائص معًا. event.elapsedTime: الوقت الذي استغرقته الحركة بالثواني، دون احتساب transition-delay. القاعدة keyframes يمكن ضم عدة حركات بسيطة معًا باستخدام قاعدةkeyframes@ من CSS، والتي تحدد اسم الحركة الانتقالية، وقواعد مكانها وزمانها وكيفيتها، بعدها سنتمكن باستخدام الخاصية animation من ربط الحركة بالعنصر وتخصيص معاملات إضافية قد نحتاجها، إليك مثالًا مع الشرح: <div class="progress"></div> <style> @keyframes go-left-right { /* "go-left-right" أعط القاعدة اسمًا*/ from { left: 0px; } /* left: 0px حرك ابتداءً من قيمة */ to { left: calc(100% - 50px); } /* 100%-50px: حرك نحو اليسار */ } .progress { animation: go-left-right 3s infinite alternate; /* طبق الحركة التي عرفناها في الأعلى على العنصر المدة 3 ثوان عدد المرات: لانهائي بدّل اتجاه الحركة في كل مرة */ position: relative; border: 2px solid green; width: 50px; height: 20px; background: lime; } </style> See the Pen JS-P3-05-CSS-animations-ex3 by Hsoub (@Hsoub) on CodePen. ستجد العديد من المقالات التي تشرح القاعدة @keyframes من CSS مع ميزاتها المفصلة، ولن تحتاجها غالبًا إلا عندما يكون كل شيء في موقعك متحركًا باستمرار. الأداء يمكن تحريك أغلب خاصيات CSS بما أنها قيم رقمية مثل width و color و font-size، فيعمل المتصفح عندما تحرك هذه الخاصيات على تغيير هذه القيم تدريجيًا في كل إطار من الإطارات مما يعطي إيحاء بتأثير حركي سلس، ولكن انتظر، لا تبدو كل الحركات سلسلة كما تريدها لأن تغيير بعض خاصيات CSS عملية مجهدة. لنغوص أكثر في التفاصيل، عندما يكتشف المتصفح حدوث تغير في التنسيق، فإنه يمر بثلاثة خطوات حتى يخرج الصفحة بالتنسيق الجديد وهي: التخطيط Layout: إعادة حساب إحداثيات ومواضع كل عنصر من عناصر الصفحة، ثم الشكل Paint: إعادة حساب كيف يجب أن يظهر كل عنصر بعد تموضعه في مكانه وكل شيء حرفيًا بما فيها الخلفيات والألوان، ثم التركيب Composite: تصيير النتائج النهائية وإخراجها وعرضها على بكسلات الشاشة وتطبيق تحويلات CSS إن وجدت. تكرر هذه الخطوات خلال إجراء تحريك عبر CSS لكل إطار من الإطارات، رغم أن خاصيات CSS التي لا تؤثر على الإحداثيات أو التموضع مثل تغيير خاصية اللون color فقد تتخطى الخطوة الأولى وينتقل المتصفح إلى الخطوة الثانية مباشرةً ثم الثالثة وقد تتخطى بعض الخاصيات حتى الخطوة الثانية وتنتقل إلى الخطوة الثالثة مباشرةً، ويمكنك أن تطلع على قائمة خاصيات CSS والمراحل التي تستهدفها من موقع CSS Triggers. معلومٌ أن تلك الخطوات تأخذٌ وقتًا في الحساب خصوصًا إن حوت الصفحة على عناصر كثيرة وكانت تخطيطها معقدًا، فقد يُلاحظ تأخر في الحركة على أغلب الأجهزة مسببًا حركة مضطربة مرتعشة، لذا تتصف الحركات المطبقة على الخاصيات التي تتخطى حساب التخطيط (ويفضل أيضًا الشكل أي الخطوة الثانية) بالسرعة والسلاسة. تعد الخاصية transform خيارًا جيدًا لسببين هما: تستهدف التحويلات في CSS صندوق العنصر ككل (تدوير، أو قلب أو تمديد أو إزاحة …إلخ.) لا تؤثر التحويلات على العناصر المجاورة للعنصر المستهدف. وفقًا ذلك، تطبق التحويلات على عناصر يكون فيها التخطيط والشكل محسوبين مسبقًا وتنتقل مباشرةً إلى الخطوة الثالثة من الخطوات السابقة، أي أن المتصفح يحسب التخطيط (الحجم والمواضع) ثم يضيف لها تسنيق الشكل من ألوان وواجهات وغيرهما في المرحلة الثانية ثم يطبق التحويل الممثل بالخاصية transform على صندوق العنصر إن وجدت. أي تغييرات (تحريكات) تطبق على الخاصية transform لا تستدعي المرور ضمن الخطوة الأولى والثانية مطلقًا، علاوة على أن المتصفح يستغل قدرات الحاسوب الرسومية (بطاقة العرض التي تكون مدمجة في المعالج أو منفصلة) لمعالجة التحويلات مما يزيد من كفاءة العملية. مما سبق نجد أن الخاصية transform قوية للغاية ويمكنك عبرها تدوير عنصرٍ أو قلبه أو تطويله أو تقصيره أو حتى تحريكه وغيرها (انظر صفحة الخاصية على موسوعة حسوب)، فيمن استعمال transform: translateX(…)‎ بدلًا من استعمال الخاصية left أو margin-left أو استعمال transform: scale لزيادة حجم عنصر وهكذا. لاحظ أن الخاصية opacity لا تمر على الخطوة الأولى من الخطوات السابقة (أيضًا تتخطى الخطوة الثانية في محرك Mozilla Gecko)، ويمكن استعمالها لتطبيق تأثيرات مثل الإظهار أو الإخفاء أو التلاشي، ويمكن استعمال transform معها لإنشاء حركات سلسلة جميلة. انظر مثلًا المثال التالي الذي يتحرك فيه العنصر بمجرد الضغط عليه إلى اليمين مقدار 300 بكسل ثم يختفي: <img src="https://js.cx/clipart/boat.png" id="boat"> <style> #boat { cursor: pointer; transition: transform 2s ease-in-out, opacity 2s ease-in-out; } .move { transform: translateX(300px); opacity: 0; } </style> <script> boat.onclick = () => boat.classList.add('move'); </script> See the Pen JS-P3-05-CSS-animations-ex4 by Hsoub (@Hsoub) on CodePen. وإليك أيضًا مثال آخر أكثر تعقيدًا يُطبَّق فيه إطارات الحركة ‎@keyframes: <h2 onclick="this.classList.toggle('animated')">click me to start / stop</h2> <style> .animated { animation: hello-goodbye 1.8s infinite; width: fit-content; } @keyframes hello-goodbye { 0% { transform: translateY(-60px) rotateX(0.7turn); opacity: 0; } 50% { transform: none; opacity: 1; } 100% { transform: translateX(230px) rotateZ(90deg) scale(0.5); opacity: 0; } } </style> See the Pen JS-P3-05-CSS-animations-ex5 by Hsoub (@Hsoub) on CodePen. خلاصة تسمح الحركات الانتقالية التي تدعمها CSS بإجراء تغيرات ناعمة على خاصية أو أكثر، وهي تقنية جيدة للكثير من مهام الرسوم المتحركة، كما يمكننا استخدام رسوم JavaScript المتحركة وهذا ما سنراه في جزئية لاحقة من هذه السلسلة. النقاط الأساسية التي تجعل الرسومات المتحركة باستخدام CSS محدودةً موازنةً برسوم JavaScript هي: الإيجابيات. تنفَّذ الأشياء البسيطة ببساطة. سريعة وخفيفة على المعالج. السلبيات. رسوم JavaScript أكثر مرونةً، إذ يمكنها تنفيذ أي منطق رسومي، مثل "انفجار" عنصر مثلًا. لا تعتمد رسوميات JavaScript على تغيرات الخاصية، بل يمكن إنشاء عناصر جديدة في JavaScript مثل جزء من الرسوميات. في أمثلتنا الأولى حركنا font-size وleft وwidth وheight، لكن إذا رغبنا في أداء أفضل في مشاريعنا الحقيقية، فيجب أن نستخدم ()transform: scale و()transform: translate. يمكن تنفيذ الرسوميات المتحركة باستخدام CSS كما شرحناها في هذا المقال، وسيسمح لنا الحدث transitionend باستخدام JavaScript بعد انتهاء الحركة الانتقالية، وبالتالي ستتكامل جيدًا مع الشيفرة. سنتعرف في المقال القادم على رسوم JavaScript المتحركة التي تساعدنا في تنفيذ حالات أكثر تعقيدًا. مهام لإنجازها تحريك طائرة في CSS أظهر رسمًا متحركًا يشابه صورة الطائرة في الأسفل: يزداد حجم الصورة من 40x24px إلى 400x240px. تستغرق العملية 3 ثوان. اطبع كلمة "!Done" عند الانتهاء. لا يجب أن تتوقف العملية بالنقر على الصورة أثناء التنفيذ. افتح المثال في بيئة تجريبية الحل إليك الشيفرة: /* original class */ #flyjet { transition: all 3s; } /* JS adds .growing */ #flyjet.growing { width: 400px; height: 240px; } انتبه إلى أن الحدث transitionend يقع مرتين، مرة لكل خاصية، وبذلك ستظهر الرسالة مرتين إن لم نضع أي شرط تحقق. تحرك الطائرة 2 أعد التمرين السابق لكن اجعل الحجم يتجاوز الحجم الأقصى للصورة 400x240px، ثم يعود إلى هذا الحجم. الحل نريد اختيار أنسب منحني بيزيه لتلك الحركة، إذ يجب أن تحقيق y>1 في موضع ما للطائرة لتحقيق تأثير القفزة مثل cubic-bezier(0.25, 1.5, 0.75, 1.5)‎، انظر المخطط: افتح الحل في بيئة تجريبية. تحريك دائرة أنشئ الدالة showCircle(cx, cy, radius) التي تظهر دائرةً تنمو. cx,cy: يمثلان إحداثيات مركز الدائرة بالنسبة إلى إحداثيات النافذة. radius: نصف قطر الدائرة. انقر الزر لترى كيف سيظهر الحل: تجد المثال في هذه البيئة التجريبية وتجد حله في هذه البيئة التجريبية. تحريك دائرة مع دالة استدعاء انطلاقًا من المهمة السابقة، نحتاج إلى دائرة تُظهر رسالةً داخلها. ينبغي أن تظهر الرسالة مباشرةً بعد اكتمال الحركة، أي ظهور الدائرة بحجمها الكامل، وإلا سيبدو المنظر سيئًا. ترسم الدالة (showCircle(cx, cy, radius الدائرة، لكن لا يمكنها أن تدلّك على اكتمال الرسم، لذا أضف دالة استدعاء callback مثل معامل إلى الدالة السابقة (showCircle(cx, cy, radius, callback، حيث تُستدعى عندما ينتهي الرسم المتحرك. ينبغي أن تتلقى دالة الاستدعاء callback العنصر <div> للدائرة مثل وسيط. إليك مثالًا: showCircle(150, 150, 100, div => { div.classList.add('message-ball'); div.append("Hello, world!"); }); النموذج: تجد حل المثال في هذه البيئة التجريبية. ترجمة -وبتصرف- للفصل css-animations من سلسلة The Modern JavaScript Tutorial. اقرأ أيضًا المقال السابق: منحنى بيزيه وأهميته في الرسوميات وصناعة الحركات في جافاسكربت تأثيرات الانتقال والحركة في CSS منحنى بيزيه وأهميته في الرسوميات وصناعة الحركات في جافاسكربت table { width: 100%; } thead { vertical-align: middle; text-align: center; } td, th { border: 1px solid #dddddd; text-align: right; padding: 8px; text-align: inherit; } tr:nth-child(even) { background-color: #dddddd; } p iframe { border: 1px solid #e7e5e3 !important; }
  3. يعد التحريك باستخدام مكتبة React Native من المواضيع الأساسية المطروحة في أقسام الدراسة أو ورشات العمل، ربما لكون عدد من المطورين يجدون تحديًا في استخدامها. في الوقت الذي تركّز فيه الكثير من المدونات والمصادر في الويب على جوانب الأداء عند استخدام React Native، لا يخوض إلا عدد قليل منها في الأساسيات. سنعرض في هذه المقالة لأساسيّات تطبيق التحريكات باستخدام مكتبة React Native. أولًا سنلقي نظرة على خلفية المكتبة وتاريخها. بداية التحريكات في React Native وتطوّرها عند تشغيل برنامج عابر للمنصّات مكتوب بلغة جافاسكريبت تحتاج مكوّنات React Native على هاتفك إلى تبادل المعلومات بواسطة عنصر يسمّى الجسر (Bridge). التبادل عبر هذا العنصر غير متزامن (Asynchronous)، وهو ما يجعل التطبيقات المبنية على إطار العمل React Native تصبح بطيئة لأن الطلبات غير المتزامنة المارّة على الجسر تسدّ المسار أمام شفرة جافاسكريبت التي تتفاعل مع أجزاء إطار العمل. للحصول على أداء عال يجب أن تصيّر (Render) التحريكات على خيط (Thread) واجهة المستخدم الأصلي في نظام التشغيل، وبما أن البيانات تحتاج للسَّلسَلة (Serialization) عبر الجسر فإن ذلك يؤدّي غالبًا إلى منع خيط جافاسكريبت، ممّا يتسبّب في نقص عدد الإطارات (Frame) على الشاشة. بقي هذا المشكل حاضرًا منذ 2015 حين كانت التحريكات تمثّل واحدة من العقبات الكبرى أمام إطار العمل React Native. لحسن الحظ، تحسّنت الحالة منذ ذلك الوقت بفضل الدعم الكبير من أعضاء مجتمع المطورين، إذ أصبح من الشائع الآن إنجاز 60 إطارًا في الثانية الواحدة (Frame per second, FPS) في عمليات التحريك ضمن React Native. سهّلت واجهات تطبيقات برمجيّة تصريحيّة (Declarative API) مثل Animated عمليّة تنفيذ التحريكات التفاعلية. استخدام واجهة التطبيقات البرمجية Animated لتحسين الأداء يواجه المطورون حتى الآن العديد من القضايا المتعلقة بالأداء خاصة عندما يعملون على رسومات متحركة معقّدة. كما ذكرنا سابقًا، تتسبب الاختناقات في الأداء التي تحدث عند تنفيذ الرسوم في React Native، بأعباء عمل كبيرة على خيوط جافاسكربت (JavaScript threads)، مما يقلّل من معدل إظهار الإطارات، وبالتالي يتسبّب في البطء عند استخدام البرنامج، وللتغلب على هذه المشكلة نحتاج إلى الحفاظ على معدل 60 إطارًا في الثانية الواحدة. إن أفضل حل للحفاظ على معدّل الإطارات بالثانية هو استخدام Animated API لأنها تحسّن الزمن المطلوب للسَّلسَلة وعكسها (Serialization/Deserialization). تعمل Animated API عبر استخدام واجهة تطبيقات تصريحية لوصف التحريكات. الفكرة التي تقوم عليها هي التصريح بالتحريك كاملًا مرةً واحدة مقدّمًا لكي تُمكِن سَلسَلة التصريح في جافاسكريبت وإرسالها إلى الجسر. ينفّذ مشغّلٌ (Driver) التحريكاتِ إطارًا بعد الآخر. تنفيد التحريكات ضمن React Native توجد طرق عدة لتطبيق التحريك في React Native. في ما يلي الطرق التي أجد أن لديها فائدة أكبر. القيم المتحرّكة Animated values يتربّع تحريك القيم على قائمتي بوصفه لبنة أساسيّة للتحريكات في تطبيقات React. تشير هذه القيم عمومًا إلى قيم حقيقة تُحوَّل إلى أعداد حقيقية عند تمريرها مع مكوّن مُحرَّك. فلننظر إلى المثال التالي. Animated.timing(this.valueToAnimate, { toValue: 42; duration: 1000; }).start() نلاحظ في المثال السابق أننا أسندنا القيمة 42 إلى value.ToAnimate والتي ستنفّذ بعد 1000 ميلي ثانية. كما يمكن التصريح عن قيم خاصيات التحريك الأخرى مثل الشفافية opacity أو الموضع position. في ما يلي مثال تطبيقي على الشفافية بقيم متحرّكة. <Animated.View style={{ opacity: myAnimatedOpacity }} /> مشغلات التحريك: Animated.timing و Animated.event و Animated.decay انظر إلى المشغّلات على أنها عُقد في مخطّط بياني (Graph) تغيّر قيمةً متحرّكة مع كل إطار. على سبيل المثال، ستزداد القيمة المسندة إلى Animated.timing، بينما ستنقص القيمة المسندة إلى Animated.decay في كل إطار. لنلق نظرة على المثال التالي: Animated.decay(this.valueToAnimate, { velocity: 2.0, deceleration: 0.9 }).start(); في هذا المثال، ستنفَّذ الرسوم المتحركة انطلاقًا من سرعة محددة بالقيمة 2.0، ثم تتناقص تدريجيًا خلال الوقت المحدَّد. أصبحت هذه الطريقة شائعة في التطبيقات العابرة للمنصّات مع بداية ظهور التوثيقات عن التصميم المسطّح (Material design). تبدو التحريكات بمظهر جيّد، وتوجد طرق عدّة لجعل التجربة لا تنسى. يمكن كذلك استخدام Animated.event لتشغيل قيمة عند تمرير المستخدم: <ScrollView onScroll={Animated.event( [{nativeEvent: {contentOffset: {y: this.state.scrollY}}}] )} > </ScrollView> في المثال السابق يُعيد Animated.event دالّة تعدّل قيمة الخاصيّة nativeEvent.content.offset.y في المكوّن scrollView لتأخد قيمة scrollY الحالية. عمومًا، يمكن استخدام مشغلّات التحريك مع القيم المتحركة أو مع مشغّلات أخرى. ملحوظة جانبية: انتبه إلى أنه عندما يحدّث المشغّل كل إطار فإن القيمة الجديدة تحدّث مباشرةً قيمة الخاصيّة View، وبالتالي يجب أن تكون حذرًا عند التصريح بالمتغيّرات وتنتبه إلى نطاقها أثناء استخدامها. توابع التحويل Transform methods تتيح لك توابع التحويل تحويل قيمة متحرّكة إلى قيمة متحرّكة جديدة. يمكنك استخدام توابع مثل Animated.add()‎ وAnimated.multiply()‎ وAnimated.interpolate()‎ لتنفيذ عمليّات تحويل بين القيم. يمكنك تنفيذ عمليّة تحويل على أي عقدة في المخطّط البياني قيد التحريك كالتالي: newAnimated.Value(55).interpolate(.....) // Transformation operation using Animated.interpolate() method تحريك الخاصيّات الخاصيّات المتحرّكة هي عقد خاصّة تربط بين القيم المتحرّكة وخاصيّة في مكوّن. تُولَّد تلك الخاصيّات عند تصيير الخاصيّة Animated.view وإسناد خاصيّات لها. فلننظر إلى الشفرة التالية: Var opacity = new Animated.Value(0.7); <Animated.View style={{ opacity }} /> أضفنا خاصيّة متحرّكة تُحوِّل القيمة 0.7 إلى خاصية. في حال حدّث التابع تلك القيمة، سينعكس التغيير على خاصية View. تعمل التوابع الموصوفة أعلاه أساسًا بالتزامن مع الكائنات المتحرّكة (Animated objects) في React، كما أن توابع التحويل تؤدّي دورًا أساسيًّا في عمل تلك الكائنات. يغيّر مشغّل التحريك (Animated.Timing أو Animated.Event أو Animated.Decay) قيم التحريك في كل إطار ثم تُمرر النتيجة عبر أي تابع من توابع التحويل لتُخزَّن بصيغة خاصية عرض (الشفافية Opacity أو قيمة التحويل). يسلم مفسّر جافاسكريبت النتيجة إلى Native React حيث تُحدَّث الواجهة من خلال استدعاء التابع setNativeProps. في الأخير تُمرَّر الخاصيّة إلى iOS أو Android حيث يتسلم المكوّن UIView أو Android.View التحديثات. تنفيذ الرسوم المتحركة باستخدام Animated API و Native Driver تشرف مشغلات جافاسكريبت منذ ظهور Animated API على عملية تنفيذ التحريك، ولكن هذه الطريقة سببت تباطؤًا في عملية التحريك بسبب قلة عدد الإطارات المعروضة في الثانية ويعود السبب في ذلك أن العمل كله يتم في الخيط (Thread) الخاص بجافاسكريبت. لتجاوز هذه المشكلة أضيفت مشغلات خاصة بإطار العمل React Native وبالتالي أصبحت قادرة على تنفيذ عملية التحريك كاملةً، إطارًا بعد الآخر، ضمن React Native. عند استخدام المشغل الخاصة بإطار العمل React native مع Animated API فإن ذلك يسمح بتحديث العرض مباشرة دون الحاجة إلى إعادة حساب القيم مرة أخرى في جافاسكربت. لاستخدام المشغّل الخاص بإطار العمل React يجب تعيين القيمة true إلى الخاصيّة useNativeDriver أثناء ضبط التحريكات. useNativeDriver: true استخدام PanResponder للتعامل مع لمس الشاشة في React Native يمكن لواجهة التطبيقات Animated API تنفيذ غالبية الأعمال الروتينية عند عمل التحريكات في React Native، إلّا أنها محدودة في التعامل مع لمس الشاشة للتفاعل مع التحريكات، فهي غير قادرة على التجاوب مع الحركات التي تحدث خارج المكوّن ScrollView. رغم أنه يمكن تنفيذ أشياء كثيرة عن طريق مكوّن ScrollView بسيط، إلّا أن التطبيقات على الأجهزة الجوّالة تبقى ناقصة بدون لمس الشاشة التي يستعملها المستخدم للتفاعل مع التحريكات عن طريق التمرير أو التدوير على سبيل المثال. يمكن التعامل مع حركات اللمس في React Native بسلاسة باستخدام PanResponder مع Animated API. يدمج PanResponder لمسات عدّة في حركة خاصّة، ويجعل لمسة واحدة تتجاوب مع لمسات إضافية لكي تعمل حركات اليد بسلاسة. افتراضيًّا، يتمثّل PanResponder في مقبض InteractionManager يمنع الأحداث العاملة على خيط جافاسكريبت من تعطيل حركات اللمس. تحسين زمن التشغيل لانتقالات التصفح البطيئة عادةً يحتاج أي تحريك يستدعي الانتقال من شاشة إلى أخرى في React Native إلى استخدام مكوّنات التصفّح. تُستخدَم مكوّنات التصفّح مثل React Navigation عادةً للانتقالات أثناء التصفح. تحدث الانتقالات أثناء التصفّح في React Native عادةً في خيوط جافاسكريبت، ممّا قد يتسبّب في انتقالات بطيئة في الأجهزة الرخيصة أو ذات الذاكرة المحدودة (أجهزة أندرويد أساسًا إذ أن الأجهزة العاملة بنظام iOS تتعامل مع الأمر بفاعلية أكبر). تحدث انتقالات التصفح البطيئة عادة عندما يحاول React Native تصيير شاشة جديدة في حين أنه ما زالت تُنفَّذ تحريكات في الخلفية. لتفادي حالات مثل تلك المذكورة أعلاه، يسمح مدير التفاعلات (InteractionManager) بجدولة الأنشطة التي تأخذ وقتًا في التنفيذ بجدولتها بعد تنفيذ تحريك أو تفاعل في خيط جافاسكريبت. تحريك التخطيطات Layouts تعمل واجهة التطبيقات البرمجية LayoutAnimation على تحريك الشاشة تلقائيًّا إلى الوضعية الموالية عندما يحدث التخطيط (Layout) الموالي. تُنفَّذ واجهة التطبيقات تلك ضمن خيط واجهة المستخدم (UI Thread) وهو ما يجعلها ذات أداء عال. تُطبَّق التحريكات المعدَّة عن طريق LayoutAnimation، فور استدعائها، على كل المكوّنات؛ بخلاف واجهة Animated التي يمكنك عن طريقها التحكّم في القيم المخصوصة بتحريكها. يمكن لواجهة LayoutAnimation تحريك كل شيء في التصيير القادم، لذا يجب استدعاؤها قبل استدعاء setState. يضمن إعداد تحريك للتخطيط قبل استدعاء setState تحريكات سلسة في خيط Native ويحول دون تأثر التحريكات بتنفيذ شفرة برمجية عند إطلاق دور setState أخرى (وهو ما يتسبّب - في الظروف العادية - في تهديد تحريكات تطبيقك). توجد طريقة أخرى لاستخدام LayoutAnimation وتتمثّل في استدعائها داخل التابع WillReceiveProps. استدع بكل بساطة التابع LayoutAnimation.configureNext مع تمرير الوسائط المناسبة لإعداد التحريك، كما هو موضَّح أدناه: LayoutAnimation.configureNext(animationConfiguration, callbackCompletionMethod); this.setState({ stateToChange: newStateValue }); لا تدعم واجهة LayoutAnimation سوى خاصيّتين هما الشفافية (Opacity) وقابلية التكيّف (Scalability). تتعرّف الواجهة على العروض (Views) باستخدام مفاتيحها الفريدة وحساب وضعيّتها المتوقّعة. علاوة على ذلك، تحرّك تغيّرات الإطارات ما دام العرض يحتفظ بالمفتاح نفسه بين تغيّر الحالات. تعمل التحريكات المطبَّقة بواسطة LayoutAnimation ضمن الخيط الأصلي لواجهة المستخدم في نظام التشغيل، وهو أمر جيّد من ناحية الأداء، إلّا أنه يمثّل تحديًّا إذا دعت الحاجة لتحريك كل الخاصيّات بين حالات الإطارات. خاتمة لا يدخل هذا المقال في تفاصيل التحريكات في React Native ويكتفي بأمور سطحية، إلّا أن هناك قاعدة أساسية عند التعامل مع إطار العمل React Native وهي استخدام واجهة التطبيقات البرمجية Animated API ما دام ذلك ممكنا. بالنسبة لحركات اللمس، استخدم PanResponder بجانب Animated API. يمكن التغلّب على الكثير من المشاكل التي تواجهها بالاستفادة من مشغّل Native driver إلى جانب واجهة Animated. إنْ استمرّت مشاكل الأداء رغم ذلك فالزم LayoutAnimation. ترجمة - وبتصرّف - للمقال Getting started with React Native animations لصاحبه Rakshit Soral.
  4. يتضمن العمل مع أشكال SVG (الرسوميات المتجهية متغيرة الحجم) في سير عمل تصميم الويب المتجاوب مرحلة تصميم ومرحلة تطوير. يتعامل المصممون عادةً مع مرحلة التصميم وقد يعرفون أو لايعرفون كيفية كتابة الشيفرة. ونظرًا لطبيعة SVG كتنسيق صورة وتنسيق مستند معًا، فإنّ كل خطوة تتم في محرر الرسومات أثناء عملية إنشاء SVG تؤثر بشكلٍ مباشر على الشيفرة الناتجة وبالتالي على عمل المطور المسؤول عن تضمين SVG أو كتابته كنص برمجي أو تحريكه. عادةً، خلال عملي اليومي أنا المطور الذي يسلّم المصممون له أصول التصميم، وصور SVG هي جزء من هذه الأصول. احتاجت معظم الأصول التي تم تسليمها في مشاريعي السابقة إلى المزيد من العمل و/أو جولة ثانية من التحرير في محرر الرسومات قبل أن أتمكن من كتابتها كنصوص برمجية، لأنّ شيفرة SVG الناتجة لم تُحسَّن بما فيه الكفاية لنوع العمل - خاصةً الرسوم المتحركة - التي تم استئجاري للقيام بها. سبب ذلك هو أنّ العديد من المصممين الذين عملت معهم يعرفون القليل جدًا - إن كانوا يعرفون - عن شيفرة SVG. ينشؤون رسوميات متجهة وأصول واجهة المستخدم كل الوقت، لكن بالنسبة لهم فإنّ SVG ليس سوى تنسيق صورة ولا يعرفون الكثير عن الشيفرة المتولّدة عند تصدير أصولهم كمستندات SVG. هناك بعض الخطوات التي يمكن للمصممين اتخاذها أو تجنبها - مجموعة من "افعل ولا تفعل" - يمكن أن تساعد في جعل الشيفرة المتولدة أنظف. أودّ أن أشارك بعضها في هذه المقالة، إذا كنت تعرف أي شيء آخر يرجى مشاركته في التعليقات الموجودة في نهاية المقال. النصائح التي سنتحدث عنها قابلة للتطبيق في Adobe Illustrator -محرر الرسومات المفضل لي- وكذلك محررات الرسومات الأخرى. لكن بما أنني شخصيًا أستخدم AI فهذا ما سأركّز عليه خلال هذه المقالة. سنتحدث أيضًا عن خيارات تصدير SVG الحالية المتوفرة في AI وأيّ منها تختار ولماذا. لكن لاحظ أنّ هذه الخيارات ستتغير في المستقبل، وبعدها سيتم تحديث هذه المقالة لتعكس هذه التغييرات. تعتمد هذه المقالة على حديثي "SVG لمصممي ومطوري الويب" - حديث قمت به في CSSDevConf 2015 الشهر الماضي. لذا، لنبدأ. إذا كنت تستخدم برنامج Sketch لإنشاء SVG، هناك أيضًا بعض الأشياء التي يمكن أن تقوم بها لتصدير شيفرة أنظف. شارك Sean Kesterson بعض النصائح في هذه المقالة. 1- أنشئ الأشكال البسيطة باستخدام عناصر شكل بسيطة وليس عناصر <path> هناك سبب لوجود أشكال أساسية مختلفة في SVG لإنشاء أشكال أساسية بشكلٍ جيد. يمكن للشخص إنشاء أي شكل عمليًّا باستخدام عنصر <path>، أليس كذلك؟ عناصر الشكل البسيطة (<line>، <circle>، <rect>، <ellipse>، <polygon> و<polyline>) موجودة لعدة أسباب، وأحد هذه الأسباب هو أنّها سهلة القراءة وسهلة الصيانة وقابلية للتحرير باليد من بدائلها <path>. تأتي الأشكال الأساسية مع مجموعة من الخاصيات التي تسمح لك بالتحكم في ميزات الشكل، مثل الموضع (x، y، cx، cy) والأبعاد (width وheight)، بينما لا يكون لعناصر <path> مثل هذه الخاصيات. مثلًا، يعرض المقتطف التالي الاختلاف بين دائرة تم إنشاؤها وتصديرها كشكلٍ بسيط، مقابل دائرة تم إنشاؤها وتصديرها كمسار: <circle fill="#FFFFFF" stroke="#000" cx="28.1" cy="28.1" r="27.6"/> <!-- مقابل --> <path fill="#FFFFFF" stroke="#000" d="M55.7,28.1 c0,15.2-12.4,27.6-27.6,27.6 S0.5,43.3,0.5,28.1 S12.9,0.5,28.1,0.5 S55.7,12.9,55.7,28.1z"/> إذا أردت تحريك شكلك عن طريق تحريك موضع الدائرة أو تكبيرها، يمكنك القيام بذلك عن طريق تحريك موضع المركز عبر الإحداثيات x و y أي (cx وcy) ونصف قطر الدائرة (r). بينما إذا كنت تعمل مع دائرة متولدة كمسار، يجب عليك استخدام تحويلات CSS/SVG (التحريك وإعادة التحجيم) للقيام بذلك. ثمّ بفرض أردت تحريك ذلك المسار وتتطلب منك الحركة تطبيق المزيد من التحويلات، يمكن أن يصبح لديك ببساطة فوضى تحويلات. ميزة أخرى لاستخدام الأشكال البسيطة هي أنّه في معظم الحالات، الشيفرة المطلوبة لإنشاء شكل باستخدام عناصر شكل بسيطة هي أقلّ من المطلوبة لإنشاء نفس الشكل باستخدام عنصر <path> (شاهد المقتطف اعلاه للمقارنة)، لذا فإنّ استخدام أشكال بسيطة سيؤدي أيضًا إلى حجم ملف أصغر، وهذا أفضل دائمًا. 2 - حوّل النص إلى حدود خارجية..أو لا تحوّله لتحويل النص إلى حدود خارجية: اختر النص الذي تريد تحويله اختر النوع (Type) -> إنشاء حدود خارجية (Create Outlines) الإيجابيات النص المحوّل إلى حدود خارجية سيحافظ على نوع الخط المستخدم، بدون الحاجة إلى استخدام خط ويب لعرضه. هذا يعني أنك تحفظ القليل من طلبات HTTP الإضافية ولا تخاطر بعرض نصك بالخط الاحتياطي الذي لا يبدو جيدًا بشكلٍ كافٍ لاستبدال الخط الجميل الذي اخترته. يعدّ تحويل النص إلى حدود خارجية والحفاظ على نوع الخط المستخدم جيّدًا للحفاظ على هوية العلامة التجارية عندما تُعرّف بنوع خط مستخدم، مثلًا في شعار، أقوم دائمًا بتحويل نص الشعار إلى حدود خارجية وهذا جيد للحفاظ على الخط لنصوص برمجية معينة عندما تستخدم العناوين. السلبيات النص المحوّل إلى خطوط خارجية ليس نصًا حقيقيًا: إنّه مجموعة من المسارات التي تشكل الحدود الخارجية (الشكل) للنص. وبالتالي يصبح النص غير واقعي ولا يمكن الوصول إليه، وغير قابل للبحث وغير قابل للتحديد. إذا تمّ تحويل النص إلى حدود خارجية في عنوان نص برمجي أو حتى شعار، فإنّ استخدام نص alt (إذا تم تضمين الشعار كصورة) أو عناصر سهلة الوصول لـ SVG مثل (<title> و&>) هو فكرة جيدة لتوفير نص بديل لقارئات الشاشة. أوصي بشدّة بقراءة كل شيء عن جعل SVG سهل الوصول في هاتين المقالتين لـLéonie Watson: - نصائح لإنشاء SVG سهلة الوصول - استخدام ARIA لتحسين سهولة الوصول لـSVG يمكن أن يسبب تحويل النص إلى حدود خارجية زيادةً كبيرةً في حجم ملف SVG، حسب تعقيد الخط المستخدم. تُظهر الصورة أدناه الاختلاف في حجم (وسهولة القراءة) لـSVG مع النص المحوّل إلى حدود خارجية (يسار) والنص الذي يتم تصديره كـ SVG <text>‎ (يمين). لا يمكن التحكم بالمسارات أو تحريكها بسهولة مثلما يتم ذلك في عناصر <text> (المتضمنة عناصر <tspan>). إذ تحتوي الأخيرة على مجموعة من الخاصيات التي تمنحك المزيد من التحكم في رسومك المتحركة، بينما تبقى بيانات المسار محدودة بهذا الشأن. 3- تبسيط المسارات يعرَّف المسار بمجموعة من النقاط والتي بدورها يتم تحديد كلّ منها بزوج من الإحداثيات. كلّما قلّ عدد النقاط، قلّت بيانات المسار (خاصية d)، وبالتالي انخفض حجم ملف SVG الكلي. هذه الخطوة الجيدة يجب اتخاذها دائمًا لأنّ حجم الملف الأصغر أفضل للأداء. لتبسيط مسار: اختر المسار اذهب إلى كائن (Object) -> مسار (Path) -> تبسيط (Simplify) عدّل عدد النقاط. تأكّد من أن أنّك فحصت المعاينة حتى تتمكن من معرفة كيف يتغير المسار أثناء تغيّر عدد النقاط. عدّل العدد حتى تحصل على أقل عدد من النقاط أثناء المحافظة (أو التضحية) على أفضل مظهر مرئي للمسار الذي تحتاجه. يوجد فيديو تعليمي لشركة Adobe يشرح العملية، لذا إذا كنت أكثر انسجامًا مع مقاطع الفيديو، يمكنك الاطلاع عليه هنا. يمكنك أيضًا تبسيط المسارات باستخدام أداة Warp Tool. أنا لست مصممة ولكن أستخدم عادةً خوارزمية تبسيط Ai لتبسيط مساراتي، لذا إذا كنت مصممًا متمرّسًا، من المحتمل أنّك تعرف أكثر بكثير عن أداة Warp tool مني. يوجد مقال في مجلة Smashing حول هذه الأداة، يمكنك الاطلاع عليها إن أردت. 4- تجنب دمج المسارات إذا لم تكن بحاجة للتحكم في المسارات الفردية يميل العديد من المصممين إلى جمع المسارات أو دمجها كلما أمكن ذلك. لدمج المسارات: اختر الطرق التي تريد دمجها اذهب إلى نافذة (Pathfinder <- (Window اختر خيار الدمج (Merge) من بين قائمة الخيارات أسفل اللوحة (الأيقونة الثالثة من اليسار، المبينة في لقطة الشاشة أدناه). قد يكون هناك فوائدٌ لجمع المسارات، لكن تجنبها عندما تحتاج أنت أو المطور للتحكم و/أو تحريك المسارات بشكلٍ منفصل. تم تصميم بعض الرسوم المتحركة بحيث يتم تحريك عناصر متعددة بشكلٍ منفصلٍ، أو في بعض الأحيان قد تريد فقط تصميم المسارات باستخدام ألوان تعبئة مختلفة. إذا قمت بجمع المسارات، فلن يكون ذلك ممكنًا بعد الآن. تحتاج إلى التأكّد من معرفتك لما يحتاجه المطور (أو أنت إذا كنت ستتعامل مع مرحلة التطوير أيضًا) ولما يريد القيام به مع الأشكال التي تعمل عليها، واتخاذ قرار الدمج أو عدم الدمج وفقًا لذلك. هذا سيوفر لكما الكثير من الوقت والخلاف. 5- إنشاء مرشّحات باستخدم مرشّحات SVG، وليس تأثيرات Photoshop إذا كنت تستخدم المرشّحات في قسم تأثيرات Photoshop ضمن خيار تأثير، فسيقوم Illustrator بتصدير التأثيرات التي تنشؤها كصور نقطية. مثلًا، إذا قمت بإنشاء ظل إسقاط باستخدام تأثير الضبابية Blur في فوتوشوب، فإن الظلّ المسقط المتولّد سيكون صورة نقطية مضمنة داخل SVG إما مضمنة داخليًا أو خارجيًا، باستخدام عنصر <image>. أنت بالتأكيد لا تريد ذلك عند العمل مع SVG. تحتاج لتوليد مؤثراتك كشيفرة SVG إلى استخدام مرشّحات SVG المتاحة: اذهب إلى تأثير (Effect) -> مرشّحات (SVG Filters (SVG اختر واستخدم أحد المرشّحات المتاحة في اللائحة. 6- اجعل لوح الرسم (Artboard) مناسبًا لرسمتك هل قمت يومًا بتضمين SVG في صفحة، وإعطائه ارتفاعًا وعرضًا محددين ثمّ وجدت أنه كان معروضًا بحجم أصغر من الحجم الذي حددته؟ في معظم الحالات، يكون السبب في ذلك هو وجود مساحة بيضاء داخل منفذ العرض (viewport) الخاص بـ SVG. يتم عرض منفذ العرض بالحجم الذي تحدده في صفحة الأنماط (style sheet) الخاصة بك، لكن المساحة الإضافية داخلها - حول الرسم - تتسبب في "تقليص" صورتك، لأنّ هذه المساحة البيضاء تأخذ مساحةً داخل منفذ العرض. لتجنّب ذلك، تحتاج إلى التأكّد من أنَّ لوح الرسم الخاص بك كبير بما فيه الكفاية ليناسب الرسمة بداخله، ولكن ليس أكبر منها. أبعاد لوح الرسم هي أبعاد منفذ عرض SVG المصدَّر، وأي مساحة بيضاء في لوح الرسم سيتم إنشاؤها كمساحة بيضاء داخل منفذ العرض. ليتناسب لوح الرسم مع رسمتك: حدد كامل الرسمة (أنا أستخدم الاختصار cmd/ctrl + A) اذهب إلى كائن (Object) -> ألواح الرسم (Artboards) واختر الخيار تناسب مع حدود العمل الفني (Fit to Artwork Bounds option). 7- استخدم اصطلاحات تسمية، وتجميع وطبقات جيّدة أعلم أنّ هذا يبدو كأنّه غير عقلاني، لكن يجب التأكيد عليه لعدة أسباب: ستتم ترجمة معرّفات وأسماء الفئات التي تستخدمها في محرر الرسومات إلى معرّفات وأسماء الفئات في الشيفرة المتولّدة. كلّما كانت هذه الأسماء أكثر منطقيةً وأكثر وضوحًا في تصنيف العناصر الخاصة بكل منها، سيكون هناك تعارضًا أقل عندما يعمل المطوّر مع الشيفرة. أنا لا أقول الآن أنّه يجب عليك التفكير في الأسماء المثالية - أنا متأكّدة أنّه لكلّ منّا طرق مختلفة لتسمية الأشياء ويمكن أن تكون التسمية واحدة من أصعب المهام، لكن تسمية المجموعات بشكلٍ مناسب تقطع شوطًا طويلًا. مثلًا، إذا كنت ترسم سيارة، فإنّه من المناسب استخدام معرّف العجلة لتسمية الطبقة أو مجموعة تغليف الأشكال المكوّنة للعجلة. إذا كنت تقوم بتجميع كل العجلات في مجموعة واحدة، فقد تعطيها معرّف العجلات. تؤثّر الأسماء البسيطة في التعبير عن العناصر والمجموعات وتحفظ الكثير من الوقت، خاصةً إذا كان المطوّر سيحرر الشيفرة ويعالجها يدويًا. لا يقوم Illustrator بعمل أفضل في تسمية الأشياء، لذا فإنّ تحديد الأسماء يساعد في تقليل كمية المخلّفات التي ينتجها. وبالتأكيد، سيكون هناك بعض التحرير الإضافي المطلوب للتخلّص من الخطوط السفلية المزعجة التي يصرّ Ai على توليدها، لكن استخدام الأسماء الصحيحة يساعد في جعل هذه العملية أسهل قليلًا. كما ذُكر سابقًا، ستُظهر النسخة التالية من Illustrator تحسّنًا كبيرًا في طريقة توليد SVG، متضمنةً المعرّفات المتولّدة. استخدم الطبقات لتجميع العناصر ذات الصلة. تُترجم الطبقات إلى مجموعات في الشيفرة، لذا يجب تسميتها بشكلٍ جيّد أيضًا. أنشئ طبقات/مجموعات لتجميع العناصر ذات الصلة معًا، خاصةً تلك التي قد تكون متحركة بالكامل. إذا لم يتم ذلك بالفعل في مرحلة التصميم فمن الممكن قضاء الكثير من الوقت في إعادة ترتيب وتجميع العناصر يدويًا من قِبل المطوّر. تأكّد من التجميع بشكلٍ مناسب لتوفير الوقت. يُعدّ التحدّث مع المطور في مرحلة التصميم وتصميم كيفية ستُنفّذ الرسوم المتحركة معًا هما أكبر موفران للوقت. إذا كانت الصور التي تقوم بإنشائها ستُستخدم لإنشاء SVG sprite، فإنّ الأسماء التي تستخدمها يمكن أن تُستخدم وستُستخدم من قِبل معظم أدوات الأتمتة لتوليد ملفات جديدة. لذا فإنّ استخدام أسماء واضحة ومناسبة سيؤدي إلى أسماء ملفات أنظف. 8- اختر أفضل خيارات تصدير مناسبة للويب بدءًا من Illustrator CC 2015.2 الذي تمّ إصداره في تشرين الأول 2015، يوجد تدفق عمل جديد لتصدير SVG (ملف> تصدير> SVG) لتصدير ملفات SVG مُحسّنة للويب لتدفقات عمل تصميم الشاشة والويب لديك. يمكنك أيضًا أن تختار تصدير الأغراض الفردية أو كامل لوح الرسم. راجع هذه المقالة لمزيدٍ من التفاصيل. في وقت كتابة هذا المقال، يأتي Illustrator مع مجموعة من خيارات التصدير التي تسمح لك بتوليد شيفرة SVG أفضل بشكلٍ عام. لتصدير الـ SVG الخاص بك: اختر ملف (File) -> حفظ كـ (Save As) اختر SVG من القائمة المنسدلة اضغط حفظ (Save) بمجرد النقر على حفظ، سيظهر مربع حوار يحتوي على مجموعة من الخيارات التي يمكنك تخصيصها، والتي ستؤثّر على شيفرة SVG المتولّدة: الخيارات الموضّحة في الصورة أعلاه هي الخيارات المستحسنة لتوليد SVG للويب. يمكنك بالطبع اختيار تحويل النص إلى حدود خارجية إذا لم تكن ترغب باستخدام خط ويب، وكما ترى يوفر لك Illustrator خيارًا أيضًا للقيام بذلك عند التصدير. يحدد خيار موقع الصورة (Image Location) فيما إذا سيتم تضمين أي صور نقطية داخليًا في الـ SVG الخاص بك أو خارجيًا مع رابط يدلّ عليه في الـ SVG. ومجددًا، هذا يعتمد على ما تحتاجه. يمكن أن تزيد الصور المضمنة داخليًا في الـ SVG حجم الملف بشكلٍ كبيرٍ. آخر مرة أرسل مصممٌ لي SVG مع صورة مضمنة فيه، كان حجم الملف أكثر من 1 ميغابايت! بعد حذف تلك الصورة (وبسبب تأثيرات Photoshop المستخدمة المذكورة سابقًا)، انخفض حجم الملف إلى أكثر من 100 كيلو بايت! لذا، اختر بحكمة. يمنحك خيار خصائص CSS الحرية لاختيار كيف تريد إنشاء الأنماط داخل الـ SVG: استخدام خاصيات التقديم، الأنماط المضمنة داخليًا، أو داخل وسم <style>. هذا أيضًا مسألة تفضيل وتعتمد على الطريقة التي تنوي بها التعامل مع SVG بمجرد تضمينها. إذا لم تكن الشخص الذي سيفعل ذلك، فتأكد من التشاور مع المطور لتحديد الخيار الذي يناسب احتياجاته على أفضل وجه. كلّما قلّ عدد المنازل العشرية، قلّ حجم ملف SVG. يجب أن تكون منزلة عشرية واحدة كافية بشكلٍ عام، لذا سأتّبع ذلك. لاحظ أنّه إذا اخترت 3 أو 4 منازل عشرية، مثلًا، ثمّ استخدمت أداة تحسين لتحسين SVG وخفض هذا الرقم إلى 1، فقد ينتهي بك الأمر إلى SVG معطوب، لذا من الأفضل اختيار هذا الخيار في وقت مبكر. هناك المزيد في لائحة الخيارات التي قمت بتغطيتها. كتب Michaël Chaize من Adobe مقالةً ممتازةً حول لائحة التصدير توضّح ما يفعله كل خيار تمامًا. أوصي بشدّة بمراجعة مقالته: تصدير SVG للويب مع Illustrator CC الآن، في وقت كتابة هذا المقال، سيبقى Illustrator يولّد شيفرةً غير ضرورية مثل البيانات الوصفية للمحرر، والمجموعات الفارغة، من أمورٍ أخرى، لذا ستحتاج إلى تحسين الـ SVG بشكلٍ أكبر بعد تصديره، سواء كان ذلك باليد، أو باستخدام أداة تحسين SVG مستقلة. لكن قبل أن ننتقل إلى جزء التحسين، أريد أن أشير إلى أنّك قد ترغب أو لا ترغب في التحقق من خيارٍ إضافي أثناء حفظ SVG: خيار "استخدم ألواح الرسم" ، في لائحة الحفظ: يعدّ هذا الخيار مفيدًا عندما تعمل مع صور SVG متعددة (مثل الأيقونات) وتستخدم لوح رسم لكلّ أيقونة. سيؤدي تصدير ألواح رسم متعددة إلى توليد ملفات svg. متعددة، ملف لكل لوح رسم (واحد لكل أيقونة). سيتم تعطيل هذا الخيار بشكلٍ افتراضي إذا كنت تعمل مع لوح رسم واحد. يعتمد اختيار تصدير ملف SVG واحد أو عدة ملفات SVG على كيفية تضمين SVG. مثلًا، إذا كنت تريد إنشاء SVG sprite لنظام أيقونات SVG، فهناك عدة طرق يمكنك من خلالها إنشاء واستخدام الـ sprite، وكلّ منها تتطلب منهجًا مختلفًا: تتطلّب إحدى التقنيات فصل الأيقونات في البداية، بينما تتطلّب الأخرى أن تكون الأيقونات جزءًا من صورة واحدة. سأكتب منشورًا مفصّلًا حول SVG sprite وخيارات لوح الرسم، لكن حتى ذلك الحين، يمكنك أن تأخذ نظرة عامة حول التقنيات المختلفة لـ SVG sprite في المقالة التالية التي كتبتها لـ24Ways.org: نظرة عامة حول تقنيات إنشاء SVG sprite للتحسين أو لعدم التحسين يوصى عادةً بتحسين SVG بعد تصديره من محرر رسومات باستخدام أداة تحسين مستقلة. أداة التحسين الحالية الأكثر شيوعًا هي الأداة المعتمدة على NodeJS والتي تسمى SVGO. لكن قد لا يكون من الأفضل دائمًا تحسين SVG، خاصة إذا كنت تنوي تحريكه. إذا كنت تنوي كتابة SVG كنص برمجي و/أو تحريكه، فمن المحتمل أن تقوم بإعداد بنية وثيقة معينة - غلاف المجموعات، وأسماء المعرفات التي لا تستخدمها/تشير إليها داخل الـ SVG لكنك تنوي استخدامها في جافاسكربت أو غيرها. ستتغير البنية إذا قمت بتحسين الـ SVG باستخدام SVGO (أو أي أداة تحسين أخرى). عادةً ما تزيل أدوات التحسين أي مجموعات ومعرّفات غير مستخدمة، بالإضافة إلى أنّها تطبّق العديد من التغييرات على الـ SVG للتأكد من تحسينه بشكلٍ جيد. لقد قمت بتحسين ملف SVG مرةً بعد تطبيق رسم متحرك عليه باستخدام <animate>. كان ملف الـ SVG معطوبًا والحركة بداخله، لأنّه تم تغيير البنية بالكامل. وهذا شيء يجب تذكره قبل تحسين SVG. تجنّب التحسين مستخدمًا أداة تحسين، إذا قمت بتحرير و/أو توليد SVG يدويًا ببنية معينة تحتاجها، وحسّن يدويًا قدر الإمكان. يمكن إزالة بعض مخلفات التحرير في بداية ونهاية الـ SVG يدويًا بسهولة، والمخلفات الأخرى مثل البيانات الوصفية والفئات المتولّدة من قِبل برامج التحرير التي لا تحتوي على خيارات تحسين SVG - مثل Sketch - قد يكون من الصعب تحسينها يدويًا. عمومًا، أنا لا أستخدم Sketch لتوليد SVG معقدة. أستخدم Illustrator أو Inkscape؛ إذ يأتي الأخير مع لائحة تصدير افتراضية تعطيك الكثير من الخيارات لتحسين الـ SVG قبل تصديره (انظر الصورة أدناه). يولّد Inkscape أنظف شيفرة SVG في وقت كتابة هذا المقال. أي إذا اخترت خيار تحسين SVG، لكن ضبابية واجهة المستخدم على شاشة شبكة العين وكذلك اعتمادها على X11 على OS X يجعل من الصعب استخدامه، لذلك أنا متمسكة حاليًا بـ Illustrator. إذا كنت تحتاج/تريد تحسين الـ SVG الخاص بك فإنني أنصحك بأداة SVGO، إذ يأتي SVGO مع مجموعة من الإضافات التي يمكن دمجها مع أي نوع من تدفقات العمل تقريبًا. 9- تواصل. تواصل مبكرًا ربما كان أهم نصيحة يمكنني تقديمها هو التواصل والقيام بذلك مبكرًا في عملية التصميم. أفترض أنّك الآن - المصمم الذي ينشئ SVG - لست الشخص نفسه المسؤول عن تطوير SVG (كتابة نص برمجي، التحريك، التضمين، …إلخ). تتطلّب كل واحدة من النصائح السابقة تقريبًا معرفة مرحلة التطوير وما ينوي المطور القيام به مع الـ SVG - كيف ينوون تضمينه، وكتابته كنص برمجي، وتصميمه، وتحريكه. لذا إذا لم تكن أنت نفس الشخص الذي يصنع القرارات لكلا المرحلتين، وما لم تكن تريد تضييع الكثير من الوقت في تكرار وتحرير الـ SVG، تحتاج إلى التأكّد من معرفتك لما يحتاج لمطور أن يفعله مع الـ SVG وما المنهجية (أو المنهجيات) التي سيتبعها. إذا كنت تعمل في مشروع له موعد نهائي ضيق، فمن المحتمل أنك لا تستطيع أن تضيع وقتًا كبيرًا في إجراء تغييرات ومراجعات على أصول الصور، عندما يمكنك تجنب ذلك عن طريق التواصل مبكرًا. يمكن أن يكون المصممون والمطورون أفضل أصدقاء لبعضهم بعضًا. تتطلّب طبيعة SVG أن تكون مراحل التصميم والتطوير مفتوحة على بعضها بعضًا، وهذا بدوره يتطلب من المصمم (المصممين) والمطور (المطورين) التحدّث قبل بدء عملية التصميم وطوال العملية أيضًا . ترجمة -وبتصرف- للمقال Tips for Creating and Exporting Better SVGs for the Web لصاحبته Sara Soueidan
  5. نستخدم نحن المطوّرين ومُصمّمي الواجهات CSS في التنسيق والتَمَوْضُع (positioning)، وفي إنشاء مواقع تتسم بالجماليّة والمظهر الخلّاب، ونستخدمها غالبًا في إضافة الحركة إلى الصفحات باستخدام التنقّل (transitions) أو التحريك (animations)، ولكنّنا عادةً لا نتعمّق، ولا ندخل في خفايا خاصّيات CSS المُعقّدة. يُمكن للتحريك أنّ يكون أداةً قويّة في مُساعدة زوّار مواقعنا وعُملائنا على فهم تصميم الموقع بالشكل الصحيح، ولذلك يوجد بعض المبادئ والتي بتطبيقها يمكن الاستفادة من التحريك بالشكل الأمثل. إنّ هذه المبادئ ليست بالجديدة، وهي عبارة عن مُمارسات عمليّة وتجارب طويلة من عالم ديزني، فقد نُشرت هذه المبادئ الاثنا عشر للتحريك بكتاب وهو بعنوان: "وهم الحياة: الرسوم المُتحركة في ديزني" في عام 1981، وصفت وصوّرت هذه المبادئ كيف يُمكن للتحريك أنّ يُستخدم في سلب عقل المُشاهدين في عالم وهميٍّ قابل للتصديق. سأتناول في هذه المقالة، كلًا من المبادئ الاثنا عشر، ومُناقشة كيف لها أنّ تُطبّق في صناعة صفحات الويب مُستخدمًا الأمثلة التوضيحيّة، وإتاحة الوصول إلى مصدر شيفرة HTML و CSS الخاصّة بهذه الأمثلة عبر حساب الأكاديمية في Github. التمدّد والانكماش (Squash and Stretch) إنها المفهوم القائم على أنّ للأجسام كتلة فيزيائيّة، وبتحركها يجب أن تبقى الكتلة ثابتة دون أن تتغيّر، فستتوسّع الكرة عندما تصطدم مع الأرض، ولكنّها أيضًا ستصبح أقصر باعتبار أنّ كتلتها سيُعاد توزيعها. يُمكن الاستفادة من هذا المفهوم عند إنشاء الكائنات الّتي نُريدها أنّ تبدو فيزيائيّة، مثل الأشخاص، الأشياء، أو تنطط الكرات. يُمكن تجاهل هذه المبدأ عند التعامل مع عناصر صفحة الويب، فلا ترتبط عناصر الـ DOM بالضرورة مع الأجسام الفيزيائيّة، ويُمكن لها أنّ تكبر وتتقلّص على المُتصفّح كما تقتضي الحاجة، فعلى سبيل المثال، يُمكن للزر أنّ يكبر ومن ثم يتلاشى، أو يُمكن لرسائل الخطأ أنّ تظهر وتختفي كما يحلو لها. ولكن في حقيقة الأمر، يُمكن الاستفادة من مبدأ التمدّد والانكماش في إعطاء الكائن أو الجسم صفات الكتلة الفيزيائيّة، ويُمكن للتغيرات الصغيرة في الشكل إنشاء تأثيرات طفيفة ولكنّها في نفس الوقت مُلفتة للنظر. التهيئة (Anticipation) لا تحدث الحركات فجأةً، ففي الواقع العمليّ، تَنتج الحركة عادةً تدريجيًا، سواءً كان ذلك في دوران الكرة قبل السقوط من على الطاولة، أو عندما يثني شخصٌ ما قدميه استعدادًا للقفز. يُمكننا استخدام ذلك في جعل التحوّل (transitions) والتحريك (animations) في CSS أكثر حيويّةً وواقعيّة، ويُمكن لهذا المبدأ أنّ يكون على شكل ارتداد خفيف للكرة، ليُساعد المُستخدم على إدراك ما الّذي يتغيّر ويتتبّع مسار الجسم على الشاشة. فعلى سبيل المثال، يُمكن لعنصر من عناصر الصفحة أنّ يتقلّص قليلًا قبل أنّ يكبر في الحجم عند حركة المرور (hover)، أو لنقل مثلًا عند إضافة عناصر قائمة (items) جديدة إلى قائمة، فيُمكن أنّ يُمهد لهذه الحركة عبر إبعاد باقي العناصر وإفساح المجال لها أوّلًا. التقديم (Staging) يتأكّد هذا المبدأ من أنّ الجسم أو الشيء هو عنصر المشهد الرئيسي، وهو عندما تفسح باقي الأجسام الأخرى أو جوانب المشهد المجال لمكان حدوث الفعل الرئيسي، يعني هذا إما وضع الفعل الرئيسي في مكان بارز للعيان، أو حجب باقي العناصر بهدف التركيز على ما يجب للمُستخدم أنّ يراه. إن أردنا قولها بلغة ومُصطلحات الويب، فإن أحد الأساليب قد يكون في استخدام تغشية لمُحتوى مُعيّن دون آخر، أو ربما إضافة طبقة داكنة على الصّفحة، ومن ثُمّ وضع المُحتوى في الواجهة ليَظهر هذا المُحتوى بارزًا للنظر والاهتمام. يُمكن استخدام أسلوب آخر وهو الحركة، فعندما تتحرّك أجسام عدّة، فمن الصعب معرفة أي منها جديرٌ بالاهتمام والمُتابعة، ولكن إنّ توقّفت جميع التحركات وجسم واحد تحرّك، ولو بحركة صغيرة، فمن السهل جدًا اكتشافه. يُستخدم هذا الأسلوب عادةً مع زر الحِفظ (save)، بحيث يتذبذب أو يتمايل أو يومض بخفّة ليوضّح للمُستخدم أنّ عليه حِفظ المُستند قبل المُتابعة، مع الحفاظ على بقية أجزاء الصفحة ساكنة وبدون أدنى حركة، مع العلم أنّ أي حركة ولو طفيفة ستبرز وتكون واضحة للعيان. الحركة المُفصّلة والحركة من توقّف إلى توقّف (Straight-Ahead Action and Pose-to-Pose) إن الفعل straight-ahead يكون عندما يتمّ رسم كل إطار صورة (frame) لإتمام التحريك، أما الفعل pose-to-pose (توقّف إلى توقّف) يكون عندما يتمّ رسم سلسلة من الإطارات المفتاحيّة (keyframes) وتُرسم الفترات فيما بينها لاحقًا، عادةً من قِبل مُساعد. يُستخدم في عالم الويب معظم الأحيان التحريك من نوع pose-to-pose، فمثلًا الانتقال (transition) بين الإطارات المفتاحيّة (keyframes) يُمكن أنّ تتم معالجتها من قبل المُتصفّح، والذي يُقحم الاختلاف بين كل إطار ويرسم عددًا منها أيضًا بهدف جعل التحريك أكثر سلاسةً وواقعيّة. يوجد استثناء وحيد، وهو دالة التوقيت steps، فمع هذه الدالة، سيخطو المُتصفّح خطوات على عدد الإطارات المُحدّدة، وبهذه الطريقة ستتمكن من رسم سلسلة من الصور وجعل المُتصفّح يعرض كل منها تتابُعيًا، ليُنشئ بذلك حركة بالأسلوب **Straight Ahead Action”. توابع الفعل وتداخله (Follow Through and Overlapping Action) لا تحدث الأشياء دائمًا في نفس الوقت، فعندما تتوقّف سيارة فجأةً، فإنّها تميل إلى الأمام، مع تصاعد الدخان نتيجة احتكاك العجلات مع الأرض، ومن داخل السيارة يواصل السائق ميلانه نحو الأمام إلى حين توقّف كل حدث بشكل مُنفصل. إن هذه التفاصيل ما هي إلا أمثلة على توابع الحركة وتداخل الحركة، ويُمكن استخدام هذا المبدأ على الويب للمُساعدة على التأكيد أنّ شيئًا ما قد توقّف الآن لأنّه يجب أن يتوقّف، وليس أنّه قد توقّف عن التحريك بشكل مُطلق، على سبيل المثال، عنصر قائمة أُضيف إلى القائمة قد ينزلق، ليتقدّم شيئًا ما أكثر من اللازم، ومن ثُمّ يُصحّح نفسه إلى التَمَوْضُع الصحيح. إن إنشاء حركة ذات طابع تداخلي، يتطلّب إنشاء عناصر تتحرّك خطًا مُختلفة وذات فروقات طفيفة عن بعضها البعض، وفي الحقيقة هذا الأسلوب مُستخدم بشكل جيّد في أنظمة التشغيل iOS، فعندما يتمّ التنقل بين صفحات التطبيق، بعض الأزرار والعناصر ستتحرّك بمُعدّل مختلف عن بعضها، ليظهر التأثير الكلي في النهاية بشكل مُفعم بالمرونة والسلاسة وأقل سطحيّة من إذا كان كلُ شيءٍ يتحرّك دفعة واحدة وبنفس المُعدّل، وهذا التنقل المتوحد في كينونة واحدة يُعطي المُشاهد أو المُستخدم فترةً زمنيّة ليُدرك هذا التغيير الحاصل بالشكل المطلوب، والابتعاد عن الالتباسات. قد يُستخدم هذا الأسلوب في عالم الويب عبر تجميع التنقلات (transitions) أو التحريك (animations) تتابعيًا، بهدف إنشاء تأثيرات تظهر بمُعدّل سرعة مُختلف فيما بينها. التباطؤ والتسريع (Slow In and Slow Out) لا تنتقل الأجسام من السكون التام إلى السرعة القصوى فورًا، بل تميل الأجسام إلى رفع السرعة تدريجيًا، والتَبْطيء منها قبل التوقّف، فبدون التسارع والتباطؤ، ستكون الحركة وكأنها حركة آلة (روبوتي) يُعرَف التباطؤ والتسريع في عالم CSS بالمُصطلح easing (تسهيل)، ويُستخدم كدالة توقيت (timing function)، وهو طريقة في وصف وتحديد مُعدّل التغيّر خلال مسار التحريك. يُمكن وباستخدام دالات التوقيت جعل الأجسام المُتحركة تبدأ بطيئةً وترفع من السرعة (الدالة ease-in)، أو تبدأ سريعةً وتخفّف من السرعة (الدالة ease-out)، ويُمكن من أجل التأثيرات الأكثر تعقيدًا استخدام دالّة التوقيت cubic-bezier. التقوّس (Arc) لا شك أنّ الأجسام ستبدو أكثر حيويّة باستخدامها حركات التباطؤ والتسريع المُتبعة في المبدأ السابق، ولكن في حقيقة الأمر إن الأجسام نادرًا ما تتحرك بحركة مستقيمة، فهي تميل إلى اتباع انحناءات مقوّسة. يُمكننا تحقيق هذه النوع من الحركات المُقوّسة مع CSS بطريقتين، تكون الطريقة الأولى بالجمع بين أكثر من تحريك، فالحركة الخاصّة بتنطط وارتداد الكرة، يُمكن تطبيقه عن طريق عمل تحريك أوّل يجعل الكرة تتحرّك صعودًا ونزولًا، بينما تحريكٌ ثاني يجعل الكرة تتحرّك إلى جهة اليمين في نفس الوقت، عندها ستظهر الكرة عبر الشاشة وهي ترتد من الأرض وبشكل مقوّس. تكون الطريقة الثّانية عبر تدوير العنصر نفسه، حيثُ بإمكاننا التعديل على مركز دوران الجسم عبر ضبط مبدأ التغيّر (transform origin) ليُصبح خارج جسم العنصر، فعندما ندوّر الجسم، فإنه سيدور في تقوّس. الفعل/الحدث الثانوي (Secondary Action) بينما الحدث الرئيسي يحدث، يُمكن لحدثٍ ثانويٍ أن يُساعد على التأكيد منه أو حتَّى أنّ يزيد عليه، ربما على سبيل المثال، تأرجح ذراعي شخص يمشي (المشي حدث رئيسي والتأرجح حدث ثانوي) أو تنطط كرة (حدث رئيسي) مع ظهور بعض الغبار (حدث ثانوي) عند الارتطام. يُمكن رؤية هذا المبدأ على مواقع الإنترنت، عندما تبعد العناصر من نفسها لإفساح المجال للعنصر الجديد، كما يحدث عند سحب عنصر قائمة ووضعه في منتصف القائمة. التوقيت (Timing) إن توقيت التحريك هو الوقت المُستغرق في إتمام حركته، فيُمكن للتوقيت أنّ يُستخدم في جعل الأجسام الوزنة تبدو بطيئة في حركتها، أو في إضافة طابع مُميّز وحيوي في الحركة نفسها. إن التعديل وتسوية/ضبط الوقت في صفحات الويب بسيطٌ للغاية، فكل ما يتطلب فعله هو التعديل على قيمتي الخاصيتين animation-duration أو transition-duration. المُبالغة (Exaggeration) يُستخدم أسلوب المُبالغة بشكل كبير مع أفلام الرسوم المُتحرّكة، فيُمكن باستخدامه جذب نظر المُشاهد إلى حركات أو أفعال مُعيّنة، لتجعل هذه المُبالغة من الرسومات أكثر إثارة أو ربما في بعض الأحيان أكثر هزليّة، فعندما يُحاول الذئب الانقضاض على فريسته، فربما يجعل الرسام من فكاه مفتوحان على مصراعهما أكثر من المُعتاد بهدف إضافة شيء من الرعب أو الهزليّة إلى المشهد. وفي صفحات الويب، يُمكن للأجسام أنّ تتوسّع وتتقلّص بهدف التأكيد عليها وجذب الانتباه إليها، على سبيل المثال عند ملئ نموذج ما (form)، فيُمكن للقسم النشط أنّ يكبر بينما بقية الأقسام تنكمش أو تتلاشى (fade). الرسم المتين (Solid drawing) عند تحريك الأجسام في الأبعاد الثلاثة (three dimensions)، يجب أنّ يكون الاهتمام مُنصبًا على أنّ هذه الأجسام تتبع قواعد الرسم المنظوري، فالناس مُعتادة على العيش والتعامل مع عالم ثلاثيّ الأبعاد، ولذلك عندما لا يبدو على الأجسام كما لها أنّ تكون في الواقع، فستبدو للمُشاهد غريبةً وغير مقبولة. تدعم آخر إصدارات المُتصفّحات الأبعاد الثلاثيّة جيّدًا، يعني هذا أنّه يُمكننا تدوير وتوضيع الأجسام في الصفحة ليتولّى المُتصفّح عمليّة التحوّل بنفسه. عامل الجذب (Appeal) إن عامل الجذب هو خصائص ومُميّزات العمل الفني وكيف يُمكن له أنّ يجعل منا مُتصلين ذهنيًّا مع مقصد ونيّة الفنان، فهو كجاذبيّة المُمثّل (الكاريزما)، ففي النهاية الانتباه إلى التفاصيل واتحاد الحركات مع بعضها البعض تناغميًا تجعل من النتائج نتائج مُميّزة وذات ظهور خلاب. يُمكن للتحريك المصنوع بأيدٍ احترافيّة وبعناية خاصّة أنّ يُنشئ جاذبيّة ومظهر ذو شأن على صفحات الويب، وقد أدركت بعض الشركات ذلك، فاستفادت Stripe من التحريك وسخرته في إضافة مصداقيّة إلى شاشة الدفع (checkout) الخاصّة بهم. استخدم التحريك إن استخدام المبادئ السابقة له فضلٌ كبير في تحسين التحريك، فالرسوم الّتي تحافظ على الوزن الفيزيائي للأجسام والتغييرات ذات الطابع الحدسي، وتستفيد من الحدث الثانوي مع التوقيت المُناسب سيجعل منها ذو جودة عالية لُساعد في تقديم إضافة نوعيّة وذات جودة إلى المُحتوى. يُنصح، وعندما تكون الفرصة سانحة، في إضافة بعض من التحريك والرسوم إلى صفحات الويب، وخاصّة مع استخدام هذه المبادئ، والّتي ستُضيف شيئًا من الجماليّة والجاذبيّة للموقع ليتميّز عن بقيّة أقرانه. ترجمة – وبتصرّف– للمقال Animation Principles for the Web.
  6. سنتكلم في هذا المقال عن أفضل مكاتب التحريك في ‏CSS، والتي تساعدك في حفظ وقتك عند تصميم ‏موقع الويب الخاص بك من خلال استخدامك لهذه المكاتب التي تضفي بعض الديناميكية والتفاعل إلى ‏عملك، حيث تحوي هذه المكتبات على العديد من عناصر ‏التحريك والمؤثرات لأي نوع من أنواع عناصر صفحات الويب كالنصوص، الصور، الإطارات، الأزرار، والبطاقات والعديد غيرها. إن لمكاتب التحريك في CSS العديد من الأنماط styles والتي تستخدم تأثيرات خاصة بها (يمكن الإطلاع على المزيد في CSS effects)، وبالتالي مهما كان النمط الذي تبحث عنه سواء بسيط وسهل، أو ممتع مؤثر ستجد مكتبة مفيد لك. تتنوع المؤثرات من المنزلقات إلى التلاش والدوران كما يوجد العديد من التأثيرات الأكثر عمقًا وتخصيصًا مثل مؤثرات النبض، ودقات القلب وغيرها... باختصار هذه المكتبات توفر لك ماتريده، ويمكن تثبيتها بسهولة داخل موقعك كما أن غالبيتها خفيفة الحجم ومُتجاوبة responsive. Hexa تعتبر Hexa مكتبة مذهلة للتحريك، بسيطة وخفيفة الحجم. يمكن استخدام مؤثرات التحريك التي تقدمها لإحياء عناصر صفحة الويب من نصوص، صور، أيقونات وبقية العناصر الأخرى. Vivify إن Vivify هي مكتبة تحريك CSS مجانية تستطيع من خلالها إضافة المؤثرات إلى الأزرار، الصور وغيرها، وتحوي على العديد من المؤثرات التي يمكن الاختيار فيما بينها مثل الكرة، النبض، الاصطدام من اليمين واليسار، الاهتزاز، الانفلات، القفز، التلاشي، الدوران الشاقولي، السحب، الطي... Tachyons-animate تعتبر Tachyons-animate مجموعة من صفوف CSS ذات الهدف المحدد وهو تنسيق الحركة باستخدام CSS. في حال كنت تريد الحصول على أكثر من مجرد تحريك فباستطاعتك استخدام هذه الأداة لأنها لاتحوي على أي مؤثرات مُحددة مسبقًا وإنما تحوي على صفوف CSS فقط تستخدمها ضمن موقعك تبني من خلالها الحركة التي ترغب بها ولكنها توفر عليك الكثير من الوقت. ‏Infinite – useful CSS animations تعتبر Infinite-useful CSS animations مجموعة صغيرة من عناصر التحريك المفيدة للغاية والتي يمكن استخدامها لتوليد عناصر نابضة بطريقة التحكم بشفافية ومقدار التوسع في العناصر، إنشاء رسوم متحركة للتنبيه، تدوير العناصر وغيرها. Motion UI تعتبر Motion UI مكتبة Sass قوية تفيد في إنشاء التحريكات والانتقالات، وقد أوجدت هذه المكتبة بالأساس كمكون ضمني في Foundation لتصميم البرامج، ولكن يمكن استخدامها كمكتبة منفصلة الآن، حيث يمكن استخدامها في إضافة تأثيرات السرعة، الانزلاق، تغيير الحجم وغيرها.. DynCSS إن DynCSS هي مكتبة عظيمة تستخدم في التحريك والتي تقوم بتفسير الـ CSS الخاص بك من أجل إنشاء قواعد dyn بسيطة وديناميكية تبث الحياة في موقعك. All animation تعتبر All animation.css أداة تحوي العديد من عناصر التحريك الممتعة لجعل مشروعك أكثر تفاعلية وجاذبية بالنسبة للمستخدم، وهي عبارة عن عدة مؤثرات وعناصر تحريك ممكن استخدامها لإضافة تأثيرات ‏‎3D‎‏ وغيرها. Animate.CSS إن Animate.CSS هي مكتبة تحريك أخرى تعمل على جميع المتصفحات وتُستخدم لإضافة مؤثرات مثل الاهتزاز، ‏الاضطراب، النبض، التأرجح، التمايل..‏ Hover.CSS تعتبر Hover.CSS مجموعة CSS3 خاصة بتأثيرات التأرجح hover effects وتُستخدم على الروابط ، الأزرار، الشعارات، SVG، الصور وغيرها من العناصر. كما أنها متوفرة كـ CSS، Sass، و LESS. Effect.CSS تعتبر مكتبة Effect.CSS مكتبة CSS تُستخدم لإضاف انتقالات حساسة للموقع بهدف تحسين تجربة المستخدمين، حيث تقوم بإنشاء انتقالات CSS وتحريكات للأزرار، القوائم، الانتقالات بين الصفحات، العناوين، التلميحات، علامات التبويب، الإطارات وغيرها... ‎Magic CSS تحوي Magic CSS على عناصر تحريك CSS3 بمؤثرات خاصة تضفي روحًا خاصة للموقع مثل المؤثرات السحرية، المؤثؤات الساكنة، المناظير، الدوران، التحجيم، الانزلاق.. CSSHAKE إن CSSHAKE هي مجموعة من صفوف CSS لتحريك عناصر الصفحة DOM، وتثبيت هذه المكتبة سهل للغاية حيث يمكن تنزيل ملفات منفصلة لكل تأثير تحريك، توسيع، أو تصغير. Repaintless CSS تعتبر Repaintless CSS مكتبة CSS خاصة بالتحريك خفيفة الحجم تحوي عشرات المؤثرات التي تجعل الموقع أكثر فاعلية بدون التأثير على سرعته، حيث يمكنك إضافة مؤثرات الانزلاق بكل سهولة. Tuesday إن Tuesday هي مكتبة CSS منفصلة تستخدم لإضافة تأثيرات الدخول والخروج مثل التمدد والتقلص، الهبوط، نزول المطر، المفصلات. Obnoxious تحوي Obnoxious تأثيرات ممتعة ولكن قد لاتناسب جميع المواقع ولكن بالتأكيد في حال استخدامها ستجعل موقعك يبرز بين المواقع الأخرى. من هذه المؤثرات الاهتزاز، زيادة الحجم، الطي، الالتواء... Flutter – CSS Image Hover Effects & Lightbox تحوي مكتبة Flutter على 12 مؤثر تحريك خاص بالتأرجح hover فوق الصور، أنظمة الأعمدة الثنائية أو الثلاثية، بالإضافة إلى 4 أنواع من الإضاءة وغيرها. Skloading – CSS3 Animations تعتبر Skloading مكتبة تحريك CSS3 بتصميم قابل للتخصيص بشكل كامل حيث يمكنك تحميل واستخدام هذه التحريكات الخاصة بهذه المجموعة ضمن مشروعك. Viavi CSS3 Scroll Effects يمكنك من خلال Viaviتجربة مجموعة المغازل ‏spinners‏ والمحملات ‏loaders‏ التي يمكن استخدامها لجذب انتباه ‏المستخدم، وهي تصميمات مُتجاوبة بشكل كامل كما أنها تتكيف بشكل رائع مع أي حجم للشاشة. CSS Bubbles and Tooltips إن هذه المكتبة ( يمكن الإطلاع على المزيد من خلال CSS Bubbles and Tooltips) تقدم لك التلميحات والفقاعات في CSS والتي ستساعدك في حفظ الوقت، حيث ستجد مجموعة من أشكال الملاحظات جاهزة على شكل مربع أو غيوم أو فقاعات على شكل قلب وكذلك تلمحيات للموقع، النصوص، الواجهات، الشرائط والأزرار. ‎ Animatia – CSS Image Hover Effects إن Animatia هي مكتبة خاصة بتأثيرات التأرجح hover التي تحدث للصور أو عناصر CSS أخرى مثل الأزرار وغيرها. CSS Box and Text Shadows يمكنك تنزيل صناديق CSS و ظلال النصوص (للإطلاع CSS Box and Text Shadows) واستخدامها مباشرة في موقعك وهي عبارة عن مجموعة فيها 40 تأثير ظلال يمكن تطبيقها على النصوص، الأزرار، الصور وغيرها. HoverMe تعد HoverMe مجموعة رائعة من عناصر تحريك CSS3 التي تحوي 4 صور أزرار، 10 أزرار تحميل، و 8 تحريكات متقدمة وغيرها. ‎Wickedcss إن Wickedcss هي مكتبة تحريك CSS3 تمنحك المتعة في التعامل معها فهي تحوي العديد من المؤثرات مثل التقافز pound، الانزلاق، النبض، دقات القلب، الدوران Woah إن مكتبة Woah هي لمطوري الويب غريبي الأطوار، حيث يمكن استخدامها لإضافة تحريكات مميزة لأي عنصر من عناصر صفحة الويب. Motion CSS تعتبر Motion CSS مكتبة تحريك ممتعة وسهلة التثبيت فلا تحتاج لاستخدامها سوى إلى ربطها مع ملف CSS ثم يمكنك استخدام صفوف محددة لأي عنصر من عناصر الصفحة لتحريكه. ترجمة -وبتصرّف- للمقال 25 Best CSS Animation Libraries لصاحبه Iggy مصمم موقع Line25
  7. يبدو الروبوت الخاص بك بشكل جيّد، لكن لونه الرمادي الافتراضي رتيب. في هذا الفصل ستتعلّم كيفيّة تطبيق خامات بلندر ومفاتيح الشكل لإظهار الروبوت. أرجوا متابعة السلسلة من بدايتها لفهم عملية تصميم هذا الروبوت منذ البداية. خامات بلندر بلندر لديه نوعان من الرندر أو التصيير (وهي عمليّة إخراج ومعالجة الصورة النهائية) مدمجين بداخله، الأوّل الرندر الداخلي الأساسي والرندر المسمى Cycles. عملية الرندر في بلندر هي تحويل المشهد ثلاثي الأبعاد إلى صورة أو فيديو ثنائي الأبعاد. في أعلى شاشة العرض 3D، تنقّل بين رندر بلندر ورندر Cycles. الآن لنضِف الخامات. في بلندر، الخامات تخلق صورة تخيّليّة عن عنصر ما بأنه مصنوع من مادة محددة. اختر Materials tab من Properties panel، ثمّ اضغط على زر New. اضغط على حقل Color لفتح قائمة اختيار الألوان color picker. غيّر اللون إلى أزرق جميل. أو وردي. أو بنفسجي. أو برتقالي. كما تحب! ثمّ افتح Settings واسحب اللون الأزرق إلى حقل لون العرض Viewport Color. الروبوت سيظهر الآن بالأزرق في شاشة العرض 3D. اضغط TAB للتعديل، ثمّ اضغط L لاختيار العينين، الرقبة، الذراعين واليدين. في قائمة الخامات، اضغط + وأشر لإضافة خامة جديدة إلى الروبوت. ثمّ اضغط على زر New. اختر الرمادي الغامق من color picker. اختر Assign لتعيين اللون على العناصر المختارة. أخيرًا، اسحب اللون الجديد من مجموعة الألوان إلى لون العرض Viewport Color الموجود أسفل Settings. قرّب المشهد إن احتجت. واختر دائرة العين. اضغط على + مرة أخرى، واضغط New. احتفظ باللون الأبيض واضغط Assign. اسحب اللون إلى لون العرض Viewport Color. اضغط مع الاستمرار على ALT + SHIFT واضغط RMB لاختيار طوق الرقبة وقاعدتها. اضغط + في قائمة الخامات ثمّ اضغط New. اختر الرمادي الفاتح ثم Assign. اسحب اللون إلى لون العرض Viewport Color. اضغط Tab لـ object mode. أيبدو جيدًا! مفاتيح الشكل Shape Keys سنقوم الآن بإضافة مفاتيح الشكل لتحريك الفم والرقبة. مفاتيح الشكل تَستَخدم نقاط عنصر لتعديل شكله. اختر قائمة Object Data من لوحة Properties. تحت Shape Key، اضغط +. هذا ينشئ مفتاح شكل جديد يسمى Basis. سنقوم بترك هذا وننشئ مفتاح شكل آخر بضغط + مرة أخرى. لقد أنشأنا الآن مفتاح شكل جديد، واسمه Key 1"". أعد كتابة اسمه إلى “Mouth”. اضغط Tab لتعديل الوضع واضغط Z. اضغط CTRL + TAB واختر حافة. من خلال الضغط مع الاستمرار على عجلة الفأرة، حرّك الفم ليكون ثلاثة أرباع منظور العنصر. ثمّ انقر RMB لتحديد أعلاه، آخر حافة للفم. اضغط NUM3 للتحويل إلى الرؤية الجانبية. ثمّ اضغط SHIFT + S واختر Cursor to selected، لتحريك المؤشر إلى الحافة المحددة. في أسفل قائمة 3D View يوجد قائمة Pivot Point. اختر 3D Cursor. اضغط L لاختيار الفم بالكامل. ثمّ قم بتدوير الفم على المؤشر 3D بضغط R، وX لتقييد حركته على محور X وادخل 20، ثمّ اضغط ENTER للتأكيد. اضغط TAB لتعديل الوضع واضغط Z للتحويل إلى العرض المصمت. حاول تجربة مفتاح الشكل الجديد بتحريك شريط Value الموجود تحت Shape Keys. اختر Basis، ثمّ اضغط + لإضافة مفتاح شكل جديد. واعد كتابة اسمه إلى Head"". اضغط TAB لتعديل الوضع واضغط L لاختيار الرأس، الرقبة، الفم والعينين. اضغط G للإمساك بالعناصر المحددة وZ لتقييد الحركة على محور Z فقط، ثمّ ادخل .2، واضغط ENTER للتأكيد. اضغط TAB للعودة إلى وضع العنصر، وقم بتحريك شريط Value في الاتجاهين لرؤية الرأس يتحرك للأعلى والأسفل. رائع، أليس كذلك؟ في الفصل القادم سنقوم بتحريك الذراعين. ترجمة – وبتصرّف – للمقال How to Model and Animate a Robot, Part 2: Blender Materials & Shape Keys لصاحبه Jared
  8. تُقدّم أشباه العناصر (pseudo-elements) عناصر DOM إضافيّة وبدون عناء يُذكر، فهي تَسمح للمُطوّر في إضافة مُحتوى إضافي إلى الصفحات وبدون إضافة أيًا من عناصر HTML على الصفحة، كما يُمكن لها أنّ تتحرّك (animated). ستتناول هذه المقالة استخدام شبه عنصر (pseudo-element) لإضافة تأثير بصري على زر. Shiny effect شبه العناصر Pseudo-elements يُمكن باستخدام CSS تحديد شبه عنصر باستخدام ::before أو ::after ليتم بعد ذلك إدراج شبه العنصر ضمن العنصر، أو بين العنصر و محتوى ما، وباعتبار أنّ شبه العنصر يعمل عمل أي عنصر، فمن المُمكن أنّ يتمّ تنسيقه، أو توضيعه، وستكون صياغة الشيفرة الخاصّة به على الشكل التّالي: .pebble::before { ... } .pebble::after { ... } يُمكن القول هنا، أنّ العنصر pebble. يملك عنصرين وهميين مُرتبطين به، ويُمكن تنسيقهما أيضًا. ملاحظة حول الفرق بين استخدام "::" و ":" يُقبَل عامًّا استخدام تضعيف النقطتان، وذلك للدلالة على استخدام شبه العناصر، وذلك على عكس شبه الأصناف (pseudo-classes) مثل :hover أو :first-child، ولكن يجب استخدام ( في حال الرغبة في دعم IE8، مع العلم أنّ جميع المُتصفّحات الأخرى وبإصداراتها الأخيرة تدعم النقطتان المُضاعفتان (::). استخدام خاصية content يجب عند استخدام شبه العناصر، ضبط الخاصّيّة content لكي يُصبح شبه العناصر مرئيًا على الصّفحة، ومن المُمكن الاحتيال عليه للظهور عبر استخدام مُحتوى فارغ كما في التّالي: .pebble::before { content: "" ... more styling goes here... } .shiny{-webkit-perspective:500px;perspective:500px;-webkit-transform-style:preserve-3d;transform-style:preserve-3d;display:inline-block}.shiny button{background:#d1703c;color:#fff;font-size:14px;border:none;border-radius:0.5em;height:3em;padding:0 1em;position:relative;overflow:hidden;line-height:2em;-webkit-transition:all 0.5s cubic-bezier(.67,-0.51,.42,1.43);transition:all 0.5s cubic-bezier(.67,-0.51,.42,1.43)}.shiny button:hover,.shiny button:focus{border-color:#d1703c;color:#fff;font-size:24px}.shiny button:hover::after,.shiny button:focus::after,.shiny .demo-container.active button::after{-webkit-animation:sheen 1s 0.5s forwards;animation:sheen 1s 0.5s forwards}.shiny button::after{content:'';position:absolute;top:-50%;right:-50%;bottom:-50%;left:-50%;background:-webkit-linear-gradient(top,rgba(209,112,60,0),rgba(255,255,255,0.5) 50%,rgba(209,112,60,0));background:linear-gradient(to bottom,rgba(209,112,60,0),rgba(255,255,255,0.5) 50%,rgba(209,112,60,0));-webkit-transform:rotateZ(60deg) translate(-5em,7.5em);transform:rotateZ(60deg) translate(-5em,7.5em)}.shiny button.visible{overflow:visible}.shiny button:hover{cursor:pointer}@-webkit-keyframes sheen{100%{-webkit-transform:rotateZ(60deg) translate(1em,-14em);transform:rotateZ(60deg) translate(1em,-14em)}}@keyframes sheen{100%{-webkit-transform:rotateZ(60deg) translate(1em,-14em);transform:rotateZ(60deg) translate(1em,-14em)}} يجب أنّ تجعل الشيفرة السابقة من العنصر مرئيًا على الصّفحة. الزر البراق (Shiny button) سيتمّ استخدام شبه العنصر لإتمام هذا المثال، وذلك عبر إنشاء تأثير اللّمعان عند المرور فوق الزر، كما في المثال. Shiny effect البداية مع شيفرة HTML <button>Oooh SHINY</button> لا يوجد حاجة إلى كتابة المزيد من سطور HTML للمُتابعة، على اعتبار أنّه سيتمّ استخدام شبه العنصر لإضافة بقيّة المُحتوى، ولكن لا بأس من إضافة صنف (class) إلى الوسم <button> لتنسيقه عند وجود أكثر من نوع على الصّفحة، ولكن للمثال الحالي سيتمّ استخدام عنصر الزر على حاله للتبسيط. إضافة التأثير إن التأثير المُراد إضافته ما هو إلا تدرّج خطي (linear gradient) يمر عبر الزر، ولإنشاء هذا التدرّج سيتمّ استخدام شبه العنصر after، وتوضيعه في خارج الزر وفي بدايته. button::after { content: ''; position: absolute; top: -50%; right: -50%; bottom: -50%; left: -50%; background: linear-gradient(to bottom, rgba(229, 172, 142, 0), rgba(255,255,255,0.5) 50%, rgba(229, 172, 142, 0)); transform: rotateZ(60deg) translate(-5em, 7.5em); } يُصنع تأثير اللّمعان من تدرّج اللون الخارجي للزر إلى الأبيض ومن ثُمّ إلى العودة إلى اللون الأصلي. يجب إخفاء طبقة اللّمعان لتظهر فقط عند حركة المرور (hover)، ولعمل ذلك سيتمّ ضبط خاصّيّة overflow إلى hidden للزر، وباعتبار أنّ شبه العنصر هو ضمن الزر، فهذا يعني أنّ تموضعه خارج الزر لن يكون مرئيًّا. button { background: #e5ac8e; color: #fff; font-size: 14px; border-radius: 0.5em; padding: 0 1em; position: relative; overflow: hidden; line-height: 32px; } تمّ إضافة بعض التنسيق إلى الزر لكي يظهر بارزًا وذو منظرٍ خاصٍّ به، تجدر الإشارة هنا إلى استخدام position: relative، وذلك لكي يكون شبه العنصر المتموضع بشكل مُطلق (absolutely) مُتواجدًا داخل الزر، فبدون ضبط هذه الخاصّيّة، سيتموضع العنصر ذو التَمَوْضُع المُطلق ضمن العنصر الأب. إضافة التحريك (Adding the animation) يجب لاستكمال هذا المثال باستخدام التحريك: أوّلًا: إخبار المُتصفّح ليستخدم التحريك عند حركة المرور (hover). ثانيًا: تحديد بالضَّبط ما هو التحريك المطلوب وذلك باستخدام keyframes. يتمّ إضافة حالة المرور عبر إلحاق after إلى hover كما في التّالي: button:hover::after, button:focus::after { animation: sheen 1s forwards; } تمّ في الشيفرة السابقة إخبار المُتصفّح، أنّه عند حركة المرور (hover)، يجب على شبه العنصر after أنّ يُطبّق التحريك animation، ذو الاسم “sheen”، ولمدّة ثانية واحدة، ويتوقف عند النهاية بدون تكرار. يجب الأخذ بعني الاعتبار الترتيب، فاستخدام ::after:hover لن يعمل، حيثُ عندها سيتمّ إخبار المُتصفّح ليتفاعل مع حالة المرور (hover) لشبه العنصر نفسه. تتوفّر الشيفرة السابقة أيضًا على حالة التمركز (focus)، والّتي تعني أنّ المُستخدم الّذي يضغط على زر لوحة المفاتيح tab ضمن الصّفحة سيرى التأثير "sheen" أيضًا عند الوصول إليه، وبدون الحاجة لحركة المرور. سيتمّ في الخطوة التّالية تعيين وضبط keyframes لهذا التحريك: @keyframes sheen { 100% { transform: rotateZ(60deg) translate(1em, -9em); } } تمّ في الشيفرة السابقة كتابة keyframe واحد فقط، وذلك باعتبار أنّ بداية التَمَوْضُع (0%) هي مُضمّنة من قبل تَمَوْضُع بداية شبه العنصر، فكل ما يجب فعله هو ضبط نهاية التَمَوْضُع، والتي ستكون أعلى يمين الزر، ليُحاكي المُتصفح هذا التأثير Shiny effect دعم المتصفحات للتحريك أصبحت الخاصّيّة animation، و شبه العناصر مدعومة بشكل جيّد مع آخر إصدارات المُتصفّحات، ولكن يُستحسن دائمًا إلحاق السوابق webkit و moz من أجل الخاصّيّة keyframes. ترجمة وبتصرف للمقال Animating pseudo-elements.
  9. في درس سابق تعرفنا على كيفية تطبيق انتقالات Transitions على الشرائح، وهي تأثيرات حركية تُشغّل عند الانتقال من شريحة إلى أخرى. في هذا الدرس سنتعرف على كيفية تطبيق حركات Animations على العناصر داخل الشريحة، كالنصوص، الصور، الأشكال، المخططات، الرسومات، وغيرها. من السهل جدا تطبيق الحركات في باوربوينت، وهي من الخصائص الرائعة التي تضيف عامل جذب بصري لعروضك التقديمية يزيد من اهتمام المشاهد. الشريحة أعلاه هي مثال على حركات مختلفة مطبقة على عدد من العناصر. قمنا بتطبيق حركة Bounce على مربع العنوان، حركة Grow & Turn على النصوص، حركة Float In على المخطط، وحركة Wipe على الصورة. وكل حركة من هذه الحركات تمتلك خيارات بديلة للتأثير. لإضافة حركة لأي عنصر من العناصر قم بتحديده أولا، ثم اذهب إلى تبويب حركات Animations، واختر الحركة المرغوبة من معرض الحركات: عند النقر على الحركة ستُعرض معاينة لها بشكل تلقائي، يمكنك إيقاف المعاينة التلقائية AutoPreview بإلغاء تأشيرها من زر معاينة Preview، واستخدام هذا الزر لعرض المعاينة يدويا: عند اختيار الحركة، يمكنك عرض خيارات التأثير لها من زر خيارات التأثير Effect Options. وتختلف هذه التأثيرات للحركة الواحدة باختلاف العنصر. فإذا قمت بتطبيق حركة Fade على النصوص ستختلف خيارات التأثير فيما لو قمت بتطبيقها على مخطط. مثلا، من خيارات التأثير لحركة Float In التي قمنا بتطبيقها على المخطط يمكننا تغيير اتجاه Direction حركة سلاسل المخطط لتكون من الأعلى إلى الأسفل، أو تغيير تتابع Sequence ظهور عناصر المخطط حسب الفئة By Category أو حسب العناصر في السلسلة By Elements in Series: ولإلغاء الحركة من العنصر، قم بتحديده ثم اختر الحركة بلا None من معرض الحركات: تحريك النصوصتوجد في باوربوينت أربعة مجاميع مختلفة من الحركات: حركات الدخول Entrance: تأثيرات جلب العناصر إلى داخل الشريحة أو إظهارها في العرض.حركات التوكيد Emphasis: تستخدم لإضافة تأثير حركي على العناصر في الشريحة وليس جلبها إلى داخل الشريحة أو إخراجها.حركات الخروج Exit: تأثيرات إخراج العناصر من الشريحة أو جعلها تختفي من العرض.مسار الحركة Motion Paths: لتحريك العناصر بمسار معين داخل الشريحة.يمكنك اختيار أي نوع من هذه المجاميع وتطبيقها على النصوص، لكن من الأفضل ألّا يكون الاختيار عشوائيا. يمكنك مثلا أن تطبق حركات الدخول على العناوين الرئيسية، وحركات التوكيد على بقية النصوص. ليست هناك قواعد لاختيار الحركات، المهم أن تكون النتيجة النهائية لتطبيقها ذات وقع بصري جذاب. كما ذكرنا أعلاه، لتطبيق حركة على النصوص قم بتحديدها أولا ثم اختر حركة من معرض الحركات. سنقوم مثلا بتطبيق حركة Appear على العنوان في الشريحة التالية: ستلاحظ ظهور أرقام بجانب العناصر عند تطبيق الحركة. هذه الأرقام تشير إلى ترتيب تشغيل الحركات عند عرض الشريحة. كما ترى فإن الحركة Appear سريعة وتكاد لا تُلاحظ. ولذلك سنقوم بإظهار كلمة بعد أخرى بدلا من إظهار العنوان كاملا. لكن خيارات التأثير لا تحتوي سوى على خيار واحد وهو إظهار النص كعنصر واحد: لذلك سنعرض الخيارات الإضافة للتأثير من مشغل الخيارات الإضافية: في مربع حوار الخيارات الإضافية يمكنك تغيير تسلسل حركة النص كعنصر واحد، حسب الكلمات، أو حسب الحروف من خانة Animate Text. كما يمكنك تحديد الفترة الزمنية بين الحركات من خيار التأخير Delay. سنقوم باختيار حركة ظهور النص حسب الكلمة By word، ونبقي على القيمة الافتراضية للتأخير (0.5 sec)، وستكون النتيجة كالتالي: إذا كانت حركة ظهور الكلمات سريعة يمكنك زيادة قيمة التأخير. أما نصوص المحتوى الرئيسي فسنقوم بتطبيق حركة مختلفة عليها، ولتكن إحدى حركات التوكيد؛ حركة Object Color مثلا: لكن عند تغير لون النص إلى اللون البرتقالي يجعله صعب القراءة، لذلك سأقوم بتغيير لون النص الأصلي من الأبيض إلى الأسود الباهت: ثم أغير لون الحركة من خيارات التأثير إلى اللون الأزرق الفاتح: بهذه الطريقة سيتغير اللون أثناء الحركة من اللون الأسود الباهت إلى الأزرق الفاتح، مما يجعله أكثر جذبا للانتباه: بالإمكان أيضا جعل لون النص باهتا بعد أن تنتهي الحركة في كل فقرة وتقليل السرعة وذلك من خلال الخيارات الإضافية. في تبويب Effect الخاص بالتأثيرات الإضافية قم بتغيير اللون الذي تريد إظهاره بعد انتهاء الحركة في الفقرة من خانة After Animation، سأقوم هنا باختيار نفس اللون الأصلي للنص، أسود باهت: ومن تبويب Timing قم بتحديد السرعة المرغوبة للانتقال من فقرة إلى أخرى من خانة Delay، يناسبني التأخير 2 ثانية لذلك سأقوم بتحديده: بعد الانتهاء انقر موافق لمعاينة تأثير الحركة وسرعته: جرب تطبيق العديد من الحركات وتأثيراتها واستخدم أمر معاينة Preview لتشغيل الحركات ومعاينتها إلى أن تحصل على النتيجة المرغوبة. تحريك الصوريمكنك تطبيق الحركات على الصور بنفس طريق تطبيقها على النصوص. المثال التالي هو عبارة عن شريحة تحتوي على مجموعة من الصور مع عناوينها داخل أشكال. سأقوم بتحديد الصورة الأولى في اليسار وتطبيق حركة Wipe عليها. من خيارات التأثير سأختار اتجاه الحركة إلى الأسفل: ثم سأقوم بتحديد الشكل الأول على اليسار (عنوان الصورة) وتطبيق حركة Color Pulse عليه. من خيارات التأثير سأختار اللون الأصفر بدلا من البرتقالي: سأستخدم أداة ناسخ الحركة Animation Painter لنسخ حركة الصورة الأولى والشكل الأول وتطبيقها على الصور والأشكال الأخرى. عند استخدام ناسخ الحركة، حدد عنصر مصدر الحركة أولا (الصورة الأولى في هذا المثال)، انقر بشكل مزدوج على ناسخ الحركة، ثم انقر على الصورة الثانية، ثم الصورة الثالثة، وهكذا. بعد الانتهاء من النسخ قم بالنقر فوق ناسخ الحركة مجددا لإلغاء تفعيله: سأكرر نفس الخطوة على الأشكال لنسخ حركتها: لكن لاحظ أن تسلسل ظهور الحركات غير مرتب. أرغب في جعل الصورة تظهر أولا ثم عنوانها، بعدها الصورة الثانية ثم عنوانها. لتغيير تسلسل الحركات سنقوم بفتح جزء الحركة Animation Pane من تبويب حركات Animations: يحتوي جزء الحركة على جميع الحركات المطبقة على جميع العناصر، ويمكنك من خلاله التحكم بترتيب تشغيل الحركات ووقت ومدة تشغيلها. عندما تقوم بتحديد العنصر في الشريحة سيتم تحديد الحركة المطبقة عليه في جزء الحركة. لتغيير ترتيب الحركة لأي عنصر من العناصر قم بتحديده في جزء الحركة واسحبه إلى الموضع الذي تريد تشغيله عنده. سأقوم بتغيير ترتيب الشكل الثاني من 5 إلى 4 ليتم تشغيله بعد الصورة الثانية (واسمها Picture 6) في هذا المثال: والآن أصبح تشغيل الحركة مرتبا: لاحظ أن حركة الصورة تشغل أولا ثم حركة الشكل. وهذا يعني أنه عند تشغيل العرض التقديمي يجب أن تنقر بالفأرة لتشغيل حركة الصورة الأولى، ثم تنقر مرة أخرى لتشغيل حركة الشكل الأول، ثم تنقر لتشغيل حركة الصورة الثانية وهكذا. لجعل حركتي الصورة والشكل تُشغلان معا انقر بزر الفأرة الأيمن على حركة الشكل في جزء الحركة واختر Start With Previous لبدء تشغيل حركة الشكل مع حركة الصورة: تمثل الأشرطة الصفراء والخضراء مدة تشغيل الحركة. قم بتمرير الفأرة فوقها إلى أن يتغير شكل المؤشر إلى متجهين صغيرين. اسحب إلى اليمين لزيادة المدة، أو إلى اليسار لتقليلها. يمكنك الاستفادة من العلامة التي تظهر أثناء السحب لمعرفة المدة. سأقوم مثلا بزيادة مدة حركة الصور إلى 1.5 ثانية: بعد الانتهاء من جميع الإعدادات قم بمعاينة التغييرات من أمر معاينة Preview، أو اضغط مفتاحي Shif +F5 لتشغيل العرض من الشريحة الحالية: تحريك المخططاتعندما يتعلق الأمر بتحريك المخططات فإنّ اختيار نوع الحركة المناسبة للمخطط مهم جدا. إذ أن هناك حركات تبدو غير ملائمة عند تطبيقها على نوع معين من المخططات. لنأخذ المخطط أدناه كمثال: فلو اخترت حركة مثل Swivel أو Bounce لمثل هذا النوع من المخططات لن تبدو منطقية. لذلك من الأفضل تجربة أكثر من حركة لاختيار الأنسب من بينها. سأقوم بتطبيق حركة Float In على المخطط. ومن خيارات التأثير سأختار تتابع الحركة Sequence حسب السلسلة By Series (أي تظهر سلسلة Flow أولا، بعدها سلسلة Stability، وأخيرا سلسلة bulk specific gravity): وستكون نتيجة الحركة كالتالي عند تشغيلها: إذا كنت ترغب في جعل خطوط شبكة المخطط ثابتة وبقية العناصر متحركة تستطيع حذف حركتها. حدد الرقم 1 من حركات المخطط واضغط Delete من لوحة المفاتيح لحذف الحركة الأولى وهي الخاصة بالشبكة. وإذا كان لديك مخطط دائري (كما في المثال أدناه) يمكنك اختيار حركات مثل Wheel: (صورة 33) وبنفس الطريقة يمكنك تطبيق الحركات على رسومات SmartArt. من الحركات المناسبة Fade، Wipe أو Zoom. سنقوم بتطبيق حركة Wipe على المخطط التالي، ومن خيارات التأثيرات سنختار اتجاه الحركة من الأعلى From Top ونوع التتابع Level at Once لعرض المستوى الأول ثم الثاني، ثم الثالث، إلخ: وستكون نتيجة الحركة النهائية كالتالي: وبالطبع يمكنك تغيير سرعة الحركة من الخيارات الإضافية كما فعلنا في الأمثلة السابقة. في المثال أدناه لدي ثلاثة تروس أرغب في إضافة حركة دوران إليها: سأقوم أولا بتحديد الترس الأزرق، وأطبق حركة Spin عليه، وهي أكثر حركة مقاربة لدوران التروس. من خيارات التأثير الإضافية سأقوم بزيادة المدة Duration إلى 5 ثانية لجعل حركة الدوران بطيئة: سأستخدم ناسخ الحركة Animation Painter لتطبيق نفس الحركة على الترسين الآخرين. وبما أن حركة التروس المتداخلة تكون واحدة عكس الأخرى، لذلك سأقوم بتحديد الترس الوردي وعكس حركته لتكون عكس حركة الترس الأزرق (أي عكس عقارب الساعة Counterclockwise) من خيارات التأثير: ومن جزء الحركة Animation Pane سأجعل حركة الترسين الوردي والأخضر تبدأ مع حركة الترس الأزرق Start With Previous: وأخيرا سأقوم بمعاينة الحركة من أمر معاينة Preview، وستبدو بالشكل التالي: قد لا تبدو الحركة مثالية (من الناحية الميكانيكية) لكنها تعطيك تصورا عما يمكنك فعله مع خيارات الحركة المتوفرة وإنشاء عروض تقديمية مميزة. إنشاء حركات مخصصة باستخدام مسارات الحركةفي حركات الدخول، التوكيد، والخروج يمكنك التحكم باتجاه الحركة وتتابعها من خيارات التأثير. لكن لا يمكنك أن تتحكم بموضع بدء الحركة ولا مسارها. للتحكم بمثل هذه الخيارات استخدم مسارات الحركة Motion Paths. قم بتحديد الشكل الذي تريد تطبيق مسار الحركة عليه واختر أحد المسارات من معرض الحركات: يمثل الخط مسار الحركة، النقطة الخضراء بداية الحركة، والنقطة الحمراء نهاية الحركة. الخطوات التالية هي أمثلة توضيحية عما يمكن تطبيقه باستخدام مسارات الحركة. حدد النقطة الحمراء وقم بتحريكها تجاه الشكل 3 إلى أن يتطابق الشكلين معا، ثم انقر معاينة، ستلاحظ أن الشكل 1 قد تحرك خلف الشكل 3: بنفس الطريقة طبق مسار الحركة Lines على الشكل 2، ثم حركه باتجاه الشكل 3 إلى أن يتطابق معه. انقر معاينة لمشاهدة الحركة: يمكنك اختيار مسارات أخرى، كالأقواس أو المسارات الدائرية. وإذا رغبت برسم مسار مخصص يدويا يمكنك استخدام المسار المخصص Custom Path: يمكنك أيضا تطبيق أكثر من حركة على نفس العنصر. حدد العنصر الذي ترغب في تحريكه، وطبق إحدى الحركات عليه من معرض الحركات، ولتكن مسار مقوس مثلا. ثم انقر فوق إضافة حركة Add Animation من نفس التبويب واختر الحركة الثانية، سأختار هنا Spin: من جزء الحركة Animation Pane اجعل الحركة الثانية بعد مع الحركة الأولى: يمكنك الوصول إلى خيارات التأثير الإضافية Effect Options بالنقر على الحركة بالزر الأيمن في جزء الحركة أيضا. قم بإجراء التغييرات المرغوبة من خيارات التأثير، وحدد Auto-reverse إذا كنت ترغب بعكس الحركة أيضا: انقر معاينة لمشاهدة النتيجة، أو اضغط مفتاحي Shift+F5 لبدء العرض من الشريحة الحالية:
  10. هذا الدرس الأول من سلسلة نصائح وحيل فوتوشوب، التي سنتعلم من خلالها العديد من الحيل والأدوات عند التصميم ببرنامج فوتوشوب بالإضافة إلى مجموعة من النصائح حول الإستخدام الأمثل للبرنامج. سنتعلم في هذا الدرس كيفية تصميم شريط إعلاني (Banner) متحرك صغير وبسيط بخطوات سريعة وبسيطة. افتح ملفا جديدا في برنامج فوتوشوب بحجم 400×75 بكسل. طبّق على الخلفية تدرّج لوني كما في الصورة. ارسم تحديد دائري يظهرُ طرفهُ فقط في الجزء الأيسر من الشريط. امسح هذا الجزء المحدد. أبقِ على التحديد وارسم بداخله تدرج لوني مطابق للخلفية مع عكس اتجاهه. أبقِ على التحديد أيضًا ثم اذهب للقائمة: Select > Modify > Contract وأدخل القيمة 5 وبعدها اضغط OK ثم طبّق تدرّج لوني على ما بقي من التحديد من الرمادي الفاتح إلى الأبيض كما في الصورة. أدخل الشعار في هذا الجزء الرمادي الفاتح. أدخل عنوان الشريط الرئيسي في الموقع الذي تراه مناسبًا. أدخل العنوان الفرعي في المساحة المتبقية مع جعلها بحجم خط أصغر وبألوان متناسقة مع التصميم بصورة عامة (علمًا أنّه يوجد العديد من العناوين الفرعية ولكننا سنقوم بإدخالها لاحقًا). انسخ طبقة النص الفرعي بالضغط على Ctrl+J بعد تحديد طبقة النص طبعًا ثم حدد النسخة واذهب للقائمة: Filter > Blur > Motion Blur ثم أدخل القيمة 12 وبعدها OK (سيسألك لدى تنفيذ هذا الفلتر عن موافقتك على تحويل الطبقة إلى صورة نقطية فاضغط موافق). أخفِ هاتين الطبقتين ثم أدخل العنوان الفرعي الثاني في طبقة جديدة وكرّر عملية تطبيق الفلتر عليه بذات الأسلوب. كرّر العملية مع جميع العناوين الفرعية ثم فعّل نافذة TimeLine من قائمة Window ثم أدخل الأطر تباعًا مع إظهار النص الفرعي أولًا فقط ثم النص الفرعي الأول مموّه بالفلتر ثم النص الفرعي الثاني وهكذا حتى النهاية مع جعل مدّة عرض إطار النص الفرعي العادي 1 ثانية ومدّة عرض النص الفرعي المموّه 0.1 ثانية. اذهب إلى القائمة: File > Save to Web ثم احفظ الملف بصيغة GIF مع تخصيص الإعدادات المناسبة والنتيجة ستكون كالتالي:
  11. عند استخدام التحريكات animations والانتقالات transitions ضمن واجهة المستخدم، فإنّه من الضروري أن يكون لها هدف واضح ومحدّد، ألا وهو تحسين تجربة المستخدم. تؤمّن لنا الانتقالات transitions الوسيلة المناسبة والمثالية لجعل الحركة سلسة وانسيابية أمام المستخدم. بدون تأثيرات الانتقال من الممكن أن يصبح المستخدم في حيرة من أمره حول الذي حدث بالضبط عند تنفيذه لأمر معين. في هذا المقال، سننشئ بعض التحريكات والانتقالات الإبداعية لإضافة وإزالة عناصر من قائمة، لقد أعجبتني الفكرة الواردة في مقال باسكويل دي سيلفيا. أمّا بالنسبة للشيفرة المسؤولة عن الإنتقالات في مقال باسكويل، فقد كتبه كريس كوير. سأعمل على تطوير المثال الوارد في مقال باسكويل، وذلك بإضافة المزيد من تأثيرات الانتقالات والتحريكات، وسأستخدم أيضاً شيفرة صغيرة من مقال كريس لإضافة خطوة إضافية في كل تحريكة، تتمثل بحجز مكان للعناصر المراد إضافتها إلى القائمة قبل إضافتها فعلياً. سأستخدم خصائص CSS بدون أي بادئة prefix وذلك بغرض الاختصار، لكنك ستجد الخصائص كاملة ضمن النص المصدري للمشروع على Github. ستعمل مقاطع الشيفرة التي ستجدها ضمن هذا الدرس على متصفحات تدعم خصائص CSS المستخدمة. لنبدأ العمل! الرماز The Markupلتوضيح فكرة الدرس بشكل جيد، أنشأت تطبيقاً بسيطاً خاصاً بالملاحظات البسيطة. يستخدم هذا التطبيق تقنية التخزين المحلي LocalStorage التي توفرها HTML5 وذلك لحفظ الملاحظات ضمن التخزين المحلي لمتصفح ويب لديك. يسمح لك التطبيق بأخذ ملاحظات وحفظها ضمن المتصفح إن أردت ذلك، في الحقيقة هو السبب الذي من أجله بنيت هذا التطبيق، وذلك من أجل ملاحظاتي الخاصة. لن أخوض في تفاصيل كيفية بناء هذا التطبيق لأنّ ذلك ليس هدف هذا الدرس. الرُماز markup المستخدم في هذا التطبيق هو مجرد نموذج form بسيط يحتوي على حقل نصي text field وزر إرسال submit button، بالإضافة إلى قائمة غير مرتّبة unordered list. ستُضاف الملاحظات إلى هذه القائمة بشكل تلقائي. كما يوجد أيضاً عنصري div لعرض التنبيهات، التي ستظهر عند حفظ أو إزالة أي عنصر، بالإضافة إلى عدّاد وزر لحذف جميع العناصر بنقرة واحدة. فيما يلي جميع رُماز HTML الذي سنحتاجه: <div class="notification undo-button"> Item Deleted. Undo? </div> <div class="notification save-notification"> Item Saved </div> <div class="reminder-container"> <header> <h1>mini reminders list</h1> </header> <form id="input-form"> <input type="text" id="text" placeholder="Remind me to.."/> <input type="submit" value="Add" /> </form> <ul class="reminders"> </ul> <footer> <span class="count"></span> <button class="clear-all"> Delete All </button> </footer> </div>يمكنك إضافة وتحرير وإزالة العناصر (الملاحظات) بالإضافة إلى إمكانية إستعادة العنصر المحذوف. في الواقع، تأتي أغلب التحريكات مرافقة لعملية إزالة وإستعادة العناصر. تُعتبر عملية إضافة العناصر بسيطة ولا تترافق مع الكثير من التحريكات، باستثناء التحريك الخاص بالظهور التدريجي fade in والسقوط إلى أسفل falling down واللذان سنتحدث عنهما عندما نبدأ العمل مع CSS. تنسيقات CSSستحصل العناصر المُضافة توّاً عن طريق JavaScript على الصنف new-item. (صنف CSS). أمّا العناصر المُزالة فستحصل على الصنف removed-item. كما ستحصل العناصر المُستعادة على الصنف restored-item. وكل صنف من الأصناف السابقة سيُفعّل التحريكات الخاصة به. ستبقى أسماء الأصناف السابقة ثابتةً لجميع الأمثلة التوضيحية، في حين ستختلف فيما بينها بالتوجيه المسؤول عن مظهر التحريك keyframes@. لنبدأ الآن بالمثال التوضيحي الأول. المثال الأول المثال الأول: العناصر المُزالة "تسقط إلى أسفل"، والعناصر المُستعادة ستعود بحركة معاكسة. ستسقط العناصر المضافة حديثاً من الأعلى، وهذا تأثير بسيط لكنه جميل. سيبدأ كل عنصر مُضاف حديثاً بالسقوط إلى أسفل وذلك من موقع يعلو 400 بيكسل عن الموقع النهائي الذي سيستقر فيه (أي الموقع النهائي ناقص 400 بيكسل) لا تنس أنّه يجب على الخاصية الفرعية animation-fill-mode أن تحمل القيمة forwards وذلك للتأكّد من أنّ العناصر ستبقى في موقعها النهائي ضمن القائمة، وإلّا فإنّها ستختفي بمجرّد انتهاء عملية التحريك. li.new-item { opacity: 0; animation: new-item-animation .3s linear forwards; } @keyframes new-item-animation { from { opacity: 0; transform: translateY(-400px); } to { opacity: 1; transform : translateY(0); } }ستسقط العناصر المزالة وتتلاشى fade out. بالنسبة لتحريكة السقوط إلى أسفل فهي بسيطة جداً، حيث ينتقل العنصر إلى أسفل وفق محور التراتيب (محور y) ليحاكي تحريكة السقوط، ويدور بينما يسقط ويتلاشى بالتدريج حتى يختفي تماماً (ستتحقّق شيفرة JavaScript من أنّ العنصر قد أُزيل كليّاً من DOM في نهاية هذه التحريكة). li.removed-item { animation: removed-item-animation 1s cubic-bezier(0.55, -0.04, 0.91, 0.94) forwards; transform-origin: 0% 100%; } @keyframes removed-item-animation { 0% { opacity: 1; transform: rotateZ(0); } 100% { opacity: 0; transform: translateY(600px) rotateZ(90deg); } }أمّا عندما نستعيد عنصرًا فستعمل تحريكة الاستعادة على عكس المنطق الموجود في تحريكة إزالة عنصر، لذلك فستكون الأُطر الأساسية keyframes مُعرّفة بشكل معاكس تماماً لما هو عليه في تحريكة إزالة عنصر: li.restored-item { animation: openspace 0.3s ease forwards, restored-item-animation 0.3s 0.3s cubic-bezier(0, 0.8, 0.32, 1.07) forwards; } @keyframes openspace { to { height: auto; } } @keyframes restored-item-animation { 0% { opacity: 0; transform: translateY(600px) rotateZ(90deg); } 10% { opacity: 1; transform: translateY(600px) rotateZ(90deg); } 100% { opacity: 1; transform: rotateZ(0); } }يمكنك أن ترى أننا نستخدم في الشيفرة السابقة مظهر تحريك اسمه openspace استعرته من مقال كريس كوير. يتأكّد مظهر التحريك هذا من أنّ العناصر التي تقع أسفل العنصر المُسترجع (إن وجدت)، ستنزلق إلى الأسفل وتفسح مجالاً للعنصر المُسترجَع ليعود إلى مكانه. إذاً عندما تنزلق العناصر إلى الأسفل لتفسح مجالاً open space للعنصر المُسترجَع، فإنّها فعلياً يجب أن تنتقل إلى الأسفل بشكل سلس، ولكن بما أنّ العناصر في هذا التطبيق لا تملك ارتفاعاً height ثابتاً، لذلك فإنّ إطار التحريك الأساسي to (انظر الشيفرة في الأعلى) سيجعل قيمة الارتفاع height لها لتصبح auto في نهاية عملية التحريك، سيؤدي ذلك لسوء الحظ إلى أنّ العناصر لن تنزلق إلى الأسفل، بل ستبدو كما لو أنّها تقفز إلى الأسفل. على أية حال توجد طريقة تجعل العناصر تغير مواقعها بشكل سلس، وهي تقنية كتب عنها ستيف ساندرسون Steve Sanderson هنا. لكنه يستخدم لهذا الغرض التموضع المطلق absolute positioning، وكمية لا بأس بها من شيفرة JavaScript. يمكنك تفقّد مقالته إذا كنت مهتماً بمعرفة المزيد عن التقنيّة التي يستخدمها، والتي تعطي في الحقيقة نتائج رائعة! المثال الثاني المثال الثاني: العناصر تكبُر وتتلاشى أمام المستخدم، وتُستَعاد بطريقة معكوسة. يعود الفضل في هذه الفكرة إلى تيم بيتروسكي Tim Pietrusky، حيث جاء بها عندما أخبرته أنّ الأفكار قد نفذت منّي بعد أن وضعت خمسة أمثلة توضيحية! في هذه الفكرة، تظهر العناصر المُضافة حديثاً (أي تلك العناصر التي لم تُزال من قبل ثم استُعيدت) بشكل تدريجي fade in ضمن موقعها. li.new-item { opacity: 0; animation: fadeIn .3s linear forwards; } @keyframes fadeIn { to { opacity: 1; } }عندما تُزال العناصر، فإنّها تكبُر وتتلاشى أمام المستخدم، أمّا العناصر المُستعادة فتسلك الأسلوب المعاكس، فعملية التحريك بالنسبة للعناصر المستعادة تماثل تماماً عملية التحريك بالنسبة للعناصر المزالة ولكن بالمقلوب. li.removed-item { animation: removed-item-animation .6s ease-out forwards; transform-origin: 50% 50%; } @keyframes removed-item-animation { 0% { opacity: 1; transform: scale(1); } 100% { opacity: 0; transform: scale(4); } } li.restored-item { animation: openspace .3s ease forwards, restored-item-animation .3s .3s ease-out forwards; } @keyframes openspace { to { height: auto; } } @keyframes restored-item-animation { 0% { opacity: 0; transform: scale(4); } 100% { opacity: 1; transform: scale(1); } }المثال الثالث المثال الثالث: ستنزلق العناصر المستعادة لتدخل من اليمين، أما العناصر المزالة فستنزلق يساراً إلى الخارج. يُعتبر المثال الثالث أبسط من سابقيه من الناحية الشكلية. فالعناصر المُضافة حديثاً سيكون لها نفس تأثير الظهور التدريجي كما في المثالين السابقين، لذلك سنتجاوز عملية التحريك الخاصة بإضافة عنصر جديد. بالنسبة للعناصر المُزالة فإنها ستنزلق يساراً إلى الخارج، مع ملاحظة تأثير جميل يحدث عند بدء عملية الإزالة باستخدام دالة توقيت من النوع Cubic Bezier، انظر إلى المثال التطبيقي لترى كيف تعمل هذه التحريكة. li.removed-item { animation: removed-item-animation .8s cubic-bezier(.65,-0.02,.72,.29); } @keyframes removed-item-animation { 0% { opacity: 1; transform: translateX(0); } 30% { opacity: 1; transform: translateX(50px); } 80% { opacity: 1; transform: translateX(-800px); } 100% { opacity: 0; transform: translateX(-800px); } }أمّا العناصر المستعادة فستنزلق إلى الداخل من اليمين، وذلك باستخدام نفس دالة التوقيت السابقة، ولكنها ليست الحالة المعاكسة تماماً لها (تفقّد المثال التطبيقي لترى النتيجة النهائية). li.restored-item { animation: openspace .3s ease forwards, restored-item-animation .5s .3s cubic-bezier(.14,.25,.52,1.56) forwards; } @keyframes openspace { to { height: auto; } } @keyframes restored-item-animation { 0% { opacity: 0; transform: translateX(300px); } 70% { opacity: 1; transform: translateX(-50px); } 100% { opacity: 1; transform: translateX(0); } } المثال الرابع المثال الرابع: ستكبر العناصر المستعادة والجديدة وتظهر تدريجياً ضمن موقعها، أمّا العناصر المزالة فإنّها ستصغر وتختفي تدريجياً. وهذا المثال بسيط أيضاً. فكل من العناصر الجديدة والمستعادة ستكبر وتظهر تدريجياً في مواقعها، أما العناصر المزالة ستصغر وتختفي تدريجياً. هناك إطارين أساسيين keyframes لهاتين التحريكتين: li.removed-item { animation: removed-item-animation .6s cubic-bezier(.55,-0.04,.91,.94) forwards; } @keyframes removed-item-animation { from { opacity: 1; transform: scale(1); } to { opacity: 0; transform: scale(0); } } li.restored-item { animation: openspace .3s ease forwards, restored-item-animation .3s .3s cubic-bezier(0,.8,.32,1.07) forwards; } @keyframes openspace { to { height: auto; } } @keyframes restored-item-animation { from { opacity: 0; transform: scale(0); } to { opacity: 1; transform: scale(1); } } المثال الخامس المثال الخامس: تسقط العناصر الجديدة من الأعلى إلى الأسفل. العناصر المزالة تبقى معلّقة قليلاً ثم تسقط إلى الأسفل. أما العناصر المستعادة فتنزلق إلى الداخل من اليمين. في هذا المثال، عندما نُزيل أحد العناصر فإنّه يبقى معلّقاً قليلاً قبل أن يبدأ بالسقوط الفعلي ثم الإختفاء. في الحقيقة هذا هو الجزء الأهم في هذا المثال، لأنّ العناصر الجديدة ستسقط إلى الأسفل كما في المثال الأوّل، والعناصر المستعادة ستنزلق إلى الداخل من اليمين كما في المثال الثالث، ولكن مع فرق طفيف في دالة التوقيت timing function. لذلك فإنّ التحريكة الخاصة بإزالة العناصر هي التأثير الجديد الوحيد في هذا المثال. li.restored-item { transform: translateX(300px); animation: openspace .3s ease forwards, restored-item-animation .3s .3s cubic-bezier(0,.8,.32,1.07) forwards; } @keyframes openspace { to { height: auto; } } @keyframes restored-item-animation { to { opacity: 1; transform: translateX(0); } } li.removed-item { animation: removed-item-animation 2s cubic-bezier(.55,-0.04,.91,.94) forwards; transform-origin: 0% 100%; }يعطي تغيير زاوية الدوران للعنصر ضمن أُطر frames مختلفة (الأطر الرئيسية: 0% و 20% و 40% و 60% و 70% و 90% و 100%) انطباعاً بأنّ العنصر يتأرجح بينما يكون معلّقاً، وبعد ذلك يبدأ بالسقوط إلى الأسفل. @keyframes removed-item-animation { 0% { opacity: 1; transform: rotateZ(0); } 20% { opacity: 1; transform: rotateZ(140deg); } 40% { opacity: 1; transform: rotateZ(60deg); } 60% { opacity: 1; transform: rotateZ(110deg); } 70% { opacity: 1; transform: rotateZ(90deg) translateX(0); } 90% { opacity: 1; transform: rotateZ(90deg) translateX(600px); } 100% { opacity: 0; transform: rotateZ(90deg) translateX(600px); } } المثال السادس المثال السادس: ستختفي العناصر المزالة تدريجياً وتسقط إلى الأسفل باتجاه اليسار، أما العناصر الجديدة والمستعادة فستنزلق إلى الداخل من اليمين. سيكون لكل من العناصر الجديدة والمستعادة نفس السلوك في هذا المثال، حيث ستنزلق هذه العناصر إلى الداخل من اليمين ثم تخرج بشكل طفيف من الجهة اليسرى قبل أن تستقرّ في مكانها. li.restored-item { transform: translateX(300px); animation: openspace .3s ease forwards, restored-item-animation .5s .3s cubic-bezier(.14,.25,.52,1.56) forwards; } @keyframes openspace { to { height: auto; } } @keyframes restored-item-animation { 0% { opacity: 0; transform: translateX(300px); } 70% { opacity: 1; transform: translateX(-50px); } 100% { opacity: 1; transform: translateX(0); } }ستنزلق العناصر المزالة ببطء نحو اليسار، وبعد ذلك ستسقط إلى الأسفل باتجاه اليسار وتتلاشى. من المهم الآن أن نعمل على إعداد تحويل مناسب لموضع نقطة الأصل origin (مبدأ الإحداثيات)، بحيث أنّ التأثير المسؤول عن السقوط إلى أسفل يبدو أكثر واقعية. بغية ذلك، أجريت تحويلاً على نقطة الأصل لكي تنطبق على آخر نقطة تماس بين العنصر والسطر الذي ينتمي إليه، وذلك قبل أن يبدأ بالدوران والسقوط إلى أسفل، يعطي ذلك انطباعاً بأنّ العنصر يسقط بسبب وزنه. li.removed-item { animation: removed-item-animation 1s linear; transform-origin: 390px 100%; } @keyframes removed-item-animation { 0% { opacity: 1; transform: translateX(0) rotateZ(0); } 50% { opacity: 1; transform: translateX(-400px) rotateZ(0); } 75% { opacity: 1; transform: translateX(-420px) rotateZ(-30deg); } 100% { opacity: 0; transform: translateX(-800px) rotateZ(-60deg) translateY(400px); } } خاتمةفي الواقع، الإمكانيات المتاحة لا حدّ لها تقريباً، هناك الكثير من الطرق الأكثر الإبداعية لإضافة وإزالة عناصر قائمة، وأنا على ثقة بأنّك تستطيع ابتكار تأثيرات خاصة بك، وأرجو أن يكون هذا الدرس مثيراً وملهماً. لم أدخل في القسم المتعلّق بـ JavaScript لأنّ ذلك ليس من محور اهتمام الدرس. من الملاحظ وجود خطأ ضمن متصفح Firefox (ربما يُصحّح في النسخ اللاحقة) ,والذي يسبب وميضاً للصفحة كلّما تمّ وضع التركيز على العنصر أو حتى إزالة التركيز عنه (أي عندما تضغط زر edit/save). لا أدري إذا كانت توجد طريقة لتجاوز هذا الأمر، لذلك فمن فضلك أعلمني إذا استطعت تحديد سبب ذلك الوميض وإذا كانت هناك أي طريقة لمنعه. على أية حال جُرّبت الأمثلة السابقة بشكل جيّد على المتصفحات التي تدعم Webkit. شكراً لقراءتك هذا الدرس، وأرجو أن تكون قد استمتعت فيه. بإمكانك الاطّلاع على هذه الأمثلة من هنا، أما الشيفرة المصدرية فهي متُوفّرة على هذا المُستودع. ترجمة -وبتصرّف- للمقال Creative Add/Remove Effects For List Items with CSS3 Animations لصاحبته Sara Soueidan.
×
×
  • أضف...