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

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

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

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

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

نوع المحتوى


التصنيفات

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

التصنيفات

  • مقالات برمجة عامة
  • مقالات برمجة متقدمة
  • 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

ابحث في

ابحث عن


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

  • بداية

    نهاية


آخر تحديث

  • بداية

    نهاية


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

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

  • بداية

    نهاية


المجموعة


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

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

  1. يمكن لرسوم JavaScript التعامل مع حالات لا يمكن أن تتعامل معها CSS، مثل التحرك على مسار معقد مختلف عن منحنيات بيزيه Bezier curves باستخدام دالة توقيت، أو رسوميات متحركة على لوحة رسم. استخدام الدالة setInterval يمكن إنجاز الرسوم المتحركة في صورة سلسلة من الإطارات، والتي تكون عادةً تغيرات صغيرةً في خصائص HTML/CSS، فعلى سبيل المثال: يؤدي تغيير قيمة الخاصية style.left من 0px إلى 100px إلى تحريك العنصر، وإذا زدنا هذه القيمة ضمن الدالة setInterval، فسيؤدي تغير مقداره 2px مع تأخير ضئيل، لتكرار العملية بمقدار 50 مرةً في الثانية، مما يجعل الحركة سلسةً وناعمةً، ويُتَّبع هذا الأسلوب في السينما، فعرض 24 إطارًا في الثانية يجعل الصورة سلسةً. إليك الشيفرة المجردة pseudo-code للفكرة: let timer = setInterval(function() { if (animation complete) clearInterval(timer); else increase style.left by 2px }, 20); // تغير بمقدار 2 بكسل بتأخير 20 ميلي ثانية يعطي 50 إطار في الثانية وهذا مثال أكثر تعقيدًا: let start = Date.now(); // تذكر وقت البدء let timer = setInterval(function() { // كم مضى من الوقت منذ البداية let timePassed = Date.now() - start; if (timePassed >= 2000) { clearInterval(timer); // أنهي الحركة بعد ثانيتين return; } // ارسم إطار الحركة في اللحظة الحالية draw(timePassed); }, 20); // عندما يتغير الوقت بين 0 و2000 ميلي ثانية // تتغير قيمة الخاصية من 0 بكسل إلى 400 بكسل function draw(timePassed) { train.style.left = timePassed / 5 + 'px'; } إليك المثال النموذجي التالي: شيفرة الملف index.html: <!DOCTYPE HTML> <html> <head> <style> #train { position: relative; cursor: pointer; } </style> </head> <body> <img id="train" src="https://js.cx/clipart/train.gif"> <script> train.onclick = function() { let start = Date.now(); let timer = setInterval(function() { let timePassed = Date.now() - start; train.style.left = timePassed / 5 + 'px'; if (timePassed > 2000) clearInterval(timer); }, 20); } </script> </body> </html> وستكون النتيجة: See the Pen JS-p3-05-JavaScript-animations -ex1 by Hsoub (@Hsoub) on CodePen. استخدام الدالة requestAnimationFrame لنفترض تنفيذ عدة حركات انتقالية معًا. إذا شغّلنا هذه الرسوم منفصلةً فسيعيد المتصفح -وعلى الرغم من أنّ لكل حركة دالة (setInterval(..., 20 خاصةً- رسم الصور بمعدل أكبر بكثير من 20 ميلي ثانية، ويحدث هذا لوجود أوقات بداية مختلفة لكل حركة، وبالتالي سيختلف تكرار التغيّر الذي ضبطناه عند 20 ميلي ثانية بالنسبة لكل حركة، وهكذا سنكوِّن حالات تشغيل مستقلةً لكل حركة انتقالية تتكرر كل 20 ميلي ثانية، وبكلمات أخرى انظر الشيفرة التالية: setInterval(function() { animate1(); animate2(); animate3(); }, 20) والتي ستكون أخفّ من ناحية التنفيذ على المتصفح من الشيفرة: setInterval(animate1, 20); // حركة انتقالية مستقلة setInterval(animate2, 20); // في أماكن مختلفة من السكربت setInterval(animate3, 20); ينبغي تجميع عمليات الرسم المستقلة لتسهيل الأمر على المتصفح، ولتخفيف الحِمل على وحدة المعالجة إلى جانب إظهار حركة أكثر نعومةً. تذكر دائمًا أنه يجب ألا نشغل عملية الرسم كل 20 ميلي ثانية، لأنها قد تزيد حمولة وحدة المعالجة، أو لوجود أسباب لتقليل عملية إعادة الرسم، مثل الحالة التي تكون ضمن نافذة مخفية للمتصفح. ولتمييز ذلك في JavaScript سنستخدم ميزةً تُدعى توقيت الحركة Animation timing، والتي تزوّدنا بالدالة requestAnimationFrame التي تتعامل مع هذه الأمور وأكثر، وإليك صيغة استخدامها: let requestId = requestAnimationFrame(callback) تجدول الدالة requestAnimationFrame دالة الاستدعاء callback للعمل في أقرب وقت يريد فيه المتصفح تنفيذ الحركة، فإذا نفَّذنا أي تغييرات على العناصر ضمن الدالة callback، فستُجمّع مع غيرها من دوال الاستدعاء التي تجدولها الدالة requestAnimationFrame ومع رسوميات CSS، وهكذا سيعيد المتصفح الحسابات الهندسية، ثم يعيد الرسم مرةً واحدةً بدلًا من مرات متعددة. يمكن استخدام القيمة requestId التي تعيدها الدالة requestAnimationFrame في إلغاء الاستدعاء: // ألغ تنفيذ الاستدعاءات المجدولة cancelAnimationFrame(requestId); لدالة الاستدعاء callback وسيط واحد، وهو الوقت الذي انقضى منذ بداية تحميل الصفحة مقدرًا بالميكروثانية، والذي يمكن الحصول عليه باستدعاء التابع performance.now. يُنفَّذ الاستدعاء callback مبكرًا إلا في حالة التحميل الزائد للمعالج، أو عندما تقارب بطارية الحاسوب المحمول على النفاد أو لأسباب مشابهة، وتظهر الشيفرة التالية الوقت المستغرق خلال مرات التنفيذ العشرة الأولى للدالة requestAnimationFrame، وهو عادةً بين 10-20 ميلي ثانية: <script> let prev = performance.now(); let times = 0; requestAnimationFrame(function measure(time) { document.body.insertAdjacentHTML("beforeEnd", Math.floor(time - prev) + " "); prev = time; if (times++ < 10) requestAnimationFrame(measure); }) </script> See the Pen JS-p3-05-JavaScript-animations -ex2 by Hsoub (@Hsoub) on CodePen. الرسومات المتحركة المهيكلة Structured animation سننشئ الآن دالةً أكثر عموميةً مبنيةً على الدالة requestAnimationFrame: function animate({timing, draw, duration}) { let start = performance.now(); requestAnimationFrame(function animate(time) { // يتحرك الزمنين 0 و1 let timeFraction = (time - start) / duration; if (timeFraction > 1) timeFraction = 1; // حساب الحالة الراهنة للرسوم المتحركة let progress = timing(timeFraction) draw(progress); // تنفيذ الرسم if (timeFraction < 1) { requestAnimationFrame(animate); } }); } تقبل الدالة animate ثلاثة معاملات تصف الحركة، وهي: duration: الزمن الكلي لتنفيذ الحركة مقدرًا بالميلي ثانية. (timing(timeFraction: دالة توقيت تشابه الخاصية transition-timing-function في CSS، وتعطي نسبة الوقت الذي انقضى (0 عند البداية و1 عند النهاية)، وتعيد ما يدل على اكتمال الحركة، مثل الإحداثي y عند رسم منحني بيزيه، ولنتذكر أن الدالة الخطية تعني أن الحركة ستتقدم بانتظام وبالسرعة ذاتها: function linear(timeFraction) { return timeFraction; } وسيبدو الرسم البياني للدالة الخطية كالتالي: وهي مشابهة تمامًا للخاصية transition-timing-function، وسنرى لاحقًا بعض أشكال الاستخدام الأخرى. (draw(progress: وهي الدالة التي تأخذ معاملًا هو مقدار اكتمال الحركة وترسمه، وتشير القيمة progress=0 إلى حالة بداية الحركة، بينما تشير القيمة progress=1 إلى حالة النهاية، فهي الدالة التي ترسم الحركة فعليًا، إذا يمكنها نقل عنصر مثلًا: function draw(progress) { train.style.left = progress + 'px'; } أو تنفيذ أي شيء آخر، وبالتالي يمكننا تحريك أي شيء بالطريقة التي نريد، لنحرّك العنصر width من 0 حتى 100% باستخدام هذه الدالة: شيفرة الملف animate.js: unction animate({duration, draw, timing}) { let start = performance.now(); requestAnimationFrame(function animate(time) { let timeFraction = (time - start) / duration; if (timeFraction > 1) timeFraction = 1; let progress = timing(timeFraction) draw(progress); if (timeFraction < 1) { requestAnimationFrame(animate); } }); } شيفرة الملف index.html: <!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <style> progress { width: 5%; } </style> <script src="animate.js"></script> </head> <body> <progress id="elem"></progress> <script> elem.onclick = function() { animate({ duration: 1000, timing: function(timeFraction) { return timeFraction; }, draw: function(progress) { elem.style.width = progress * 100 + '%'; } }); }; </script> </body> </html> ستكون النتيجة كالتالي: وإليك الشيفرة المستخدمة: animate({ duration: 1000, timing(timeFraction) { return timeFraction; }, draw(progress) { elem.style.width = progress * 100 + '%'; } }); يمكننا بهذا الأسلوب تنفيذ أي دوال توقيت ورسم على خلاف CSS، ولا ترتبط دوال التوقيت بمنحني بيزيه فقط، كما يمكن للدالة draw أن تتخطى الخصائص إلى إنشاء عناصر جديدة لرسوميات نحتاجها، مثل الألعاب النارية. دوال التوقيت اطلعنا في الفقرات السابقة على أبسط الدوال وهي الدالة الخطية، لنرى الآن بعض الدوال الأخرى، حيث سنجرب بعض الحركات الانتقالية باستخدام دوال توقيت مختلفة. دالة القوة من الدرجة n يمكن استعمال progress بدلالة القوة من الدرجة n لتسريع الحركة، مثل الدالة التربيعية (أي من الدرجة 2): function quad(timeFraction) { return Math.pow(timeFraction, 2) } إليك الرسم البياني: لترى النتيجة انقر على الشكل التالي: كما يمكنك استعمال الدالة التكعيبية (من الدرجة 3)، وسترى أن سرعة الحركة ستزداد بزيادة درجة القوة، إليك نموذجًا تكون فيه progress من الدرجة 5: الدالة المثلثية القطعية arc صيغة الدالة: function circ(timeFraction) { return 1 - Math.sin(Math.acos(timeFraction)); } الرسم البياني: المثال النموذج: دالة إطلاق السهم back عند اطلاق السهم bow shooting فسنسحب وتر القوس ثم نحرره، وخلافًا للدالتين السابقتين، ستعتمد الدالة على معامل إضافي x هو ثابت المرونة elasticity coefficient، والذي يُعرِّف المسافة التي نسحب بها وتر القوس: function back(x, timeFraction) { return Math.pow(timeFraction, 2) * ((x + 1) * timeFraction - x) } الخط البياني للدالة عندما x = 1.5: المثال النموذجي عند نفس القيمة للمعامل x: دالة الارتداد bounce عندما نرمي كرةً فستسقط للأسفل وترتد عدة مرات ثم تتوقف. تسلك الدالة bounce هذا السلوك تمامًا لكن بترتيب معكوس، حيث يبدأ الارتداد مباشرةً، وتستخدم هذه الدالة بعض الثوابت الخاصة: function bounce(timeFraction) { for (let a = 0, b = 1, result; 1; a += b, b /= 2) { if (timeFraction >= (7 - 4 * a) / 11) { return -Math.pow((11 - 6 * a - 11 * timeFraction) / 4, 2) + Math.pow(b, 2) } } } إليك نموذجًا يستخدم دالة الإرتداد: دالة الحركة المرنة elastic إليك دالةً أخرى "مرنةً" تقبل معاملًا إضافيًا x يضبط المجال الابتدائي للحركة: function elastic(x, timeFraction) { return Math.pow(2, 10 * (timeFraction - 1)) * Math.cos(20 * Math.PI * x / 3 * timeFraction) } الخط البياني للدالة عندما x=1.5: إليك نموذجًا عن استخدام الدالة: الدوال بترتيب معكوس تعرفنا حتى اللحظة على دوال التوقيت التي تُعرف بتحويلات الدخول السهل easeIn، لكننا قد نحتاج أحيانًا إلى عرض الحركة بترتيب معكوس. تُنفَّذ هذه الحركات بالتحويل الذي يُعرف باسم الخروج السهل easeOut. التحويل easeOut تُوضع الدالة timing في هذا التحويل ضمن المُغلِّف timingEaseOut: timingEaseOut(timeFraction) = 1 - timing(1 - timeFraction) بعبارة أخرى لدينا دالة التحويل makeEaseOut التي تقبل دالة توقيت نظاميةً وتعيد المُغلّف الذي يحيط بها: // accepts a timing function, returns the transformed variant function makeEaseOut(timing) { return function(timeFraction) { return 1 - timing(1 - timeFraction); } } يمكن على سبيل المثال اختيار الدالة bounce التي شرحناها سابقًا وتطبيقها: let bounceEaseOut = makeEaseOut(bounce); وهكذا لن تكون الحركة الارتدادية في بداية الحركة بل في نهايتها، وستبدو الحركة أفضل: شيفرة الملف style.css: #brick { width: 40px; height: 20px; background: #EE6B47; position: relative; cursor: pointer; } #path { outline: 1px solid #E8C48E; width: 540px; height: 20px; } شيفرة الملف index.html: <!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <link rel="stylesheet" href="style.css"> <script src="https://js.cx/libs/animate.js"></script> </head> <body> <div id="path"> <div id="brick"></div> </div> <script> function makeEaseOut(timing) { return function(timeFraction) { return 1 - timing(1 - timeFraction); } } function bounce(timeFraction) { for (let a = 0, b = 1, result; 1; a += b, b /= 2) { if (timeFraction >= (7 - 4 * a) / 11) { return -Math.pow((11 - 6 * a - 11 * timeFraction) / 4, 2) + Math.pow(b, 2) } } } let bounceEaseOut = makeEaseOut(bounce); brick.onclick = function() { animate({ duration: 3000, timing: bounceEaseOut, draw: function(progress) { brick.style.left = progress * 500 + 'px'; } }); }; </script> </body> </html> وستكون النتيجة: سنرى هنا كيف سيغيّر التحويل سلوك الدالة، إذ ستعرَض التأثيرات الموجودة في بداية الحركة -مثل الارتداد- في النهاية، ففي الشكل التالي ستجد الارتداد الاعتيادي باللون الأحمر، والارتداد وفق تحويل الخروج السهل باللون الأزرق. الارتداد الاعتيادي: يرتد الكائن عند القاع، ثم يقفز بحدّة إلى القمة في النهاية. باستخدام easeOut الخروج السهل: يقفز أولًا إلى القمة ثم يرتد هناك. التحويل easeInOut يمكن أن نُظهر التأثير المطلوب في بداية ونهاية الحركة معًا، ويُدعى هذا التحويل بالدخول والخروج السهل easeInOut. سنحسب حالة الحركة باعتماد تابع توقيت ما كالتالي: if (timeFraction <= 0.5) { // نصف الحركة الأول return timing(2 * timeFraction) / 2; } else { // النصف الثاني للحركة return (2 - timing(2 * (1 - timeFraction))) / 2; } شيفرة المُغلِّف: function makeEaseInOut(timing) { return function(timeFraction) { if (timeFraction < .5) return timing(2 * timeFraction) / 2; else return (2 - timing(2 * (1 - timeFraction))) / 2; } } bounceEaseInOut = makeEaseInOut(bounce); إليك مثالًا نموذجيًا: شيفرة الملف style.css: #brick { width: 40px; height: 20px; background: #EE6B47; position: relative; cursor: pointer; } #path { outline: 1px solid #E8C48E; width: 540px; height: 20px; } شيفرة الملف index.html: <!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <link rel="stylesheet" href="style.css"> <script src="https://js.cx/libs/animate.js"></script> </head> <body> <div id="path"> <div id="brick"></div> </div> <script> function makeEaseInOut(timing) { return function(timeFraction) { if (timeFraction < .5) return timing(2 * timeFraction) / 2; else return (2 - timing(2 * (1 - timeFraction))) / 2; } } function bounce(timeFraction) { for (let a = 0, b = 1, result; 1; a += b, b /= 2) { if (timeFraction >= (7 - 4 * a) / 11) { return -Math.pow((11 - 6 * a - 11 * timeFraction) / 4, 2) + Math.pow(b, 2) } } } let bounceEaseInOut = makeEaseInOut(bounce); brick.onclick = function() { animate({ duration: 3000, timing: bounceEaseInOut, draw: function(progress) { brick.style.left = progress * 500 + 'px'; } }); }; </script> </body> </html> وستكون النتيجة: يدمج التحويل كائنين رسوميين معًا، وهما التحويل easeIn (الاعتيادي) في النصف الأول للحركة، والتحويل easeOut (المعكوس) للنصف الثاني. سنرى التأثير بوضوح عند الموازنة بين التحويلات الثلاث easeIn وeaseOut وeaseInOut عند تطبيقها على دالة التوقيت circ: easeIn: باللون الأحمر. easeOut: باللون الأخضر. easeInOut: باللون الأزرق. كما نرى طبقنا على النصف الأول من الحركة easeIn، وعلى النصف الآخر easeOut، لذا ستبدأ الحركة وتنتهي بنفس التأثير. دالة draw أكثر تميزًا يمكننا القيام بأكثر من مجرد تحريك العنصر، وكل ما علينا فعله هو كتابة شيفرة مناسبة للدالة draw، إليك طريقةً لإظهار ارتداد أثناء كتابة نص مثلًا: شيفرة الملف style.css: textarea { display: block; border: 1px solid #BBB; color: #444; font-size: 110%; } button { margin-top: 10px; } شيفرة الملف index.html: <!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <link rel="stylesheet" href="style.css"> <script src="https://js.cx/libs/animate.js"></script> </head> <body> <textarea id="textExample" rows="5" cols="60">He took his vorpal sword in hand: Long time the manxome foe he sought— So rested he by the Tumtum tree, And stood awhile in thought. </textarea> <button onclick="animateText(textExample)">Run the animated typing!</button> <script> function animateText(textArea) { let text = textArea.value; let to = text.length, from = 0; animate({ duration: 5000, timing: bounce, draw: function(progress) { let result = (to - from) * progress + from; textArea.value = text.substr(0, Math.ceil(result)) } }); } function bounce(timeFraction) { for (let a = 0, b = 1, result; 1; a += b, b /= 2) { if (timeFraction >= (7 - 4 * a) / 11) { return -Math.pow((11 - 6 * a - 11 * timeFraction) / 4, 2) + Math.pow(b, 2) } } } </script> </body> </html> وستكون النتيجة كالتالي: خلاصة يمكن أن تساعدك JavaScript في تنفيذ الرسوميات التي لا تستطيع CSS التعامل معها، أو تلك التي تتطلب تحكمًا دقيقًا. تّنفّذ حركات JavaScript باستخدام التابع المدمج requestAnimationFrame الذي يسمح بإعداد دالة استدعاء تُشغَّل عندما يحضّر المتصفح نفسه لعملية إعادة الرسم Repaint. لن تُنفَّذ عملية إعادة الرسم إطلاقًا عندما تكون الصفحة في الخلفية، وبالتالي لن تعمل دالة الاستدعاء وسيُعلّق تنفيذ الحركة، ولن يكون هناك استهلاك للموارد. إليك الدالة المساعدة animate التي تحضّر معظم الرسوميات المتحركة التي تحتاجها: function animate({timing, draw, duration}) { let start = performance.now(); requestAnimationFrame(function animate(time) { // timeFraction goes from 0 to 1 let timeFraction = (time - start) / duration; if (timeFraction > 1) timeFraction = 1; // calculate the current animation state let progress = timing(timeFraction); draw(progress); // draw it if (timeFraction < 1) { requestAnimationFrame(animate); } }); } الخيارات هي: duration: الزمن الكلي للحركة مقدرًا بالميلي ثانية. timing: الدالة التي تحسب مقدار تقدم الحركة، حيث تقبل الدالة قيمًا زمنيةً هي نسبة بين 0 و1، وتعيد مقدار تقدم العملية. draw: الدالة التي ترسم الحركة. وبالطبع يمكن تحسين هذه الدوال وإضافة العديد من الأمور الأخرى، لكن لا يتكرر استخدام رسوميات JavaScript كثيرًا، فهي تستخدَم لإظهار شيء مهم لا لأمور تقليدية، لذا يمكنك إضافة الميزة التي تريدها عند الحاجة. يمكن أن تستخدم JavaScript أي دوال توقيت، وقد غطينا الكثير منها في هذا الفصل وطبقنا عليها تحويلات عدةً، إذًا لسنا مقيدين بمنحنيات بيزيه كما هي الحال في CSS. يمكننا استخدام draw لتحريك أي شيء وليس خصائص CSS فقط. مهام لإنجازها 1. تحريك كرة مرتدة أنشئ كرةً ترتد كما في المثال التالي: افتح المثال في بيئة تجريبية. الحل لجعل الكرة ترتد، سنسنتعمل الخاصية top والخاصية position:absolute مع الكرة والخاصية position:relative مع الملعب، ويكن إحداثيات أرضية الملعب هي field.clientHeight. تشير الخاصية top إلى بداية أعلى الملعب لذا يجب أن تتغير من 0 إلى field.clientHeight - ball.clientHeight وهو أدنى موضع يمكن أن تنخفض إليه حافة الكرة العلوية. يمكن تطبيق تأثير الارتداد باستعمال دالة التوقيت bounce في الوضع easeOut. إليك الشيفرة النهاية الناتجة: let to = field.clientHeight - ball.clientHeight; animate({ duration: 2000, timing: makeEaseOut(bounce), draw(progress) { ball.style.top = to * progress + 'px' } }); افتح الحل في بيئة تجريبية. 2. حرك الكرة المرتدة إلى اليمين اجعل الكرة ترتد إلى اليمين كالتالي: اكتب الشيفرة بحيث تكون مسافة الانتقال إلى اليمين هي 100px. الحل احتجنا في التمرين السابق إلى تحريك خاصية واحدة فقط، بينما سنحتاج في هذا التمرين إلى تحريك خاصية إضافية هي elem.style.left. نريد تغيير الاحداثيات الأفقية للكرة بزيادتها تدريجيًا نحو اليمين أثناء السقوط، لذا سنضيف حركة إضافة anumate يمكن أن نستعمل معها دالة التوقيت linear ولكن تبدو makeEaseOut(quad)‎ أفضل بكثير. إليك الشيفرة النهاية الناتجة: let height = field.clientHeight - ball.clientHeight; let width = 100; // animate top (bouncing) animate({ duration: 2000, timing: makeEaseOut(bounce), draw: function(progress) { ball.style.top = height * progress + 'px' } }); // animate left (moving to the right) animate({ duration: 2000, timing: makeEaseOut(quad), draw: function(progress) { ball.style.left = width * progress + "px" } }); افتح الحل في بيئة تجريبية. ترجمة -وبتصرف- للفصل JavaScript Animation من سلسلة The Modern JavaScript Tutorial اقرأ أيضًا المقال السابق: إنشاء رسوم متحركة باستخدام CSS النسخة العربية الكاملة لكتاب: التحريك عبر CSS iframe { border: 1px solid #e7e5e3 !important; width: 100%; } iframe div#path { margin: auto; }
  2. يعد التحريك باستخدام مكتبة 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.
  3. في الوقت الذي ستُلقي فيه نظرة على هذا المقال قد تكون معايير SMIL أصبحت شيئًا من الماضي، لكن مهلًا! في هذا المقال ستجد دليلًا لاستبدال بعض الميزات وتطويرها. لمحة عامة يمكن تحريك الرسوم المتجهة (SVG graphics) باستخدام عناصر التحريك المعرفة في مواصفات لغة التكامل المتزامن للوسائط المتعدّدة SMIL، تشمل تلك العناصر ما يلي: <animate>: يسمح لك هذا العنصر بتحريك خاصيات HTML وخاصيات الكائنات على مدى فترة زمنية محددة. <set>: وهو اختزال مناسب للتحريك، فهو يفيد في تعيين قيم التحريك لخاصيات HTML وخاصيات الكائنات مثل خاصية الظهور والرؤية. <animateMotion>: يعمل على تحريك العنصر على امتداد مسار الحركة. <animationColor>: تستطيع من خلال هذا العنصر تعديل القيم اللونية لخاصيات HTML وخاصيات الكائنات مع مرور الوقت. لاحظ إهمال العنصر <animateColor> لمجرد استخدام عنصر التحريك لاستهداف خصائص من الممكن أن تمتلك قيم لونية. بالرغم من ذلك لا يزال ذلك العنصر متاحًا في مواصفات SVG1.1، على العكس من SVG2 فهو مهمل ومحذوف بالكامل. بالإضافة إلى عناصر التحريك المعرفة في مواصفات SMIL تحتوي الرسوم المتجهة SVG ملحقات متوافقة مع مواصفات SMIL والتي تحتوي على خاصيات توسع نطاق عمل العنصر <animateMotion> وعناصر إضافية أخرى. تشمل ملحقات الرسوم المتجهة SVG ما يلي: <animateTransform>: يتيح لك تحريك إحدى خاصيات الرسوم المتجهة مع مرور الوقت، مثل خاصية transform. path (خاصية HTML): تسمح بتحديد أي خاصية من صيغ بيانات مسار الرسوم المتجهة SVG في خاصية المسار لعنصر animateMotion، (التحريك اعتمادًا على SMIL فقط يسمح بتفرع صيغ بيانات الرسوم المتجهة خلال مسار). سنتطرق بالحديث أكثر عن animateMotion في الفقرات القادمة. <mpath>: يستخدم بالاقتران مع عنصر animateMotion للإشارة إلى مسار حركة الذي سيستخدم كمسار لتحريك العناصر. مع العلم أن عنصر mpath مضمن داخل عنصر animationMotion قبل علامة الإغلاق. <keypoints> (خاصية HTML): تستخدم كخاصية لـ animateMotion لتوفير تحكم دقيق في سرعة حركة العناصر في مساراتها. <rotate> (خاصية HTML): تستخدم أيضًا كخاصية لـ animateMotion للتحكم في ما إذا كان الكائن يستجيب للدوران تلقائيًا بحيث يشير المحور السيني له في نفس الاتجاه (أو الاتجاه المعاكس) مثل متجه الظل الاتجاهي لمسار الحركة. هذه الخاصية هي مفتاح نجاح تحريك العناصر على امتداد مسار ما كما تتوقع للحركة أن تكون. مزيدًا من التوضيح في الجزئية الخاصة بشرح animationMotion. حركة رسوم SVG من الممكن أن تكون مشابهة لرسوم CSS والانتقالات عبرها حسب طبيعتيهما. مفاتيح الحركة تُضبط وبالتالي تتحرك العناصر وتتغير الألوان …إلخ. مع ذلك بإمكان رسوم SVG القيام بأمور لا تستطيع رسوم CSS القيام بها وهذا ما سنتطرق له لاحقًا. لماذا قد تستخدم الرسوم المُتجهة (SVG Animation)؟ من الممكن تصميم وتحريك الرسوم المتجهة (SVG) باستخدام CSS. بشكل أساسي التأثيرات الحركية التي تطبق على عناصر HTML من الممكن أيضًا تطبيقها على عناصر SVG. ولكن هناك بعض الخصائص التي يمكن تطبيقها على SVG ليست فعالة على CSS. مسار SVG على سبيل المثال يأتي مع مجموعة من البيانات (d=""‎ خاصية HTML) التي تعطي للمسار شكلًا. تلك البيانات يمكن تعريفها وتحريكها خلال SMIL ولكن الأمر لا ينطبق على CSS. ذلك لأن عناصر SVG تتصف بمجموعة من خاصيات HTML تُعرف بخاصيات للعرض. بعض تلك الخاصيات من الممكن معايرتها والتحكم فيها وتحريكها باستخدام CSS وهذا لا ينطبق على الخاصيات جميعها. وهكذا ترى أن العديد من تأثيرات الحركة يمكن تطبيقها حاليًا باستخدام CSS. وأما الفجوات في استخدام SVG CSS من الممكن تجاوزها عند استخدام JavaScript أو SVG المستمدة من SMIL. إذا كنت تفضل استخدام JavaScript فيستحسن أن تجرب snap.svg بواسطة Dmitry Baranovsky الذي يعد كمكتبة حافلة بالكثير من النصوص البرمجية الخاصة بـ SVG. ويمكنك الاطلاع على العديد من الأمثلة على ذلك. أما إذا كنت تفضل الخوض في مسار تعريفي أكثر بإمكانك استخدام عناصر التحريك التي سيتطرق لها هذا الدليل. ميزة أخرى تميز SMIL عن JS هي أن رسوم JS لا تعمل عند تضمين رسوم SVG كصور img أو استعمالها كصورة خلفية (background-image) في CSS. رسوم SMIL تعمل في كلا الحالتين أو هكذا ينبغي. وهذه ميزة عظيمة. لربما ستجد نفسك قد اخترت SMIL عن غيرها من الخيارات بسبب تلك الميزة. ومن هنا فهذا الدليل سيؤدي دور المساعد لتتعلم كيف تستخدم SMIL بدءًا من اليوم. دعم المتصفح والنسخ الاحتياطية دعم المتصفح لرسوم SMIL لائق للغاية. حيث أنه يعمل في جميع المتصفحات باستثناء Internet Explorer و Opera Mini. للحصول على نظرة شاملة حول دعم المتصفح، يمكنك الرجوع إلى جدول التوافق. إذا كنت بحاجة إلى توفير نسخة احتياطية لحركة الرسوم لـ SMIL، يمكنك اختبار دعم المتصفح أثناء التنقل باستخدام Modernizr. إذا لم يكن SMIL مدعومًا ، فيمكنك تقديم نوع من الاستعاضة (رسوم JavaScript متحركة، تجربة بديلة، …إلخ). تحديد الهدف من الحركة باستخدام xlink: href بغض النظر عن أي من عناصر التحريك الأربعة التي تختارها، فأنت بحاجة إلى تحديد هدف الحركة المحدد بواسطة هذا العنصر. لتحديد الهدف يمكنك استخدام خاصية xlink: href. تعطي خاصية HTML هذه مرجع URI للعنصر المستهدف في التحريك والذي سيجري تعديله بمرور الوقت. يجب أن يكون العنصر المستهدف جزءًا من مستند SVG الحالي. <rect id="cool_shape" ... /> <animate xlink:href="#cool_shape" ... /> إذا واجهت عناصر التحريك في SVG من قبل، فمن المحتمل أنك رأيتها متداخلة مع العنصر المفترض تحريكه. هذا ممكن تبعًا لمحددات: إذا لم تتوفر خاصية xlink: hrefHTML، فسيكون العنصر المستهدف هو العنصر الأصل المباشر لعنصر الحركة الحالي. <rect id="cool_shape" ... > <animate ... /> </rect> لذلك إذا كنت تريد "تضمين" الرسم المتحرك في العنصر الذي ينطبق عليه، فبإمكانك القيام بذلك. وإذا كنت تريد أن تبقي الرسم المتحرك منفصل في مكان آخر في المستند، فيمكنك القيام بذلك أيضًا، وحدّد الهدف من كل حركة باستخدام xlink: href. كلا الطريقتين تعملان بشكل جيد. تحديد الخاصية المستهدفة للحركة باستخدام attributeName وattributeType تشترك جميع عناصر التحريك أيضًا في خاصية HTML أخرى وهي attributeName. تُستخدم attributeName لتحديد اسم خاصية HTML التي تقوم بتحريكها. على سبيل المثال، إذا كنت ترغب في تحريك موضع مركز الدائرة <circle> على المحور السيني (x-axis)، حدد cx كقيمة لخاصية attributeName. تأخذ attributeName قيمة واحدة فقط، ولا تقبل قيم متعددة، لذلك يمكنك تنشيط خاصية HTML واحدة فقط في كل مرة. إذا كنت ترغب في تحريك أكثر من خاصية HTML واحدة فأنت بحاجة إلى تعريف أكثر من تحريك واحد للعنصر. لربما لا توجد طريقة أخرى ولهذا لـ CSS أفضلية عن SMIL. ولكن مرة أخرى، نظرًا للقيم المحتملة لخاصيات الحركة الأخرى (والتي سنتطرق لها بعد ذلك)، فمن المنطقي تحديد اسم خاصية HTML واحد فقط في المرة الواحدة، وإلا فقد تصبح قيم الخاصيات الأخرى معقدة للغاية بحيث لا يمكن التعامل معها. عند تحديد اسم خاصية HTML، يمكنك إضافة البادئة XMLNS (اختصار namespace XML) للإشارة إلى مجال اسم خاصية HTML. يمكن أيضًا تحديد مجال الاسم باستخدام الخاصية attributeType. على سبيل المثال، تعد بعض الخاصيات جزءًا من مساحة اسم CSS (مما يعني أنه يمكن العثور عليها كخاصية CSS أيضًا) والبعض الآخر XML فقط. يمكن العثور على جدول يوضح هذه الخاصيات هنا. خاصيات HTML في الجدول ليست كلها من خاصيات SVG إنها فقط تلك التي يمكن ضبطها باستخدام CSS. بعضها متاح بالفعل كخصائص CSS. إذا لم تُعيّن قيمة attributeType بشكل صريح أو عُيّنت على "تلقائي"auto، يجب أن يبحث المتصفح أولاً من خلال قائمة خصائص CSS عن اسم خاصية مطابق، وإذا لم يُعثر على أي منهما سيبحث في مجال اسم XML الافتراضية للعنصر. على سبيل المثال، يوضح المقتطف التالي التحكم في تحريك شفافية مستطيل SVG. نظرًا لأن خاصية HTML للشفافية opacity متوفرة أيضًا كخاصية CSS، تُعين attributeType على مجال اسم CSS: <rect> <animate attributeType="CSS" attributeName="opacity" from="1" to="0" dur="5s" repeatCount="indefinite" /> </rect> سنتجاوز خاصيات الحركة الأخرى في الأمثلة التالية أدناه. جميع خاصيات التحريك متعارف عليها ما بين جميع عناصر التحريك ما لم يذكر خلاف ذلك. تحريك خاصية HTML لعنصر من قيمة لأخرى على مدار فترة زمنية وتحديد الحالة النهائية: from وby وto وdur وfill ابدأ بتحريك دائرة من موقع إلى آخر عن طريق تغيير قيمة الخاصية cx الخاصة بها (والتي تحدد قيمة x لمركزها). عنصر <animate> سيتيح لك القيام بذلك حيث يستخدم لتحريك خاصية واحدة في كل مرة. عادةً ما تتحرك الخاصيات التي تأخذ قيم رقمية ولونية باستخدام هذا العنصر. تفقد الجدول للتعرف على الخاصيات التي يمكن تحريكها. للتغيير من قيمة إلى أخرى خلال فترة زمنية يمكنك استخدام الخاصيات From وto وdur. ستحتاج أيضًأ إلى تحديد بداية الحركة عن طريق خاصية begin. <circle id="my-circle" r="30" cx="50" cy="50" fill="orange" /> <animate xlink:href="#my-circle" attributeName="cx" from="50" to="450" dur="1s" begin="click" fill="freeze" /> يوضح المثال السابق طريقة تعريف دائرة وتحريكها من مركزها من الموضع الأولي عند 50 وحدة ثم إلى الموضع الجديد 450 وحدة على امتداد محور السينات (x-axis). تتحدد قيمة البداية begin بالنقر click أي أن الدائرة سوف تتحرك عند النقر عليها. ويمكنك أيضًا قيمة البداية كقيمة زمنية. على سبيل المثال، تعيين القيمة "begin="0s يعني أن حركة العنصر ستبدأ بمجرد تحميل الصفحة. بإمكانك تأخير حركة العنصر عند تحديد قيمة موجبة، مثلًا "begin="2s تعني أن حركة العنصر ستبدأ بعد ثانيتين من تحميل الصفحة. الأكثر إثارةً هو أنه بإمكانك تعيين قيمة البداية begin مثل s1+click لتبدأ حركة العنصر خلال ثانية واحدة بعد النقر عليه! علاوةً على ذلك بإمكانك استخدام قيم أخرى تسمح لك بمزامنة العنصر بدون حساب المدة الزمنية وزمن التأخير للعناصر المتحركة الأخرى. ستعرف المزيد لاحقًا. خاصية dur تكافئ animation-duration في CSS. الخاصيتان from وto تشبهان الإطارين المفتاحيين (keyframes)‏ from وto في قاعدة ‎@keyframe الخاصة بـ CSS: @keyframes moveCircle { from { /* start value */ } to { /* end value */ } } أما خاصية HTML التعبئة fill (والتي تحمل نفس اسم خاصية HTML "التعبئة" التي تحدد لون العنصر لسوء الحظ) فهي تشبه خاصية وضع ملء الرسوم fill-mode property والتي تحدد ما إذا كان على العنصر أن يعود لحالته الأولية بعد انتهاء عملية التحريك. تتشابه قيم SVG مع تلك الموجودة في CSS، باستثناء اختلاف التسميات: freeze: يُعني هذا التأثير بتجميد قيمة التأثير لآخر قيمة في الفترة النشطة. يبقى التأثير مجمدًا للفترة الزمنية المتبقية في المستند أو حتى إعادة تشغيل الحركة. remove: يقوم هذا التأثير بإزالة تأثير الحركة (أي أنه لم يعُد مُطبقًا) عند انتهاء المدة النشطة للحركة. بعد انتهاء زمن الحركة لم يعد الهدف متأثرًا بالحركة ما لم يُعاد تشغيل الحركة من جديد. حاول تغيير القيم في العرض الحي المباشر لترى كيف تتأثر الحركة: تستخدم خاصية by لتعيين إزاحة نسبية للحركة. كما يوحي الاسم فبإمكانك استخدام الخاصية HTML لتحديد مقدار الإزاحة التي تريد للحركة أن تتقدم بها. يكون تأثير الخاصية by مرئيًا عند تقدمك خلال مدة الحركة في خطوات منفصلة، على غرار الطريقة المعمول بها في CSS عبر steps()‎. المكافئ لدالة steps()‎ في CSS هو "calcMode="discrete في SVG، وسنتطرق لخاصية calcMode لاحقًا في المقالة. الحالة الأخرى عندما يكون تأثير by أكثر وضوحًا عند تحديد خاصية to. سيأتي مثال على ذلك لاحقًا. وأخيرًا وليس آخرًا، تأتي by بفائدة أخرى عند العمل مع الحركة المضافة والتراكمية. إعادة تشغيل الحركة باستخدام restart قد يكون من المفيد وقف إعادة تشغيل الحركة أثناء نشاطها. للقيام بذلك تمنح SVG خاصية restart المزودة بخيارات ثلاثة: always: تمكنك من إعادة تشغيل الحركة في أي وقت حيث أنها القيمة الافتراضية. whenNotActive: يمكن إعادة تشغيل الحركة فقط عندما لا تكون نشطة (أي بعد النهاية النشطة). أما محاولات إعادة تشغيل الحركة خلال المدة النشطة فيتم تجاهلها. never: لا يمكن إعادة تشغيل العنصر لما تبقى من المدة البسيطة الحالية لحاوية الزمن. (في حالة SVG نظرًا لأن حاوية الوقت الأصلية هي جزء من مستند SVG، فلا يمكن إعادة تشغيل الحركة للفترة المتبقية من مدة المستند). تسمية الحركة ومزامنتها افترض أننا نريد تحريك موضع ولون دائرة، بحيث يتغير اللون في نهاية الحركة. بإمكانك القيام بذلك عن طريق تحديد قيمة begin لحركة تغيير اللون لتكون مساوية لمدة الحركة dur، هذه هي الطريقة التي نفعلها عادة في CSS. SMIL مع ذلك، لديها ميزة لطيفة التعامل مع الأحداث. لقد ذكرنا قبل ذلك أن الخاصية begin تقبل قيمًا مثل click + 5s. تسمى هذه القيمة "قيمة الحدث (event value)، وتتكون في هذه الحالة من مرجع حدث متبوعًا بـ "قيمة الساعة". الجزء المثير للاهتمام هنا هو تسمية الجزء الثاني: "قيمة الساعة". لماذا ليست مجرد "قيمة زمنية"؟ حسنًا، الجواب هو أنه يمكنك استخدام قيمة الساعة حرفيًا مثل "10min" أو "01:33" أي ما يعادل "دقيقة و 33 ثانية"، أو حتى "02:30:03" (ساعتان، 30 دقيقة، و 3 ثوان). في وقت كتابة هذا التقرير، لم تُطبق قيم الساعة بالكامل في أي متصفح. لذا، إذا أردنا العودة إلى العرض الحي السابق واستخدمت click + 01:30، إذا بدأ متصفح يدعمه، ستبدأ الحركة خلال دقيقة و 30 ثانية بعد النقر فوق الدائرة. نوع آخر من القيم التي يمكن أن يقبلها هو معرف رسوم متحركة أخرى يتبعها مرجع حدث. إذا كان لديك حركتان (أو أكثر) (سواء طبقت على نفس العنصر أم لا!) وتريد مزامنتهما بحيث تبدأ إحداهما نسبة إلى الأخرى، يمكنك القيام بذلك دون الحاجة إلى معرفة مدة الحركة المتبقية. على سبيل المثال، في العرض الحي التالي، يبدأ المستطيل الأزرق في التحرك لمدة ثانية واحدة بعد بدء حركة الدائرة. و ذلك عن طريق إعطاء معرف كل حركة ID، ثم استخدام هذا المعرف مع الحدث begin كما هو موضح في التعليمات البرمجية التالية: <circle id="orange-circle" r="30" cx="50" cy="50" fill="orange" /> <rect id="blue-rectangle" width="50" height="50" x="25" y="200" fill="#0099cc"></rect> <animate xlink:href="#orange-circle" attributeName="cx" from="50" to="450" dur="5s" begin="click" fill="freeze" d="circ-anim" /> <animate xlink:href="#blue-rectangle" attributeName="x" from="50" to="425" dur="5s" begin="circ-anim.begin + 1s" fill="freeze" id="rect-anim" /> البداية "begin="circ-anim.begin + 1s هي الجزء الذي يخبر المتصفح ببدء الحركة للمستطيل بعد ثانية واحدة من بداية الدائرة. تفقد العرض التوضيحي التالي: يمكنك أيضًا بدء الحركة للمستطيل بعد انتهاء حركة الدائرة باستخدام حدث النهاية end بتتبع الشيفرة التالية: <animate xlink:href="#blue-rectangle" attributeName="x" from="50" to="425" dur="5s" begin="circ-anim.end" fill="freeze" id="rect-anim"/> يمكنك حتى بدء تشغيله قبل نهاية حركة الدائرة باستخدام الشيفرة التالية: <animate xlink:href="#blue-rectangle" attributeName="x" from="50" to="425" dur="5s" begin="circ-anim.end - 3s" fill="freeze" id="rect-anim"/> تكرار الحركة باستخدام repeatCount إذا كنت ترغب في تشغيل الحركة أكثر من مرة، فيمكنك القيام بذلك باستخدام خاصية repeatCount. يمكنك تحديد عدد المرات التي ترغب في تكرارها، أو استخدام الكلمة المفتاحية الأساسية غير المحددة لجعلها تتكرر إلى ما لا نهاية infinite. لذلك، إذا أردنا تكرار الحركة للدائرة مرتين، ستكون الشيفرة كما يلي: <animate xlink:href="#orange-circle" attributeName="cx" from="50" to="450" dur="5s" begin="click" repeatCount="2" fill="freeze" id="circ-anim" /> يمكنك التحقق من العرض الحي هنا. في المثال الحي، عين عدد التكرار ليكون 2 على الدائرة، وبشكل غير نهائي في المربع infinite. لاحظ طريقة إعادة تشغيل الحركة من القيمة الأولية from من القيمة بدلاً من القيمة التي وصلت إليها في نهاية الحركة. لسوء الحظ، لا تتضمن SMIL طريقة للرجوع إليها بين قيم البداية والنهاية مثل CSS التي تتيح لنا القيام بذلك. في CSS، تحدد خاصية اتجاه الحركة animation-direction ما إذا كانت الحركة يجب أن تنفذ بشكل معاكس على بعض أو كل الدورات أو التكرارات. Animation-direction: alternate: تعني القيمة البديلة أن عمليات تكرار دورة الحركة ذات القيم الفردية يتم تشغيلها في الاتجاه الطبيعي، وأما القيم الزوجية فتكون في اتجاه عكسي. هذا يعني أن الدورة الأولى ستكون من البداية إلى النهاية، ثم ستليها الدورة الثانية من النهاية إلى البداية، ثم الدورة الثالثة من البداية إلى النهاية، وهكذا. في SMIL للقيام بذلك، يجب عليك استخدام JavaScript لتغيير قيم الخاصيات from وto بشكل صريح. كتب جون مكبارتلاند من Big Bite Creative منشورًا لفترة من الوقت يشرح فيه كيف فعل ذلك من أجل تحريك رمز القائمة الذي عمل عليه. حل آخر هو تحديد القيمة النهائية كقيمة متوسطة ومن ثم تكون القيمة النهائية هي نفسها القيمة الأولية. على سبيل المثال، يمكنك تعيين الحركة لتبدأ من from قيمة وتنتهي بنفس القيمة مع to وكذلك باستثناء أنك تحدد ما كنت قد حددته ليكون قيمة نهائية كقيمة وسيطة بين from وto. في CSS، سنفعل ذلك باستخدام شيء مثل هذا: @keyframes example { from, to { left: 0; } 50% { left: 300px; } } المكافئ في SMIL هو استخدام خاصية values، والتي سنشرحها قريبًا. ومع ذلك، فإن الحل المذكور أعلاه قد يعمل أو لا يعمل وفقًا لنوع الحركة التي تتبعها، وما إذا كنت تقوم بسلسلة الحركة أم لا، أو تكرارها، أو القيام برسوم متحركة إضافية. إليكم رسمًا جميلًا بسيطًا من قِبل Miles Elam يستخدم فيه بعض أوقات البدء المتأخرة: تقييد وقت التكرار باستخدام repeatDur قد تصبح حركة العنصر المستمرة مزعجة أو غير متآلفة مع الاستخدام في حالة استمرار الحركة لفترة طويلة. لذلك، قد يكون من الجيد ضبط وقت التكرار على فترة زمنية معينة، وإيقاف التكرار بعد مرور بعض الوقت بالنسبة لبداية المستند. هذا هو المعروف باسم وقت العرض. يشير وقت العرض التقديمي إلى أن الموضع في الخط الزمني بالنسبة للمستند يبدأ من جزء معين. يُحدد باستخدام خاصية repeatDur. يشبه بناء الجملة الخاص بقيمة الساعة، ولكن بدلاً من أن يكون متصلاً بحدث حركة آخر أو حدث تفاعلي، فهو يتعلق ببداية المستند. على سبيل المثال، ستؤدي الشيفرة التالية إلى إيقاف تكرار الحركة لمدة دقيقة و 30 ثانية بعد بدء المستند: <animate xlink:href="#orange-circle" attributeName="cx" from="50" to="450" dur="2s" begin="0s" repeatCount="indefinite" repeatDur="01:30" fill="freeze" id="circ-anim" /> وهنا تستطيع مشاهدة العرض الحي: مزامنة الحركة على أساس عدد التكرارات الآن لنرجع خطوة إلى المزامنة بين موضوعين في التحريك. في الواقع، في SMIL يمكنك مزامنة الحركة بحيث تبدأ حركة إحداهما بناء على عدد تكرار حركة الأخرى. على سبيل المثال، يمكنك بدء رسم متحرك بعد تكرار رقم آخر، بإضافة أو طرح مقدار الوقت الذي قد ترغب في إضافته. المثال التالي يبدأ في تحريك للمستطيل في التكرار الثاني لحركة الدائرة: <animate xlink:href="#blue-rectangle" attributeName="x" from="50" to="425" dur="5s" begin="circ-anim.repeat(2)" fill="freeze" id="rect-anim" /> يوضح العرض التالي بداية حركة المستطيل بعد ثانيتين من ثاني تكرار لحركة الدائرة: يمكنك الاطلاع على نموذج لأساسيات SVG بإصدارها الثاني من إعداد David Eisenberg. التحكم في قيم الإطارات المفتاحية للحركة: keyTimes وvalues في CSS يمكننا تحديد القيم التي نريد أن تأخذها حركة الرسوم الخاصة بنا في إطار معين أثناء التحريك. على سبيل المثال، إذا كنت تحرك العنصر بإزاحة لليساربدلًا من تنشيطه من 0 إلى 300 مثلاً، يمكنك تحريكه بحيث يأخذ قيمًا معينة مثل هذا: @keyframes example { 0% { left: 0; } 50% { left: 320px; } 80% { left: 270px; } 100% { left: 300px; } } الإطارات 0٪ و 20٪ و 80٪ و 100٪ هي إطارات الحركة، والقيم الموجودة في كل إطار تحدد قيمته. التأثير الموصوف أعلاه هو أحد العناصر التي ترتد عن الحائط، ثم تعود إلى الموضع النهائي. في SMIL، يمكنك التحكم في القيم لكل إطار بطريقة مماثلة، لكن بناء الشيفرة مختلف تمامًا. لتحديد إطارات مفتاحية، يمكنك استخدام خاصية keyTimes ثم لتحديد قيمة الخاصية المتحركة لكل إطار، يمكنك استخدام خاصية values. اصطلاحات التسمية في SMIL مريحة للغاية. إذا أردنا العودة إلى الدائرة المتحركة التي رافقتنا في الأمثلة السابقة، واستخدمنا قيمًا مماثلة لتلك الموجودة في إطارات CSS الأساسية أعلاه، فإن الشيفرة سيبدو كما يلي: <animate xlink:href="#orange-circle" attributeName="cx" from="50" to="450" dur="2s" begin="click" values="50; 490; 350; 450" keyTimes="0; 0.5; 0.8; 1" fill="freeze" id="circ-anim" /> إذن ماذا فعلنا هناك؟ أول ما يجب ملاحظته هنا هو تحديد أوقات الإطار الرئيسي والقيم الوسيطة كقوائم. خاصية keyTimes هي قائمة مفصولة بفواصل منقوطة لقيم الوقت المستخدمة للتحكم في سرعة الحركة. في كل مرة في القائمة يتوافق مع قيمة في قائمة خاصية values، ويحدد متى تُستخدم القيمة في وظيفة التحريك. تُحدد كل قيمة زمنية في قائمة keyTimes كقيمة نقطة عائمة بين 0 و 1 (ضمنًا)، مما يمثل إزاحة متناسبة في المدة البسيطة لعنصر الحركة. لذا تشبه أوقات المفاتيح تلك الموجودة في CSS، إلا أنه بدلًا من تحديدها كنسب مئوية، فإنك تحددها ككسر. ما يلي هو العرض الحي للشيفرة أعلاه. انقر على الدائرة لبدء الحركة. لاحظ أنه إذا استخدمت قائمةvalues، فإن الحركة ستطبق القيم بالترتيب على مدار فترة الحركة. إذا حددت قائمة values، فسيتم تجاهل أي من الخاصيات from وto وby. في هذه المرحلة، تجدر الإشارة أيضًا إلى أنه يمكنك استخدام خاصية values بدون خاصية keyTimes - تنتشر القيم تلقائيًا بالتساوي خلال الوقت لكل قيمة calcMode بخلاف paced (راجع القسم التالي). التحكم في سرعة الحركة باستخدام التخفيف المخصص: calcMode و keySplines سنتطرق إلى موازنة CSS-SMIL مرة أخرى لأن بناء SMIL ومفاهيمه سيكون أسهل بكثير لفهم ما إذا كنت ستعتاد بالفعل على التحريك بواسطة CSS. في CSS، يمكنك اختيار تغيير سرعة الحركة الافتراضية الموحدة وتحديد وظيفة تخفيف مخصصة تتحكم في الحركة، باستخدام خاصية animation-timing-function. يمكن أن تكون وظيفة التوقيت واحدة من الكلمات المفتاحية المحددة مسبقًا، أو وظيفة مكعب cubic bezier. يمكن إنشاء ذلك باستخدام أداة مثل هذه المعدة بواسطة Lea Verou. في SMIL، تُحدد سرعة الحركة باستخدام خاصية calcMode. سرعة الحركة الافتراضية هي linear لجميع عناصر الحركة باستثناء animateMotion (سنصل إليها لاحقًا في المقالة). بالإضافة إلى قيمة linear، يمكنك تعيين القيمة إلى: discrete أوpaced أوspline. discrete: تحدد أن وظيفة الحركة ستقفز من قيمة إلى أخرى دون أي تقاطع. هذا مشابه للدالة steps()‎ في CSS. paced: يشبه linear، إلا أنه سيتجاهل أي أوقات تقدم وسطية تحددها keyTimes. ويحسب المسافة بين القيم اللاحقة ويقسم الوقت وفقًا لذلك. إذا كانت قيمك كلها بترتيب خطي linear، فلن تلاحظ الفرق. ولكن إذا كانت ذهابًا وإيابًا، أو إذا كانت ألوانًا (والتي يعامل معها كقيم متجه ثلاثي الأبعاد)، فسترى بالتأكيد القيم الوسيطة. فيما يلي عرض حي من Amelia Bellamy-Royds، يُظهر الفرق بين قيم calcMode الثلاث المذكورة حتى الآن: spline: وهي القيمة الرابعة المقبولة بواسطة calcMode. يتشابك من قيمة واحدة في قائمة values إلى القيمة التالية وفقًا لوظيفة الوقت المحددة بواسطة cubic Bezier spline. تعرف نقاط الشريحة في خاصية keyTimes، وتحددد نقاط التحكم لكل فاصل زمني في خاصية keySplines. ربما لاحظت الخاصية HTML الجديدة في الجملة الأخيرة: خاصية keySplines. لذا، ماذا تفعل خاصية keySplines؟ مرة أخرى، إلى ما يعادلها في CSS. في CSS، يمكنك تحديد سرعة الحركة داخل كل إطار رئيسي، بدلاً من تحديد سرعة حركة واحدة للحركة بأكملها. يمنحك هذا تحكمًا أفضل في كيفية متابعة كل حركة للإطار الرئيسي. مثال باستخدام هذه الميزة هو إنشاء تأثير ارتداد الكرة. قد تبدو الإطارات المفتاحية لذلك كما يلي: @keyframes bounce { 0% { top: 0; animation-timing-function: ease-in; } 15% { top: 200px; animation-timing-function: ease-out; } 30% { top: 70px; animation-timing-function: ease-in; } 45% { top: 200px; animation-timing-function: ease-out; } 60% { top: 120px; animation-timing-function: ease-in; } 75% { top: 200px; animation-timing-function: ease-out; } 90% { top: 170px; animation-timing-function: ease-in; } 100% { top: 200px; animation-timing-function: ease-out; } } بدلاً من تسهيل الكلمات المفتاحية، كان بإمكاننا استخدام الدالة ()cubic-bezier ذات الصلة: ease-in = cubic-bezier(0.47, 0, 0.745, 0.715) ease-out = cubic-bezier(0.39, 0.575, 0.565, 1) لنبدأ بتحديد الأوقات الرئيسية وقائمة القيم للدائرة البرتقالية لتخضع لنفس تأثير الارتداد: <animate xlink:href="#orange-circle" attributeName="cy" from="50" to="250" dur="3s" begin="click" values="50; 250; 120;250; 170; 250; 210; 250" keyTimes="0; 0.15; 0.3; 0.45; 0.6; 0.75; 0.9; 1" fill="freeze" id="circ-anim" /> ستبدأ الحركة عند النقر، وستتوقف بمجرد وصولها إلى القيمة النهائية. بعد ذلك، من أجل تحديد وتيرة كل إطار رئيسي، سنضيف خاصية keySplines. تأخذ خاصية keySplines مجموعة من نقاط التحكم bezier المرتبطة بقائمة keyTimes، وتحديد وظيفة bezier المكعبة التي تتحكم في سرعة الفاصل الزمني. قيمة الخاصية HTML هي قائمة مفصولة بفواصل منقوطة لوصف نقطة التحكم. كل وصف لنقطة التحكم عبارة عن مجموعة من أربع قيم: y1 x1 x2 y2، تصف نقاط التحكم bezier لشريحة وقت واحدة. يجب أن تكون جميع القيم في النطاق من 0 إلى 1، وتستبعد الخاصية HTML ما لم تُعين calcMode على شكل spline. بدلاً من أخذ دوال cubic-bezier كقيم، تأخذ keySplines إحداثيات نقطتي التحكم المستخدمة لرسم المنحنى. يمكن رؤية نقاط التحكم في لقطة الشاشة التالية المأخوذة من أداة Lea. تعرض لقطة الشاشة أيضًا إحداثيات كل نقطة، كل لون بنفس لون النقطة نفسها. بالنسبة لخاصية keySplines، هذه هي القيم التي سنستخدمها لتحديد سرعة الحركة الموجودة في keyframe. يسمح SMIL بفصل هذه القيم إما بفواصل بمسافة بيضاء اختيارية أو بمسافة بيضاء فقط. قيم keyTimes التي تحدد الجزء المرتبط هي "نقاط الربط" bezier، وقيم keySplines هي نقاط التحكم. وبالتالي، يجب أن يكون هناك مجموعة واحدة أقل من نقاط التحكم من keyTimes. إذا عدنا إلى مثال الكرة المرتدة، تُعرض إحداثيات نقطة التحكم للدالتين ease-in و ease-out كما هو موضح في الصور التالية: لترجمة ذلك إلى عنصر متحرك في SVG، نحصل على الشيفرة التالي: <animate xlink:href="#orange-circle" attributeName="cy" from="50" to="250" dur="3s" begin="click" values="50; 250; 120;250; 170; 250; 210; 250" keyTimes="0; 0.15; 0.3; 0.45; 0.6; 0.75; 0.9; 1" keySplines=".42 0 1 1; 0 0 .59 1; .42 0 1 1; 0 0 .59 1; .42 0 1 1; 0 0 .59 1; .42 0 1 1; 0 0 .59 1;" fill="freeze" id="circ-anim"/> وهنا تتابع العرض الحي: إذا كنت ترغب فقط في تحديد دوال التسارع (easing function) بأكملها دون أي قيم وسيطة، فلا يزال يتعين عليك تحديد الإطارات المفتاحية باستخدام خاصية keyTimes، ولكن عليك فقط تحديد إطارات المفاتيح للبداية والنهاية، وهي1 ؛ 0، وليس القيم المتوسطة values. الحركات المضافة والتراكمية: addictive وaccumulate في بعض الأحيان، من المفيد تحديد رسم متحرك يبدأ من حيث انتهت الحركة السابقة؛ أو آخر يستخدم المجموع التراكمي للحركات السابقة كقيمة للمتابعة. لذلك، يحتوي SVG على خاصيتين مناسبتين: addictive وaccumulate. افترض أن لديك عنصرًا تريد أن "يزداد" عرضه، أو خطًا تريد زيادة طوله، أو عنصرًا تريد نقله خطوة بخطوة من موضع إلى آخر، عبر خطوات منفصلة. هذه الميزة مفيدة بشكل خاص للحركة المتكررة. تمامًا مثل أي حركة أخرى، ستحدد قيم from وto. ومع ذلك، عند تعيين additive إلىsum، ستكون قيمتهما متناسبة مع القيمة الأصلية للخاصية HTML المتحركة. لذا، بالعودة إلى دائرتنا، يكون الموضع الأولي لـ cx هو 50. عندما تقوم بتعيين from = "0"‎ وto = "100"‎، فإن الصفر إذا كان في الواقع هو 50 الأصلي، و 100 هو في الواقع 50 + 100؛ بمعنى آخر، من الناحية العملية يشبه from = "50" to = "150"‎. من خلال القيام بذلك، نحصل على النتيجة التالية: هذا هو كل ما تفعله خاصية additive. إنه تحدد فقط ما إذا كان يجب أن تكون القيم from وto متناسبة مع القيمة الحالية أم لا. تأخذ الخاصية HTML واحدة من قيمتين فقط: sum وreplace. الأخير هو القيمة الافتراضية، وهذا يعني بشكل أساسي أن القيم from وtoسوف تحل محل القيم الحالية /الأصلية، والتي قد تؤدي في النهاية إلى قفزة غريبة قبل بدء الحركة. (حاول استبدال sum بـreplace في المثال أعلاه للحصول على مقارنة أفضل). ومع ذلك، ماذا لو أردنا إضافة القيم بحيث يبدأ التكرار الثاني من قيمة نهاية القيمة السابقة؟ هذا هو المكان الذي تأتي فيه خاصية accumulate. تتحكم خاصية accumulate فيما إذا كانت الحركة تراكمية أم لا. القيمة الافتراضية هي none، مما يعني أنه عند تكرار الحركة على سبيل المثال، ستبدأ من البداية. ومع ذلك، يمكنك تعيينها علىsum، والتي تحدد أن كل إعادة للتكرار بعد الأول يبني على القيمة الأخيرة للتكرار السابق. لذلك، إذا أردنا العودة إلى الحركة السابقة وتحديد accumulate = "sum"‎، فسنحصل على النتيجة المفضلة التالية: لاحظ أنه يتم تجاهل خاصية accumulate إذا كانت قيمة الخاصية HTML الهدف لا تدعم الإضافة، أو إذا كان العنصر المتحرك لا يتكرر. سيتم تجاهله أيضًا إذا عُينت وظيفة الحركة مع خاصية to فقط. تحديد نهاية الحركة باستخدام end كما أنه بإمكانك تحديد بداية حركة الرسوم فبإمكانك أيضًا تحديد نهايتها باستخدام خاصية end. على سبيل المثال، يمكنك تعيين حركة عنصر ما لتتكرر بشكل دائم ومن ثم إيقاف الحركة عند بداية حركة عنصر آخر. تأخذ خاصية end قيم شبيهة للقيم التي تأخذها begin. بإمكانك تحديد قيم مطلقة أو نسبية للوقت أو تطبيق إزاحة أو تكرار أو غيرها. فمثلًا في العرض الحي التالي تتحرك الدائرة ذات اللون البرتقالي ببطء في دورة تستمر 30 ثانية بالاتجاه الآخر لمسطح العمل. الدائرة ذات اللون الأخضر ستتحرك فقط عند النقر عليها. حركة الدائرة البرتقالية ستنتهي عند بدء حركة الدائرة الخضراء. انقر على الدائرة الخضراء وانظر كيف ستتوقف حركة الدائرة البرتقالية: يمكن تحقيق نفس التزامن للحركة عند تطبيق حركتين على نفس العنصر. على سبيل المثال، افترض تعيين حركة تغيير لون عنصر ما من قيمة لأخرى بشكل لانهائي. بعدها عند النقر على العنصر فإنه يتحرك للناحية الأخرى من مسطح العمل. والآن أوقف حركة تغيير اللون عند النقر على العنصر ومن بعدها تتوقف الحركة كليًا. تعيين فترات الحركة باستخدام قيم كلًا من begin وend في الواقع، تقبل كل من الخاصية begin وend قائمة القيم شبه المفصولة. ستتوافق كل قيمة في خاصية begin مع قيمة في خاصية end، وبالتالي تتشكل فواصل متحركة نشطة وغير نشطة. يمكنك أن تفكر في هذا على أنه يشبه سيارة متحركة، حيث تكون إطارات السيارة نشطة ومن ثم غير نشطة لفترات زمنية، اعتمادًا على ما إذا كانت السيارة تتحرك أم لا. يمكنك أيضًا إنشاء تأثير سيارة متحركة من خلال تطبيق الحركة على السيارة: أحدها يترجم السيارة أو يحركها على طول مسار يمثل أيضًا حركة مضافة وتراكمية، والأخرى تدور إطارات السيارة في فواصل يمكن مزامنتها مع عملية التحويل. مثال يوضح أوقات البدء والانتهاء المتعددة (أي الفواصل الزمنية) هو العرض الحي التالي، حيث يدور المستطيل استنادًا إلى الفواصل الزمنية المحددة، ويتغير من نشط إلى غير نشط وفقًا لذلك. (أعد تشغيل العرض الحي إذا فاتتك الحركة). لاحظ أنه في المثال أعلاه، استخدمت عنصر<animateTransform> لتدوير المستطيل حول مركزه. سنتحدث عن هذا العنصر بمزيد من التفصيل في القسم التالي أدناه. لاحظ أيضًا أنه، حتى إذا قمت بتعيين تكرار repeatCount بشكل غير نهائي indefinite، سيتجاوز من خلال قيم end ولن يتكرر بتلك الصورة النهائية. تقييد المدة النشطة لعنصر باستخدام min وmax مثلما يمكنك تقييد وقت تكرار الحركة، يمكنك أيضًا تقييد المدة النشطة الخاصة بها. تحدد خاصيات min وmax الحد الأدنى والحد الأقصى لقيمة المدة النشطة على التوالي. حيث أنها توفر لنا وسيلة للسيطرة على الحد السفلي والعلوي من فترة العنصر النشط. تأخذ كلا الخاصيتين قيمة الساعة كقيمة. بالنسبة لـ min، يحدد طول الحد الأدنى لقيمة المدة النشطة، ويقاس بالوقت الفعلي للعنصر. يجب أن تكون القيمة أكبر من أو تساوي 0، وهي القيمة الافتراضية ولا تقيد المدة النشطة على الإطلاق. بالنسبة إلىmax، تحدد قيمة الساعة طول الحد الأقصى لقيمة المدة النشطة، وتُقاس في وقت العنصر النشط. يجب أن تكون القيمة أكبر من 0. القيمة الافتراضية لـ max هي indefinite. وهذا لا يقيد المدة النشطة على الإطلاق. إذا حددت كل من الخاصيتين min وmax، فيجب أن تكون قيمة max أكبر من أو تساوي قيمة min. وإلا فسيتم تجاهل كلا الخاصيتين. ولكن ما الذي يحدد المدة النشطة لعنصر ما؟ ذكرنا مدة التكرار من قبل، بالإضافة إلى "المدة البسيطة"، وهي مدة الحركة دون أي تكرار (محدد باستخدام dur)، فكيف تعمل كل هذه الأشياء معًا؟ من الذي يتجاوز ماذا؟ ثم ماذا عن الخاصية end التي سيتم تجاوزها ومن ثم ببساطة تنتهي الحركة؟ الطريقة التي يحدث بها ذلك هي أن المتصفح سيقوم أولاً بحساب المدة النشطة بناءً على قيم dur و repeatCount وrepeatDur وend. بعد ذلك، تعمل المدة المحسوبة مقابل قيم min وmax المحددة. إذا كانت النتيجة ضمن الحدود، تكون قيمة المدة المحسوبة الأولى صحيحة ولن تتغير. وإلا قد تحدث حالتان: إذا كانت المدة الزمنية المحسوبة الأولى أكبر من قيمة max، تعرف المدة النشطة للعنصر بأنها تساوي قيمة max. إذا كانت المدة المحسوبة الأولى أقل من قيمة min، تصبح المدة النشطة للعنصر مساوية للقيمة min ويكون سلوك العنصر كما يلي: إذا كانت مدة التكرار (أو المدة البسيطة إذا لم يتكرر العنصر) للعنصر أكبر من min، يُشغل العنصر بشكل طبيعي لمدة نشطة (min مقيدة). بخلاف ذلك، يعمل العنصر بشكل طبيعي خلال مدة التكرار (أو المدة البسيطة إذا لم يتكرر العنصر) ثم يُجمد أو يختفي عتمادًا على قيمة خاصية fill. هذا يتركنا مع تساؤل عن طريقة قيام المتصفح بحساب المدة النشطة فعليًا. من أجل الإيجاز، لن نخوض في التفاصيل هنا. ولكن هناك جدول شامل للغاية في المواصفات التي تعرض التكوينات المختلفة لخصائص dur، وrepeatCount، وrepeatDor وend، ثم توضح المدة الفعلية التي ستستند إليها كل مجموعة. يمكنك التحقق من الجدول وقراءة المزيد حول هذا الموضوع في هذا القسم من المواصفات أخيرًا، إذا حدد عنصر للبدء في الحركة قبل العنصر الآخر (على سبيل المثال مع قيمة إزاحة سالبة بسيطة)، يُقاس الحد الأدنى للمدة من وقت البدء المحسوب وليس بداية الملاحظة. هذا يعني أن قيمة min قد لا يكون لها أي تأثير ملحوظ. أمثلة على <animate>: تحوير المسارات إحدى الخاصيات التي يمكن تحريكها في SMIL (ولكن ليس في CSS)هي الخاصية d (اختصار لـ data) الخاصة بـ SVG <path>‎. تحتوي الخاصية d على البيانات التي تحدد الخطوط العريضة للشكل الذي ترسمه. تتكون بيانات المسار من مجموعة من الأوامر والإحداثيات التي تخبر المتصفح عن مكان وكيفية رسم النقاط والأقواس والخطوط التي تشكل المسار النهائي. يسمح لنا تنشيط هذه الخاصية HTML بتحويل مسارات SVG وإنشاء تأثيرات ربط الأشكال. ولكن لكي تتمكن من تحوير الأشكال، يجب أن يكون لأشكال المسار البداية والنهاية وأي مسار وسطي نفس عدد الرؤوس /النقاط بالضبط، ويجب أن تظهر بنفس الترتيب. إذا لم يتطابق عدد النقاط، فلن تعمل الحركة. والسبب في ذلك هو أن تغيير الشكل يحدث فعليًا عن طريق تحريك الرؤوس، وتحريف مواقعها، لذلك إذا كانت نقطة واحدة مفقودة أو غير متطابقة، فلن تُقرب المسارات. لتحريك مسارSVG، يمكنك تحديد attributeName لتكون d، ثم اضبط قيم from وto التي تحدد أشكال البداية والنهاية، ويمكنك استخدام خاصية values لتحديد أي قيم وسيطة تريد أن يمر الشكل فيما بينها. من أجل الإيجاز، لن نخوض في تفاصيل كيفية القيام بذلك هنا. بدلًا من ذلك، يمكنك قراءة هذا المقال الممتاز من تأليف Noah Blon، إذ يشرح كيف قام بتحوير الأشكال لإنشاء حركة التحميل باستخدام <animate>. بإمكانك الاطلاع على العرض الحي للمقال: وهنا مثال آخر لتحوير الأشكال من إعداد Felix Hornoiu: يمكنك حتى تحوير قيم المسار المستخدم كـ clipping mask مثال على ذلك من إعداد Heather Buchel: الحركة على طول المسارات الافتراضية: العنصر <animateMotion> يعد عنصر<animateMotion> عنصر الحركة المفضل في SMIL. يمكنك استخدامه لنقل عنصر على طول المسار. عن طريق تحديد مسار الحركة باستخدام إحدى الطريقتين اللتين سنتطرق لهما بعد ذلك، ثم لإعداد العنصر بحيث يتحرك على طول هذا المسار. يقبل عنصر<animateMotion> نفس الخاصيات المذكورة سابقًا، بالإضافة إلى ثلاث خاصيات أخرى: keyPoints، و rotate، وpath. أيضًا، هناك اختلاف واحد فيما يتعلق بخاصية calcMode، حيث تكون القيمة الافتراضية لـ <animateMotion> هي paced، وليست linear. تحديد مسار الحركة باستخدام خاصية path تستخدم خاصية path لتحديد مسار الحركة. حيث يُعبر عنها بنفس التنسيق وتُفسر بنفس طريقة الخاصية d في العنصر path. يتمثل تأثير الحركة لمسار الحركة في إضافة مصفوفة تحويل تكميلية إلى مصفوفة التحويل الحالية للكائن المشار إليه والتي تتسبب في ترجمة على طول المحورين x و y لنظام إحداثيات المستخدم الحالي بواسطة قيم X و Y المحسوبة على زمن. بمعنى آخر، يُحسب المسار المحدد بالنسبة إلى الموضع الحالي للعنصر، باستخدام بيانات المسار لتحويل العنصر إلى موضع المسار. بالعودة إلى دائرتنا، سنقوم بتحريكها على طريق يشبه ما يلي: بإمكانك تطبيق تلك الحركة على الدائرة باستخدام الشيفرة التالي: <animateMotion xlink:href="#circle" dur="1s" begin="click" fill="freeze" path="M0,0c3.2-3.4,18.4-0.6,23.4-0.6c5.7,0.1,10.8,0.9,16.3,2.3 c13.5,3.5,26.1,9.6,38.5,16.2c12.3,6.5,21.3,16.8,31.9,25.4c10.8,8.7,21,18.3,31.7,26.9c9.3,7.4,20.9,11.5,31.4,16.7 c13.7,6.8,26.8,9.7,41.8,9c21.4-1,40.8-3.7,61.3-10.4c10.9-3.5,18.9-11.3,28.5-17.8c5.4-3.7,10.4-6.7,14.8-11.5 c1.9-2.1,3.7-5.5,6.5-6.5" /> هناك أمر واحد ركزنا عليه هنا: الإحداثيات في بيانات المسار. يبدأ المسار عن طريق تحريك (M) إلى النقطة مع الإحداثيات (0، 0)، قبل أن يبدأ في رسم منحنى (c) إلى نقطة أخرى. من المهم أن نلاحظ أن النقطة (0، 0) هي في الواقع موضع الدائرة، بغض النظر عن مكانها - ليست الزاوية العليا اليسرى من نظام الإحداثيات. كما ذكرنا أعلاه، فإن الإحداثيات في خاصية path تتعلق بالموضع الحالي للعنصر! نتيجة الشيفرة أعلاه هي: إذا كنت ترغب في تحديد المسار الذي يبدأ من نقطة أخرى غير (0، 0)، ستقفز الدائرة فجأة بالمقدار المحدد في نقطة البداية. على سبيل المثال، افترض أنك رسمت مسارًا في Illustrator ثم قمت بتصدير بيانات المسار لاستخدامها كمسار حركة (هذا ما فعلته في المرة الأولى التي قمت فيها بهذا)؛ قد يبدو المسار المُصدّر كالتالي: <path fill="none" stroke="#000000" stroke-miterlimit="10" d="M100.4,102.2c3.2-3.4,18.4-0.6,23.4-0.6c5.7,0.1,10.8,0.9,16.3,2.3 c13.5,3.5,26.1,9.6,38.5,16.2c12.3,6.5,21.3,16.8,31.9,25.4c10.8,8.7,21,18.3,31.7,26.9c9.3,7.4,20.9,11.5,31.4,16.7 c13.7,6.8,26.8,9.7,41.8,9c21.4-1,40.8-3.7,61.3-10.4c10.9-3.5,18.9-11.3,28.5-17.8c5.4-3.7,10.4-6.7,14.8-11.5 c1.9-2.1,3.7-5.5,6.5-6.5"/> نقطة بداية المسار في هذه الحالة هي (100.4، 102.2). إذا أردنا استخدام هذه البيانات كمسار للحركة، ستقفز الدائرة بمقدار 100 وحدة تقريبًا إلى اليمين و102 وحدة تقريبًا لأسفل، ثم تبدأ الحركة على طول المسار بالنسبة للموضع الجديد. لذلك، تأكد من وضع ذلك في الاعتبار عند إعداد مسار الحركة للحركة الخاصة بك. في حالة استخدامها، تحدد الخاصيات from وby وto وvalues شكلًا على مساحة العمل الحالية التي تمثل مسار الحركة. تحديد مسار الحركة باستخدام عنصر <mpath> هناك أيضًا طريقة أخرى يمكنك من خلالها تحديد مسار الحركة. بدلًا من استخدام خاصية HTML المسار النسبي path، يمكنك الرجوع إلى مسار خارجي باستخدام عنصر <mpath> التابع لعنصر <animateMotion>، والذي يشير إلى المسار الخارجي باستخدام الخاصية xlink: href. <animateMotion xlink:href="#circle" dur="1s" begin="click" fill="freeze"> <mpath xlink:href="#motionPath" /> </animateMotion> يمكن تحديد مسار الحركة <path> في أي مكان في المستند؛ يمكن تعريفه حرفيًا فقط داخل عنصر <defs> ولا يُعرض على سطح العمل على الإطلاق. في المثال التالي، المسار ظاهر وواضح لأنه في معظم الحالات قد ترغب في إظهار المسار الذي يتحرك فيه العنصر. لاحظ أنه، وفقا للمواصفات: مرة أخرى، "يتضاعف" موضع الدائرة أو "يتحول" بواسطة الإحداثيات في بيانات المسار. في المثال التالي، لدينا مسار في منتصف اللوحة. تُوضع الدائرة في بداية المسار. ومع ذلك، عند تطبيق مسار الحركة، لا تبدأ الدائرة حركتها من موضعها الحالي. تفقد العرض الحي للحصول على شرح أفضل. انقر على الدائرة لتحريكها. انظر كيف تتبع الدائرة نفس شكل المسار، ولكن على موضع مختلف؟ هذا يرجع إلى حقيقة أن موضع الدائرة يُحول بواسطة قيم بيانات المسار. تتمثل إحدى طرق الالتفاف حول ذلك في البدء بوضع الدائرة في (0، 0)، بحيث عند استخدام بيانات المسار لتحويلها، ستبدأ وتستمر كما هو متوقع. هناك طريقة أخرى تتمثل في تطبيق تحويل "يعيد تعيين" إحداثيات الدائرة بحيث تُحسب على الصفر قبل تطبيق المسار. فيما يلي نسخة معدلة من العرض الحي أعلاه، وذلك باستخدام مسار مغلق وتكرار الحركة بشكل غير نهائي. تجاوز القواعد لـ <animateMotion> نظرًا لوجود أكثر من طريقة واحدة لفعل نفس الشيء مع animateMotion، فمن المنطقي أن يكون هناك قواعد تجاوز لتحديد القيم التي تتجاوز القيم الأخرى. قواعد التجاوز لـ animateMotion كالتالي: فيما يتعلق بتعريف مسار الحركة، يتجاوز عنصر mpath خاصية path، التي تتجاوز values، والتي بدورها تتجاوز from وby وto. فيما يتعلق بتحديد النقاط التي تتوافق مع خاصيات keyTimes، فإن مسارkeyPoints يتخطى path، والذي يتجاوز values، والذي بدوره يتخطى from وby وto. تحديد اتجاه عنصر على طول مسار الحركة باستخدام rotate في المثال السابق، حدث أن العنصر الذي كنا نتحرك فيه على طول المسار هو دائرة. ولكن ماذا لو كنا نحرك عنصرًا له اتجاه معين، على سبيل المثال، رمز سيارة؟ رمز السيارة في المثال التالي من إعداد Freepik. في هذا المثال، استبدلت الدائرة بمعرف "السيارة"، الذي يحتوي على العنصر الذي يُكون المجموعة. بعد ذلك، من أجل تجنب مشكلة الحركة على طول المسار المذكور أعلاه، ثم تطبيق تحويل على السيارة بحيث يترجمها بمقدار معين، بحيث ينتهي الموضع الأولي عند (0، 0). القيم الموجودة داخل التحويلات هي في الواقع إحداثيات النقطة التي يبدأ فيها رسم المسار الأول للسيارة (مباشرة بعد أمر النقل M). ثم تبدأ السيارة تتحرك على طول مسار الحركة. لكن… هكذا تبدو الحركة: اتجاه السيارة ثابت، ولا يتغير لمطابقة مسار الحركة. لتغيير ذلك، سنستخدم خاصية rotate. تأخذ خاصية rotate إحدى القيم الثلاث: auto: تشير إلى أن الكائن يدور بمرور الوقت بزاوية الاتجاه (أي متجه الظل الاتجاهي) لمسار الحركة. auto-reverse: تشير إلى أن الكائن يدور بمرور الوقت بزاوية الاتجاه (أي متجه الظل الاتجاهي) لمسار الحركة بإضافة 180 درجة. رقم: يشير إلى أن العنصر الهدف يحتوي على تحويل دوران ثابت مطبق عليه، حيث تكون زاوية الدوران هي العدد المحدد من الدرجات. لإصلاح اتجاه السيارة في المثال أعلاه، سنبدأ بتعيين قيمة الدوران على auto. سننتهي بالنتيجة التالية: أما في حال أردت تدوير السيارة خارج المسار، قيمة auto-revesre ستتكفل بذلك. يبدو هذا أفضل، لكن لا تزال لدينا مشكلة واحدة وهي أن السيارة تبدو وكأنها تتحرك للخلف على طول المسار! لتغيير ذلك، نحتاج إلى قلب السيارة على طول محورها y. يمكن القيام بذلك عن طريق تحجيمه بعامل "-1" على طول هذا المحور. لذلك، إذا طبقنا التحويل على g باستخدام معرف السيارة car، فستتحرك السيارة للأمام كما هو متوقع. سيرتبط التحجيم مع الترجمة السابقة التي طبقناها سابقًا. <g id="car" transform="scale (-1, 1) translate(-234.4, -182.8)"> وبالتالي، ستكون النتيجة كما هي موضحة في العرض: التحكم في مسافة الحركة على طول مسار الحركة باستخدام keyPoints توفر خاصية keyPoints القدرة على تحديد التقدم على طول مسار الحركة لكل من قيم keyTimes المحددة. إذا حددت ذلك، فإن keyPoints تؤدي إلى تطبيق keyTimes على القيم الموجودة في keyPoints بدلاً من النقاط المحددة في خاصية values أو النقاط الموجودة في خاصية path. تأخذ keyPoints قائمة مفصولة بفواصل منقوطة لقيم الفاصلة العائمة بين 0 و 1 وتشير إلى مدى طول مسار الحركة التي يجب أن يتحرك فيها الكائن في الوقت المحدد بواسطة قيمة keyTimes المقابلة. تُحدد الحسابات عن بعد من خلال خوارزميات المتصفح. تقابل كل قيمة تقدم في القائمة قيمة في قائمة خاصية keyTimes. عند تحديد قائمة نقاط KeyPoints، يجب أن يكون هناك بالضبط العديد من القيم في قائمة keyPoints كما هو الحال في قائمة keyTimes. أحد الأشياء المهمة التي يجب ملاحظتها هنا هو ضبط قيمة calcMode على linear لكي تعمل KeyPoints. يبدو أيضًا أنه يجب أن يعمل بشكل منطقي مع الحركة، إذا كانت النقاط الرئيسية تتحرك ذهابًا وإيابًا، لكنها لا تعمل. فيما يلي مثال من إعداد Amelia Bellamy-Royds (تفقد صفحتها الشخصية) توضح فيه استخدام keyPoints لتقليد السلوك فتبدأ الحركة على مسار من إزاحة محددة مسبقًا، لأننا لا نملك هذه القدرة حاليًا بشكل افتراضي في SMIL. تحريك النص على طول مسار افتراضي يختلف نقل النص عبر مسار افتراضي عن نقل عناصر SVG الأخرى عبر المسارات. لتحريك النص، سيتعين عليك استخدام عنصر <animation>، وليس عنصر <animateMotion>. أولاً، لنبدأ بوضع النص على طول المسار. يمكن القيام بذلك عن طريق تداخل عنصر<textPath> داخل عنصر <text>. سيتحدد النص الذي سيوضع على طول مسار داخل عنصر<textPath>، وليس كتابع لعنصر<text>. ستقوم textPath بعد ذلك بالإشارة إلى المسار الفعلي المراد استخدامه، تمامًا كما فعلنا في الأمثلة السابقة. يمكن أيضًا تقديم المسار المشار إليه على مسطح العمل أو تعريفه داخل <defs>. تحقق من الشيفرة في العرض الحي التالي: لتحريك النص على طول هذا المسار، سنستخدم العنصر <animate> لتحريك خاصية startOffset. تمثل startOffset إزاحة النص على المسار. 0٪ هي بداية المسار؛ 100 ٪ تمثل نهايته. لذلك، على سبيل المثال، إذا ضبطت الإزاحة على 50٪، فسيبدأ النص في منتصف المسار. ومن هنا ستتضح الأمور للذهاب قدمًا. عن طريق تنشيط startOffset، سنقوم بإنشاء تأثير نقل النص على طول المسار. تحقق من الشيفرة في العرض الحي التالي. تحولات الحركة: عنصر <animateTransform> ينقل عنصر <animateTransform> خاصية HTML تحويل على عنصر مستهدف، مما يسمح للحركة بالتحكم في التحوير والتحجيم و/أو التدوير و/أو الربط. يستغرق نفس الخصائص المذكورة للعنصر <animation>، بالإضافة إلى خاصية HTML إضافية: type. تستخدم خاصية type لتحديد نوع التحويل الذي تُطبق الحركة عليه. وتأخذ أحد القيم الخمسة: translate وscale وrotate وskewX وskewY. تأخذ الخاصيات from وby وto قيم يعبّرعنها باستخدام تركيب الجملة نفسه المتاح لنوع التحويل المحدد: بالنسبة لـ"type="translate، يُعبر عن كل قيمة فردية كـ [<tx> [,<ty> بالنسبة لـ "type="scale، يُعبر عن كل قيمة فردية كـ [<sx> [,<sy> بالنسبة لـ "type="rotate، يُعبر عن كل قيمة فردية كـ[<rotate-angle> [<cx> <cy> بالنسبة لـ "type="skewX و"type="skewY، يُعبر عن كل قيمة فردية كـ <skew-angle> إذا لم تكن معتادًا على بناء جملة SVG لخاصية transform، ومن أجل إيجاز هذه المقالة، ولأن تفاصيل بناء الجملة وكيفية التعامل معها خارج نطاقها، بإمكانك قراءة مقال فهم أنظمة تنسيق SVG والتحولات (الجزء 2): خاصية HTML التحويل، قبل الانتقال إلى هذا الدليل. بالعودة إلى العرض الحي السابق، حيث قمنا بتدوير المستطيل الوردي باستخدام عنصر <animateTransform>. تبدو شيفرة الدوران كما يلي: <rect id="deepPink-rectangle" width="50" height="50" x="50" y="50" fill="deepPink" /> <animateTransform xlink:href="#deepPink-rectangle" attributeName="transform" attributeType="XML" type="rotate" from="0 75 75" to="360 75 75" dur="2s" begin="0s" repeatCount="indefinite" fill="freeze" /> تحدد خاصيات from وto زاوية الدوران (البداية والنهاية) ومركز الدوران. في كليهما، يبقى مركز الدوران كما هو بالطبع. إذا لم تُحدد المركز، فسيكون ذلك هو الركن العلوي الأيسر من سطح العمل SVG. العرض الحي للرمز أعلاه هو ما يلي: هنا مثال آخر ممتع لـ animateTransform من إعداد Gabriel: إن تنشيط عملية تحويل واحدة أمر بسيط، ومع ذلك، يمكن أن تصبح الأمور فوضوية ومعقدة حقًا عند تضمين تحويلات متعددة، خاصة لأن أحد تحويلات الحركة animateTransform يمكنه تجاوز الآخر، لذلك بدلاً من إضافة التأثيرات وتسلسلها، قد ينتهي بك الأمر على العكس تمامًا. هذا بالإضافة إلى طريقة تنسيق SVG للأنظمة والتحولات في الواقع (راجع المقالة المذكورة سابقًا حول الموضوع). الأمثلة واسعة، وخارج نطاق هذه المقالة. لتحويل SVGs، يوصى باستخدام تحويلات CSS. تعمل التطبيقات على جعل هذا الأخير يعمل بشكل مثالي مع SVG، لذلك قد لا تضطر أبدًا إلى استخدام SMIL لتنشيط التحويلات في SVG على الإطلاق. عنصر <set> يوفر عنصر set وسيلة بسيطة لتعيين قيمة الخاصية HTML لمدة محددة. يدعم جميع أنواع الخاصيات، بما في ذلك الأنواع التي لا يمكن تحريفها بشكل معقول، مثل قيم السلسلة والقيمة المنطقية. عنصر set غير مضاف ولا يُسمح بالخاصيات المضافة والإجمالية، وسيتم تجاهلها عند تحديدها. نظرًا لاستخدام <set> لتعيين عنصر إلى قيمة محددة في وقت معين، فإنه لا يقبل جميع الخاصيات المذكورة لعناصر التحريك السابقة. على سبيل المثال، لا يحتوي على خاصية from أو by، لأن القيمة التي تتغير لا تتغير تدريجيًا خلال الفترة الزمنية. بالنسبة لـ set، يمكنك تحديد العنصر الذي تستهدفه، واسم الخاصية HTML ونوعها، وقيمة to، ويمكن التحكم في توقيت الحركة: begin وdur وend وmin وmax وrestart وrepeatCount وrepeatDur وfill. فيما يلي مثال يضبط لون المستطيل الدوّار إلى اللون الأزرق عند النقر فوقه. يظل اللون أزرق لمدة 3 ثوانٍ، ثم يعود إلى اللون الأصلي. في كل مرة ينفر فوق المستطيل، تعمل حركة set، ويتغير اللون لمدة ثلاث ثوانٍ. العناصر وخاصيات HTML وخاصيات الكائنات التي يمكن تحريكها لا يمكن تحريك كل خاصيات SVG، ولا يمكن تحريك كل الخاصيات التي يمكن تحريكها باستخدام جميع عناصر التحريك. للحصول على قائمة كاملة بجميع الخاصيات المتحركة، وجدول يربط الخاصيات بالعناصر التي تحركها، يرجى الرجوع إلى هذا القسم من مواصفات SVG Animation. أخيرًا لدى SMIL الكثير من الإمكانيات، وبالكاد تعرض المقال لمعلومات سطحية جدًا ولم يتطرق إلا إلى الأساسيات والتقنيات الخاصة بكيفية عملها فيSVG. يمكن إنشاء الكثير من التأثيرات المؤثرة للغاية، خاصة تلك التي تنطوي على تحوير الأشكال وتحويلها. لتكن حدودك هي السماء؛ عليك أن تكمل أنت الآن فامض بشغف! ولا تنس مشاركة ما تصنعه مع الآخرين. شكرًا لقراءتك! ترجمة وبتصرف للمقال A Guide to SVG Animations (SMIL)‎ لصاحبته Sara Soueidan
  4. لنستخدم CSS لرسم شخصية بيماكس (Baymax) من فيلم Big Hero 6. سنحرّك في هذا المنشور صورة خلفية، بالإضافة إلى تأثير حركة بتوقيت دقيق، ونقوم بإجراء عرض تجريبي CSS من عنصر HTML واحد. تجربة حية. عنصر واحد سنكون قادرين باستخدام العنصر الزائف على إنشاء أجزاء الوجه بعنصر HTML واحد. <div class="baymax"></div> التصميم لضبط المرحلة سنضيف تدرّجًا دقيقًا للشاشة لجعلها تبدو كرأس أبيض منحنٍ. سنستخدم لهذا تدرجًا شعاعيًا على عنصر body. body { background: radial-gradient(circle at center, #fff, #fff 50%, #aaa); background-size: 100% 100%; background-repeat: no-repeat; height: 100vh; } بعد ذلك نضع الوجه في مركز الصفحة. الفم خط أسود بسيط، وسنقوم بذلك باستخدام الخاصية border. .baymax { border-bottom: 1.5em solid #000; position: absolute; top: 50%; left: 50%; width: 50%; transform: translate(-50%, -40%); } تقوم الخاصية الأولى بتعيين إطار سفلي أسود بعرض 1.5em. ثمَّ يتموضع الخط باستخدام الموضع المطلق، فيندفع إلى الأسفل 50% ويتحرك من اليسار 50%. قيم الـ 50% هي بالنسبة إلى حجم العنصر الحاوي (body). المشكلة التي نواجهها الآن هي أنَّ العنصر يبدأ من منتصف طول وعرض الشاشة. إنَّه خارج المركز. لموازنة ذلك، نستخدم تحويلًا لسحب العنصر 50% يسارًا من عرضه، وإلى الأعلى 40% من عرضه. عند هذه المرحلة يصبح الفم في المركز على هذا النحو: إضافة العينين سنستخدم العناصر الزائفة before وafter لإضافة العينين إلى الوجه. لن يحتاج هذا إلى أي عنصر HTML إضافي وتتم معالجته بالكامل باستخدام CSS. .baymax::before { background: #000; border-radius: 50%; content: ""; position: absolute; width: 12em; height: 12em; left: -9em; top: -6em; transform: skewX(-4deg); } .baymax::after { background: #000; border-radius: 50%; content: ""; position: absolute; width: 12em; height: 12em; right: -9em; top: -6em; transform: skewX(4deg); } كل من هذه العناصر الزائفة لها خلفية سوداء، وحواف دائرية -border-radius: 50%; لجعلها دائرية. كلّ منها متموضع في نهاية الفم، وأخيرًا لها تحوّل skew لجعلها تبدو كأنَّها مائلة قليلًا للخلف. ستظهر النتيجة كما يلي: البطارية منخفضة هناك مشهدٌ مضحك في الفيلم حيث تنخفض بطارية بيماكس. فيترنَّح وتتدلَّى جفونه. يمكننا استخدام مزيج من الحركات والتدرّجات في الخلفية لإحداث التأثير. نريد أولًا أن نعطي الخلفية لونين. أسود لجزء العين المفتوح، وأبيض للجفن. يحتاج الجزء الأبيض أن يتموضع خارج العينين في البداية، ثمَّ سنحركه لجعل الجفون تتدلَّى. .baymax::before { background: linear-gradient(to bottom, #efefef, #efefef 50%, #000 50%, #000); background-position: 0 -100%; background-size: 200% 200%; ... } .baymax::after { background: linear-gradient(to bottom, #efefef, #efefef 50%, #000 50%, #000); background-position: 0 -100%; background-size: 200% 200%; ... } نحن الآن نضيف تدرّجًا خطيًّا في الخلفية، فنجعله ضعف ارتفاع الحاوية، ثم نحدد موضعه لذا يصبح النصف العلوي خارج الحاوية. مع وجود تدرّجات للخلفية في مكانين، يمكننا أن نضيف حركة keyframes للتحكم في حركة الجفون. @keyframes blink { 0%, 50% { background-position: 0 100%; } 85%, 95% { background-position: 0 75%; } 100% { background-position: 0 100%; } } قاعدة keyframes في الحركات هي طريقة لوصف سلسلة من الإطارات، باستخدام النسبة المئوية. تعود النسبة المئوية لمدى استمرار الحركة، لذا فإنَّ النسبة المئوية 50% منتصف الطريق عبر الحركة. بهذه الطريقة يمكننا ضبط الخلفية للبقاء مستيقظين حتى منتصف الحركة، ثمَّ بين الإطار 50% والإطار85%، تتحرك للأسفل، وثمَّ تستقر في نهاية الحركة. الخطوة التالية هي إخبار العناصر الزائفة أن تستخدم إطارات الحركة هذه. أضف خاصية animation للأنماط الحالية. .baymax::before { animation: blink 6s infinite; ... } .baymax::after { animation: blink 6s 0.1s infinite; ... } أخبرنا المتصفح هنا أن يستخدم حركة blink على كل عنصر. وضبطنا مدة الحركة إلى 6 ثواني وستستمر بشكلٍ لا نهائي. خاصية واحدة إضافية في المثال الثاني: تخبر المدة 0.1s بعد 6s المتصفح أن تتأخر الحركة لـ0.1 ثانية. يخلق هذا تأثير إغلاق العين الثانية بتأخيرٍ عن الأولى. وذلك يضيف التأثير المتدلي والمتعب ويجعلها تبدو أكثر واقعيةً. يجب أن تظهر النتيجة النهائية كما في الصورة: يمكنك مشاهدة تجربة حية. المتصفحات حذفت في أمثلة الشفرة أيّ بادئات معتادة webkit- وmoz-. لكن خاصيّات transform وanimation يجب أن تكون مسبوقة، وأنصحك باستخدام شيء ما مثل Autoprefixer لهذا. نسخة gif قابلة للمشاركة إليك نسخة gif متحركة يمكنك مشاركتها على الإنترنت بسهولة: ترجمة -وبتصرف- للمقال Baymax in CSS
  5. نعرض في هذا المقال أمثلةً لحركات مستعملة في تطبيق جوال وطرقًا لكيفية تحسين تصميم التطبيق. هذه تجميعة رائعة من 20 مثال لكيفية استخدام العناصر المختلفة لجعل تطبيقك أكثر تفاعلًا وسهولةً في الاستخدام. أَلْهِم نفسك بهذه الأمثلة لحركات تطبيق الجوال! هذه التصاميم الإبداعية لحركات تطبيقات الجوال ستساعدك على إنشاء تطبيقات مذهلة بخصائص تفاعلية حيوية يحبها الجميع. يمكنك استخدامها لتحسين سلاسة الاستخدام والمحافظة على مشاركة مستخدمي تطبيقك. اطَّلع على هذه الأمثلة الممتازة لحركات تطبيق الجوال التي ستحفزك. ستتعلم كيفية إضافة أزرار شريط التنقل المتحركة، والقوائم الهلامية، وتحديث الحركات، وتأثيرات اختلاف المنظر (parallax)، ومعارض الصورغير المنتهية، والترويسات المضبَّبة (blurred headers) وتذييل الصفحات المتحرك وغيرها الكثير. شريط التنقل المتحرك هذا زر قائمة متحركة رائع يساعدك في التنقل عبر التطبيق بطريقةٍ مُبتَكرة. فكرة القائمة الهلاميَّة اللمسيَّة هذه حركات بهيجة لتطبيق الجوال؛ سيجعل التمرير أكثر متعةً بالتأكيد. هي فكرة هلامية رائعة وستعجب مستخدمي تطبيقك. فكرة حركات بتسجيل الدخول والخروج هذه تحريكات تطبيقات جوال مهمة تشمل ميزات تسجيل الدخول والخروج، جاء مصممها بفكرةٍ جميلةٍ تبدو مذهلة. تحديث البريد الوارد هذا أحد أصول تطبيق الجوال المحببة الذي يكون في متناول يديك عند قراءة بريدك الإلكتروني، هي حركات رائعة تسمح لك بتحديث البريد الوارد بسرعة من خلال تمرير إصبعك لأسفل بكل بساطة. فيديو واجهة المستخدم هذه حركات رائعة أيضًا لتطبيقات الجوال يمكنك إدراجها بسرعة في تطبيقك. استخدم فيديو واجهة المستخدم هذا للمحافظة على مشاركة مستخدمي تطبيقك. التصميم الخفيّ هذه حركات رائعة ستوسع وظائف تطبيقك دون أن تأخذ مساحة كبيرة من واجهة المستخدم، يمكنك رؤية الميزات المخفية كلما احتجت إلى ذلك. حركات بطاقات التوصيل هذه الحركات الملونة تتيح لك طريقة بهيجة وممتعة لاستخدام تطبيقك، الحركة تحدث بالإختيار وتتوقف على العنصر الذي كنت تبحث عنه. تأثير اختلاف المنظر تأثير تغيير منظر التطبيق (Farmer Parallax) هي لمحة ثلاثية الأبعاد 3D رائعة، تبدو مذهلة لأي مشروع تملكه، هذا مثال جميل لكيفية استخدام تأثير اختلاف منظر التطبيق framer parallax في تطبيقك. حركات تراكيب التصميم المادي هذه حركات بسيطة لكنها فعالة، يمكن إضافته لتطبيقك. تعرف ما إذا كانت فعَّالة لتصاميمك! فكرة السحب المرن للتحديث هذه فكرة سحب جميلة أخرى يمكنك استخدامها للمحافظة على معلوماتك محدثةً. حركة معرض الصور غير المنتهي هذه الحركة التلقائية تنشئ معرض صور غير منتهي يمكنك التمرير عبره حتى تجد الصورة التي تريدها بالتحديد. قائمة واجهة التطبيق قائمة واجهة مستخدم التطبيق هذه تبدو رائعة، توضح طريقة مؤثرة حول كيفية تقديم قائمتك الكاملة دون أن تأخذ مساحة كبيرة. تصميم مادي SVG مرن للأشرطة الجانبية هذه حركة رائعة يمكنك إضافتها بسرعة لتصميم تطبيقك. هي ميزة بهيجة وممتعة للاستخدام. قائمة الشريط الجانبي الثلاثي (Webkit فقط) يتميز تصميم القائمة المتحركة هذا بترتيب فريد يبدو مذهلًا لأي تطبيق. راجع العرض التوضيحي لتعرف ما إذا كان يمكنك استخدامها في مشاريعك المستقبلية. مفكرة ملونة باستخدام css فقط هذا تصميم جميل لمفكرة أنشئ باستخدام css. هو ترتيب ملون يستخدم ألوان جذابة ما يجعل تجربة المستخدم أكثر متعةً. تجربة مستخدم مع حركات لتطبيق بريد إلكتروني إليك حركات رائعة يمكنك استخدامها لتحسين واجهة المستخدم لتطبيق البريد الإلكتروني الخاص بك. اطلع عليها وانظر ما إن كانت تناسب نمط تصميمك. سحب القائمة - مفهوم القائمة التفاعلية هذا تصميم مذهل لمفهوم القائمة المتحركة الذي يستخدم فكرة فريدة؛ يمكنك الكشف عن المحتوى الكامل للقائمة عن طريق السحب لأسفل. الترويسات الضبابية iOS 7 هذه حركة رائعة يمكنك استخدامها لإضافة تأثير ضبابي لترويسات (headers) تطبيق iOS الخاص بك. قائمة تذييل تطبيق الجوال المتحركة هذا تصميم رائع آخر لتذييل التطبيق، سوف يعجب مستخدمي تطبيقك وبالتأكيد يحافظ على مشاركتهم. التصميم الدَّوامِي للتطبيق هذا تخطيط دوَّامي بسيط لكنَّه مؤثر جدًا يمكنك استخدامه في العديد من تطبيقات الجوال. اطلع عليه وانظر ما إذا كان يناسب نمط تصميمك. ترجمة -وبتصرف- للمقال Mobile App Animation | 20 Excellent Examples من موقع line25
  6. كلمة حركات مستمدة من الفعل «حرَّك» والتحرُّك سمةٌ تعطينا الإحساس بالحيوية وتجعل أحداث الطبيعة تبدو أكثر واقعيةً بالنسبة لنا، فالحركات تجذب انتباه الناظر وتجعلة يشعر بإثارة الموقف وتبرز المشاهد الأكثر أهميةً وإقناعًا من غيرها. أمَّا العناصر الساكنة التي تجلس بلا حراك، فتشعرك أنَّها ميتة، حتى وإن كان تصميمها جذابًا. يعدُّ التحريك فنًا مثله كَمَثل أي فنٍّ سواءً كان الشعر أو الرسم أو غيرهما من الفنون، وصارفي هذه الأيام علمًا يُدرّس وعملًا يُنجَز، حتى أنه أصبح متأصلًا في روح تصميم الويب ويبدو أنه إضافة رائعة إلى العديد من عناصر موقع الويب. هل تجلب الحركات المزيد من الحياة للتصميم أم أنها قد تفسده أحيانًا؟ دعنا نتعرف على الفوائد التي يمكن أن تقدمها الحركات لموقع الويب وما هي الحالات التي يكون من الأفضل تجنبها. كيف ظهرت الحركات في تصميم المواقع ظهرت الحركات في الويب منذ وقت طويل. أولاً، كانت هناك ملفات ‎.gif صغيرة الحجم بها صور متحركة ومقاطع فيديو متنوعة. كانت تلك العصور المظلمة مع الكثير من بطاقات Flash وأشياء نفضل أن لا نراها. في تلك الأيام، لم يكن أحدًا يعتبر الحركات وسيلة لتحسين قابلية استخدام موقع الويب. كانت تستخدم في الغالب للتزين أو للمتعة فقط. اليوم، يمكنك استخدام تأثيرات الحركة لتحسين التنقل والاستخدام لموقعك. منذ وقت ليس ببعيد، أُنشئت جميع العناصر والتأثيرات المتحركة على مواقع الويب بمساعدة تقنية Flash. بالطبع، لقد كانت تقنية ثورية في ذلك الوقت على الرغم من أنها كانت ثقيلة جدًا وزادت من وقت تحميل الموقع بشكل كبير. في هذه الأيام، تُصمّمم الحركات باستخدام شيفرات JavaScript و CSS الخفيفة التي تساعد على إضافة عناصر متحركة إلى الموقع دون زيادة تحميله. والأهم من ذلك، تُستخدم الحركات هذه الأيام لتحسين UX، وليس فقط للمتعة. إنها وسيلة رائعة لمصممي الويب التي تساعد في جعل موقع الويب أفضل وأسهل في الاستخدام. كما في الحالات التالية: تحسين قابلية الاستخدام بالحركات في كثير من الحالات، تُستخدم تأثيرات الحركة لجذب انتباه المستخدم لتفاصيل مهمة تساعده لاتخاذ القرار الصحيح بشأن إمكانية النقر فوق عنصر من بين أشياء أخرى. وبالتالي، تستخدم العديد من مواقع الويب تأثيرًا هزَّازًا في نماذج تسجيل الدخول لتبين للمستخدمين أن هناك خطأ ما وأن المعلومات قد أُدخلت بشكل غير صحيح، مثل كلمة السر الخاطئة. هذا الأسلوب يحاكي هزِّة رأس إنسان يقول "لا". هناك العديد من الطرق الأخرى لاستخدام الحركات لتحسين تجربة المستخدم UX. يمكن استخدامها في أشرطة التنقل لفصل الفئات الرئيسية عن الفئات الفرعية؛ أو ضمن خيارات متعددة، عندما تتلاشى جميع العناصر باستثناء العنصر المختار. موقع Etechevent مع عناصر متحركة يمكن استخدام الحركات لتوجيه المستخدمين حول الموقع وحتى جعلهم يشترون. إن إضافة عناصر تفاعلية وجذب انتباه المستخدمين إليها بمساعدة تأثيرات الحركة يمكن أن يساعد مواقع الويب التجارية على تحسين العقارات وعائد الاستثمار. ويمكن أن تستفيد مواقع رواية القصص أيضًا من تضمين الحركات. حيث يمكنها أن تبين للمستخدمين ما الخطوة التالية التي يجب أن تكون أو كيفية اختيار مكان الانتقال في موقع الويب. استخدام الحركات في التصميم الماديّ (Material Design) أثبتت فكرة الحركات في تصميم الويب أنها مفيدة للغاية إذا لم تستخدم بطريقة تزيينية فقط. غالبًا ما يستخدمها مصممو UI و UX لتحسين سير العمل لديهم. حتى Google تدرك أهمية الحركة لسهولة الاستخدام، وهكذا ظهر التصميم الماديّ. أصبح التصميم المادي أكثر وأكثر عصرية ويُستخدم هذه الأيام في العديد من التطبيقات وتَصاميم المواقع. سر شعبيته هو اهتمامه الكبير بكيفية إدراك الكائن أو العنصر؛ كيف يمكن للحركة أن تخبر المستخدمين أكثر عن هذا العنصر وكيفية استخدامه. تنص Google في دليلها للتصميم المادي على أن الحركة يمكن أن تخبر المستخدمين أن أي كائن هو خفيف أو ثقيل أو مرن أو كبير أو صغير. يجب استخدام الحركات لتزويد المستخدمين بِفهم أفضل لطبيعة الكائن، وبالتالي، كيف يمكن وينبغي أن تستخدم داخل التصميم. تتقدم Google إلى أبعد من ذلك مع الحركات وتوصي باستخدام العناصر المتحركة التي تغير سرعتها ومدتها اعتمادًا على الهدف أو التأثير الذي ترغب في الحصول عليه. وبالتالي، تقدم Google العناصر الواردة والصادرة التي تظهر على الشاشة عندما ينبغي جذب الانتباه، أو إزالته من الشاشة عندما لم تعد هناك حاجة إليه. نصائح لاستخدام الحركات في المواقع عند إضافة الحركات إلى موقعك، يجب أن تفكر جيدًا في جميع مخاطرها أيضًا. العناصر المتحركة يمكن أن تضر بأداء موقع الويب وتجربة المستخدم UX. أولًا، يجب إعادة التفكير في استخدام الحركات إن كانت تبطئ من سرعة تحميل موقعك وأداءه العام. يمكن الكشف عن ذلك بمقارنة بسيطة لموقعك بحركاته مع أداء ألعاب الحاسوب الثقيلة. إذا كانت اللعبة تعمل بسلاسة على سطح المكتب أكثر من موقعك فيجب أن يكون هذا سببًا في إعادة النظر في استخدام الحركات. موقع التوقعات السعيدة استفد من CSS عند إنشاء حركات لموقعك. تعد مكتبة jQuery مثاليةً وتستخدم في العديد من المشاريع، لكنها يمكن أن تبطئ بالفعل من أداء موقعك. تسمح شيفرة CSS بإنشاء حركات خفيفة ستبدو رائعةً على أي جهاز دون إِثْقال التصميم. يجب أن تتأكد أن حركاتك متجاوبةً (responsive). موقع الويب المتجاوب أمر لا بد منه إن كنت ترغب في النجاح. ولكن إذا كان الأداء يبدو رائعًا على شاشة سطح المكتب فقط، فقد تخسر المعركة مع المستخدمين. هناك العديد من الأدوات التي تسمح بإنشاء حركات مُتجاوبة (مثل Adobe After Effects أو Invision) فبُناة مواقع الويب (مثل Webflow أو MotoCMS) تتضمن تأثيرات حركية متجاوبة وتوفر أنواع مختلفة من الحركات التي يمكن استخدامها داخل المواقع لتحسين تصميمها وقابليتها للاستخدام مثل: التلاشي (اليسار ، اليمين ، أعلى ، أسفل) (Fade in). الارتداد(Bounce in). التدوير (يسار ، يمين ، أعلى ، أسفل) (Rotate). الزلق (اليسار ، اليمين ، أعلى ، أسفل) (Slide in). اللمعان والنبض(Flash and Pulse). التذبذب (Wobbling). الاهتزاز (Swinging) وإلى آخره. الحركات يجب أن تلفت الانتباه ولكن ليس كثيرًا. تأكد من أن الحركة لا تستغرق وقتًا طويلاً ولا تدوم طويلًا على الشاشة. هذا هو الحال خاصةً إذا كنا نتحدث عن العناصر التي يجب على المستخدمين التفاعل معها كثيرًا. قد يكون الأمر ممتعًا مرةً أو مرتين، لكن مع الاستخدام المتكرر قد يصبح الأمر معرقلًا للغاية. موقع Laerepenger مع حركات غامضة ابدأ باستخدام العناصر الصغيرة بالحركة على الموقع. في الواقع، الحركات وسيلة للهدف، وليست الهدف نفسه. يجب عليك عدم تضمينها أينما تريد. يجب أن يكون هناك ما يبرر لاستخدامها. من الأفضل تضمين الحركات في عناصر واجهة المستخدم أو العناصر التي يتفاعل معها المستخدمون أكثر، مثل قوائم التنقل أو نماذج الاشتراك. وفكر قبل إضافة حقل قفَّاز وصور منزلقة: كيف ستؤثر على تجربة المستخدم، هل ستحسن التفاعل مع الموقع؟ تعد الحركات رائعةً لصنع تصميم موقع لا ينسَ. فهي لا تزال تستخدم على نطاق واسع في تصميم الموقع على الرغم من النظرات المختلفة حولها مثل سرعة التحميل أو عدم الاستجابة. ولكن الشيء الرئيسي الذي يجب أن تتذكره عند تقديم عناصر متحركة لموقعك هو تأثيرها على قابليتها للاستخدام. الأمر متروك لك - تحديد أين ومقدار دمج الحركة في التصميم الخاص بك. فيما يلي ملخص قصير لمواقع الويب التي تستخدم الحركات لدرجة كبيرة: موقع KiKK تصميم موقع مقهى مثلجات موقع شركة JD للاستشارات موقع VN Star تصميم شركة Soane Capital المالية موقع وكالة Nodeplus الرقمية تصميم موقع Creative Cruise للفنادق تصميم مواقع صناعي مع تحريك تصميم موقع وكالة Pomade الرقمية موقع مجوهرات Puca تصميم موقع Carioca Promo الترويجي موقع Ultranoir مع تحريك إبداعي تصميم موقع Mahno الشخصي تصميم منظر حديقة Vintage المتحرك ترجمة -وبتصرف- للمقال Animation in Web Design: Why and When to Use من موقع line25
  7. يعد WebKit مُحرِّك متصفح ويب (web browser engine) يستخدمه كلٌّ من Safari، و Mail، و App Store، وغيرها من التطبيقات والمتصفحات التي تعمل على macOS، و iOS، ولينكس. ويعرض Webkit صفحات الويب التي تحتوي على تعليمات مكتوبة بِشيفرات Javascript و HTML و XML، ويدير أيضًا تاريخ الصفحات التي تمت زيارتها مؤخرًا. هناك الكثير من الانتقالات المميزة و تأثيرات الحركات المتاحة للاستخدام على محرك webkit من شأنها تنشيط تجربة الويب لمستخدمي متصفح Safari. في ما يلي لمحة بكيفية إحداث إحدى هذه التأثيرات. سيُوضح هذا المقال طريقة إنشاء تأثير انعكاس من خلال الخاصية rotateY، وكيف يمكن استخدامه لإنشاء تقليبات في العديد من الصور، هذا مناسب كأفضل تنسيق لإحداث تأثيرات للأوراق الرابحة. اضغط هنا لعرض التجربة الحية. يُتطلب متصفح Safari لتجريب تأثير انعكاس Webkit المتحرك. يوضح المثال المذكور كيف يمكن استخدام تأثير التقليب لإظهار البيانات في كلا الوجهين من خلال قلب البطاقة. قم بتمرير مؤشر الفأرة فوق بطاقتي Optimus Prime و Megatron الرابِحتين في الأعلى لمشاهدة النتيجة. الآن، دعنا نلقي نظرةً على كيفية صنع حركة التقليب هذه. شيفرة HTML <div id="transformers-rule"> <div class="container megatron"> <div class="card"> <div class="face front"> </div> <div class="face back"> </div> </div> </div> </div> شيفرة HTML بسيطة للغاية، وتتكون بشكل أساسي من مجموعة حاويات تشكل كل بطاقة. <div class="face front"> <img src="megatron.png" alt="Megatron CSS flip effect" /> </div> <div class="face back"> <h2>Megatron</h2> <img src="decepticons.png" alt="Decepticons logo CSS flip effect" /> <p>Megatron is the primary antagonist and leader of the evil Decepticons.</p> <dl> <dt>Skill</dt> <dd>7</dd> <dt>Power</dt> <dd>8</dd> <dt>Agility</dt> <dd>5</dd> <dt>Bravery</dt> <dd>7</dd> <dt>Speed</dt> <dd>4</dd> </dl> </div> يُقسَّم الوجه الأمامي والخلفي للبطاقات إلى حاويتين فرعيتين ويوضع بداخلهما المحتوى المناسب. يوجد في الوجه الأمامي صورة واحدة، في حين يوضع في الوجه الخلفي المواصفات الكاملة لشخصية البطاقة. نستخدم عدة عناصر ِلوصف موجز الشخصية، فعنصر <h2> يستخدم لإضافة عنوان و <p> لإضافة فقرة و <img> لعرض صورة، ثم تُدرج الأهداف المسجلة للشخصية في قائمة تعريف من خلال عنصر <dl>. شِيفرة CSS .megatron { float: left; position: absolute; top: 30px; left: 20px; } .megatron .front { } .megatron .back { width: 284px; height: 372px; padding: 20px; background: #a3a3a3 url(texture.png); } .megatron .back h2 { width: 287px; height: 42px; margin: 0 auto 20px auto; background: url(megatron-title.png); text-indent: -9999px; } .megatron img { float: right; } .megatron p { float: left; width: 185px; margin: 0 0 20px 0; font-size: 17px; line-height: 28px; color: #4c4c4c; } تُعطَى خلفية البطاقة أولاً بُنية رمادية متكررة، ثم نبدأ بتصميم عناصر HTML. يُستبدل العنصر <h2> بصورة بنفس نصه مع بعض تأثيرات Photoshop المضافة. يتم تعيين حجم الخط واللون لعناصر الفقرة ثم نُموضعهم جنبًا إلى جنب مع شعارَي Autobots و Decepticons. .megatron dl { font-size: 30px; font-weight: bold; line-height: 40px; color: #717171; width: 264px; padding: 5px 10px; overflow: hidden; background: #cfcfcf url(gradient.png) repeat-y; -webkit-box-shadow: 0 1px 5px #888; text-shadow: 0 1px 1px #f5f5f5; } .megatron dl dt { float: left; clear: both; } .megatron dl dd { float: right; } لِعرض مواصفات الشخصية جنبًا إلى جنب، يوضع عنوان التعريف لجعل كل شيء يعمل على ما يرام؛ نستخدم مجموعة من حركات webkit مع خصائص التقليب في الشيفرة. ابتداءً من الجزء العلوي، يتم إعطاء الحاويات الخاصية ‎-webkit-perspective مسندةً للقيمة 1000 لإضافة شيئٍ من الواقعية لحركة التقليب، بينما يبدو كل شيء غير ذلك مسطحًا قليلًا. ثم نضيف الخاصيتين ;‎-webkit-transform-style: preserve-3d و ;‎-webkit-transition: 0.5s لحاوية البطاقة؛ حيث يضمن نمط التحويل ثلاثي الأبعاد (preserve-3d) ببساطة أن العناصر الفرعية تتبع الحركة ثلاثية الأبعاد بدلًا من أن تبقى مسطحة، وأن قيمة الانتقال البالغة 0.5 ثانية تحدد سرعة التأثير الكلي. على اليسار ووصف التعريف (dd) يوضع على اليمين. يُعطَى عنصر قائمة التعريف (العنصر ) خلفية متدرجة وتَصميم نص مناسب، يورَّثان لِلعنصرين <dt> و <dd>. الحركة مع webkit .container { width: 324px; height: 412px; -webkit-perspective: 1000; } .card { width: 324px; height: 412px; border: 8px solid #fff; -webkit-transform-style: preserve-3d; -webkit-transition: 0.5s; } .container:hover .card { -webkit-transform: rotateY(180deg); } .face { position: absolute; -webkit-backface-visibility: hidden; } عند تحريك مؤشر الفأرة على البطاقة يضاف تحويل webkit بتدوير (rotateY(180deg قيمته 180deg، والتي تقوم بتدوير الكائن 180 درجة حول المحور Y. الخاصية ‎-webkit-backface-visibility: hidden;‎ هي خاصية أخرى ممتازة لِ webkit، تُستخدم على وجه كل بطاقة. هذا يضمن أن الجانب الآخر من البطاقة لم يعد مرئيًا، وبدون هذا، سينقلب الكائن إلى صورة معكوسة بدلاً من عرض الجانب الآخر. شيفرة HTML الكاملة شِيفرة CSS الكاملة اضغط هنا لعرض التجربة الحية. ترجمة -وبتصرف- للمقال Super Cool CSS Flip Effect with Webkit Animation من موقع line25.
  8. تتغير العناصر البصرية حولنا مع الزمن، ونحس بهذا التغيير كحركة. تكمل عقولنا العناصر المفقودة في مقاطع الفيديو أو اللوحات الفنية باستخدام تصورنا، من أجل إنتاج شعور بالحركة. نستخدمُ الرمز في كثير من الأحيان لنقل فكرة، إذ نحاول تقديم غاية القصة بصريًا لنمنح غيرنا فهمًا أعمق. 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; } فكرة جيدة أن نستخدام نوعًا من التصوُّر لرسم صورة كاملة للقصة التي نحاول سردها، إلا أن استخدام الحركات لتوصيل الرسالة يمكن أن يكون أفضل؛ إذا كانت الصورة تستحق ألف كلمة، فكم ستستحق من الحركات لوصفها؟ الحركات في الويب تؤدي ذلك الغرض؛ فهي تحاول أن تصور القصة، باستخدام رمز أو تخُّيل الحركة، مثل الضغط على زر، وفتح صفحة جديدة. نحاول تصوُّر الخطوات والعمليات لجعلها تبدو طبيعيةً أكثر، لاستدعاء حدث أو لجعل التطبيق يبدو أكثر جاذبيةً. كيف بدأت حركات الويب منذ أيام شبكة الويب القديمة، كان هناك جهودًا لتنفيذ العناصر المتحركة في نوافذ منبثقة لأجزاء مهمة من الموقع؛ ليبدو أكثر ديناميكية وجاذبية، كما في موقع Jeffrey Zeldman لِباتمان 95، إذ كان تحليق باتمان نحو المستخدم عبارة عن حركة مؤلفة من سلسلة من الصور، كانت GIF واحدة من الرسوم المتحركة الأولى على صفحة الويب وفي ذلك الموقع الذي كان واحدًا من أكثر الصفحات شيوعًا في ذلك الوقت، ما أَلْهم مطوري الويب للجمع بين الرسوم المتحركة GIF كعنصر مُراوغة في مواقعهم. الصور التي من النوع GIF مناسبة لتكرار قصير لحركة تمتد على نطاق ضيق من البكسلات، أو حتى بعض الفيديوهات. لكن ليس لديها شفافية متغيرة، ولا تدعم قناة الشفافية (alpha) في لوحة ألوانها، وجميع البكسلات فيها إما غير شفافة أو شفافة تمامًا. حركات GIF كانت البداية في نهضة تصميم الويب لكنها لم تكن مثالية. صور GIF ثقيلة نسبيًا؛ فالنتيجة عادة ما تكون دقة منخفضة، وتسلسل غير متساوي في توزيع الضوء و لوحة ألوان ذات 8 بت محدودة، ما أدى إلى القليل من التردد للمصممين بخصوص عدد الألوان اللازم استخدامها في المشهد. حدث ازدهار كبير في الحركات مع رسوم Flash المتحركة التي تتمتع بالبناء بسيط، والحركات المستندة إلى المتجهات (vector) عبرت مواقع الويب بالكامل، وإمكانيات إضافية للتفاعل، فقد كانت مثل الباروك (أسلوب فنى في القرنين السابع عشر والثامن عشر تمير بالزخرفة) في ثقافة الويب مع العديد من العناصر المتحركة أيضًا. قدَّم Flash لمحة عن إمكانيات تصميم الويب الديناميكي، الذي يتيح للمصممين إعادة الفحص وتجريب الأأداء ما سبب فترة من التطور السريع في حركات الويب. رسوم Flash المتحركة بُنيَت بِواسطة Flash أو برمجات التحريك المماثلة، وغالبًا ما يتم توزيعها بتنسيق ملف SWF، وهي خفيفة الحجم وسهلة الصنع. فملف يستخدم الصوت مع وضوح وبدون فقدان في دقة رسومات المتجهات وبحجم كيلوبايتات قليلة يجعل التحريك عملية بسيطة ولا تضيف كثيرا إلى وقت تحميل الصفحة. التفاعل في Flash ممكنًا من خلال (Action Script (AS، لغة برمجة كائنية التوجه مثل javascript. تم تصميم AS في البداية لتدير تحريكات المتجهات ذات بعدين (2d). حركات Flash لم تصمَّم لتكون متجاوبة مع جميع أحجام الشاشات، و لم تعمل بشكل جيد على جميع الأجهزة وفي النهاية استُبعدت من الأجهزة المحمولة الشهيرة. رغم كون حجم الملف صغيرًا موازنةً بغيره، إلا أن Flash لم تكن هي الأمثل، نظرًا لبعض المشكلات التي شملتها، أهمها المتعلق بالاستهلاك الكبير لوحدة المعالجة المركزية (CPU)، فقد كانت هذه بالطبع مشكلة على الهواتف الذكية والأجهزة الأخرى. جاءت نهاية عصر Flash بعدما قرر Steve Job عدم دعمها على أجهزة Apple المحموله. قال Jobs: حركات الويب هذه الأيام لدينا في هذه الأيام احتياجات مختلفة ويجب أن تكون أدوات تصميم الحركات مرنة وخفيفة. يجب على المطورين إنشاء محتوى للعرض على أجهزة مختلفة، ومراعاة طرق الإدخال المختلفة، والمتصفحات، ونسب الارتفاع، وكثافة نقاط الشاشة (pixel)، وهلم جرًا. من الواضح أن الحركات يجب أن تعمل تمامًا ابتداءً من هاتف ذكي بدقة 720 بكسل 5 بوصة وحتى جهاز QXGA بحجم 9.7 بوصة أو شاشة UHD مقاس 29 بوصة. لدينا أيضًا الكثير من حركات التمرير السريعة للتفاعل مع البرمجيات، إذ لم تعد تلك الإنتقالات، والتحْريكات، وحركات التمرير السريعة، محفوظةً للأجهزة المحمولة فقط. اعتادت عقولنا عليها كثيرًا؛ لذلك، لا يكون الأمر على ما يرام عندما يكون هناك شيء ثابت ولا يمكن تحريكه بلمسة إصبع. يُتَحقق أفضل حل لتصميم الحركات باستخدام HTML5 و CSS3 و JavaScript ورسومات قابلة للتطوير (مثل SVG). نضجت التكنولوجيا هذه الأيام لدرجة كبيرة، فحتى الأجهزة المحمولة التي تعاني من نقص في الطاقة، لديها قدرة عرض نطاق وقوة معالجة مناسبين للتعامل مع الحركات المستهلكة للعتاد، ومحتوى الفيديو عالي الدقة. لا يعني هذا أن المواقع يجب أن تكون مشغولة بالحركات كثيرًا؛ فكما هو الحال دائمًا، يتعلق الأمر بتحقيق التوازن الصحيح بين التفاعل الديناميكي والعناصر الثابتة. في الواقع، إمكانية تنفيذ الكثير من الحركات لا يعني أنه يجب عليك ذلك. شيء آخر يؤخذ بالحسبان عند تصميم حركات الويب وهو دعم تعدد المنصات. منذ عشر سنوات، لم يكن على المصممين التأكد من أن تصاميمهم ستبدو جيدة على مجموعة واسعة من الأجهزة. هذه الأيام، يجب أن تعمل الحركات بكفاءة على كلًا من الهاتف الذكي وجهاز التلفزيون الضخم. Aspect ratio(نسبة العرض للارتفاع) والصور الشخصية، والاتجاه العرضي للجوالات، وكذلك يجب مراعاة الكثافات المختلفة لنِقاط الشاشة ومسافات المشاهدة. هذا يبرز المصمم مع مجموعة جديدة من التحديات ويخْلق مصاعب إضافية. اختبار التصميم يستهلك وقتا ثمينًا، هناك المزيد من الأشياء التي يمكن أن تسوء بتعدد المنصات، والحركات يجب أن تكون أكثر تفصيلًا من السابق. الخبر السار هو أن HTML5 و CSS3 و JavaScript تساعد في معالجة معظم هذه المشكلات، وليس كلها. ومع ذلك، من الأفضل دائمًا أن تخطو بحذر، خاصةً إن كنت في دائرة مفتوحة تعرض حلولًا لكل منصات الحوسبة الجديدة. لماذا تستخدم الحركات في المواقع هناك قصة وراء استخدام الحركات، فالأمر كله يتعلق بإعطاء روح لتصميم العناصر. تتشابك الحركات على شبكة الإنترنت مع حركة المستخدم من خلال الموقع، وتوفِّر حركة العضوية للعناصر إلى الموقع. يحتاج مبرمج حركات الويب إلى إدراك تجربة المستخدم وتوقع المسارات التفاعلية المحتملة. يجب أن تكون التجربة سلسة ومنطقية. أحد أهم الأمور المتعلقة بالحركات هو التوقيت. يعطي التوقيت معنى حسِّيًا وانفعاليًا للتحريك. مصمم الحركات يحتاج لاستخدام التوقيت لإعطاء المستخدم الشعور الصحيح والإدراك العالي. هل الحركات سلسة؟ ما مدى سرعتها؟ ما هو نوع وعدد الإطارات المفتاحية التي يجب استخدامها في الحركات؟ ما رد الفعل الناجم عن التفاعل معها، وما مدى سرعة رد الفعل بعد التفاعل؟ إن لم تكن الحركات سلسة، يمكن أن ينظر إليها المستخدم على أنها خطأ ويَفقِد الحافز لمزيد من الاستكشافات حول الموقع نفسه. من وجهة نظر منطقية، يمكننا تقسيم الحركات على شبكة الإنترنت إلى نوعين أساسيين: الحركات الثابت مع منطق بسيط، لا توجد معايير ديناميكية معقدة، على سبيل المثال الرسوم المتحركة ‎.gif. الحركات الديناميكية مع نوع من مشاركة المستخدم، يعتمد على إدخال المستخدم، والمتغيرات الأخرى، ويمكن أن يكون له العديد من النتائج المختلفة. الحركات الديناميكية لها منطقها الخاص، محددةً كيفية جريان الحركة. أفضل مثال على الحركات الديناميكية هو الألعاب، حيث يتعامل المستخدمون مع المحتوى على الشاشة. مثال بسيط هو تغيير مواضع العناصر من خلال التمرير الذي يتحكم فيْه المستخدم حسب مكانه في الموقع، هذا يستفتح سلسلة من الحركات. هنا أمثلة واضحة. غالبًا ما يستخدم هذا النهج لتقديم الرسوم البيانية على موقع الويب، لذلك يعطي المستخدم المزيد من الاهتمام أثناء التصفح. إنها طريقة ديناميكية لتسليط الضوء على المعلومات ذات الصلة. الحركات الديناميكية وسيلة جيدة للحفاظ على تركيز الانتباه على الأجزاء المهمة من موقع الويب، ومن الواضح، يتيح للمصممين تقديم المنتجات والخدمات بطريقة أكثر جاذبية. لإنشاء حركات ديناميكية في مواقع الويب، نحتاج إلى المزيد من المعرفة بِ CSS و HTML. إيجابيات وسلبيات حركات الويب دعونا نتعرف على إيجابيات وسلبيات تقنيات الحركات، بما في ذلك الحلول القديمة التي لم تعد قيد الاستخدام. التقنية الإيجابيات السلبيات GIF بسيطة ومتاحة للجميع؛ لأنها تتيح تسلسل الصور المتحركة، ويمكن أن تكون مثل الفيديو وزن ملفات gif المتحركة ضخم. الشفافية مروعة. لا تدعم مجرى ألفا. لديها ضغط منخفض. ومنقطة. APGN يدعم قناة ألفا. غير معتمد في جميع المتصفحات. Flash ملف (swf) المتحرك له وزن منخفض. سريع وتفاعلي. تتيح تحريك المتجهات. التحريك العضوي في بيئة مستخدم بسيطة، لا عشوائية أو تخمين في الكود. يمكن أن يتم ذلك بشكل متجاوب. لم تعد مدعومة على منصات الهواتف المحمولة. HTML/CSS بسيطة وسهلة التعلم. جيدة للتحويلات والانتقالات. تُنفذ الرسوم المتحركة لـ HTML / CSS على الأجهزة المحمولة. تتيح التحريك للمتجهات أو نقاط الشاشة pixel. يمكن معالجة رسومات (SVG) لا يمكن تنشيط جميع خصائص SVG باستخدام CSS. لديها إمكانيات محدودة لِجافا سكريبت و SMIL .تفعل ما يُبرمجه مصممها ولذلك فهي أحد التقنيات الثابتة، لا يمكن الاستجابة للمدخلات الجديدة أو البيئة المتغيرة (التحريك الديناميكي). SMIL مدمجة وقادرة على تنشيط الخصائص التي لا تستطيع CSS التعامل معها. يُحافَظ عليها عندما يتم تضمين SVG كصورة. غير مدعوم في جميع المتصفحات. JavaScript يجعل التحريك سهل إذا كنت تستخدم مكتبة رسوم متحركة لـ SVG تنشئ تسلسل صور (تسلسل .png) لا يُحافَظ عليه عندما يتم تضمين SVG كصورة ولكن ماذا عن إيجابيات وسلبيات حركات الويب بشكل عام؟ حتى الحركات جيدة التنفيذ يمكن أن تبدو في غير محلها بعض الأحيان، لذلك من الأفضل دائمًا أن تطرح بعض الأسئلة على نفسك (والعميل) قبل مواصلة إضافه الحركات في تصميمك. بالنسبة للمبتدئين، تحتاج للتحقق ما إن كانت الحركات تؤثر على تجربة المستخدم أم لا. هل سيحسن التجربة بالفعل؟ للقيام بذلك تحتاج إلى: تفحُّص عن كثب للتصميم الحالي (إن وجد). تفحص الجمهور المستهدف ومنصات أجهزته. تحقق من زمن تحميل الموقع وتحمُّل وحدة المعالجة المركزية CPU. استعرِض البدائل الأخرى. دائما ضع خاصية سهولة الإستخدام في الحسبان. قرار استخدام الحركات يجب أن يكون كأي قرار تصميم آخر؛ عليك أن تزن الإيجابيات والسلبيات وتتأكد من أن تجربة المستخدم لا تتأثرسلبًا، وأنك لن تتعثر مع الكثير من التعليمات البرمجية غير الفعالة (والتي قد تضطرك لإضافة شيفرة جديدة والتحديثات في وقت لاحق). بشكل عام، استخدام الحركات من أجل التحريك ليس فكرة جيدة. صحيح أن الحركات نضجت على شبكة الإنترنت، لكن كون توفرها على نطاق واسع لا ينبغي أن يكون السبب الوحيد وراء قرارك بتنفيذها. لا تنظر إلى الحركات من منظور تقني بحت، عليك أن تفعل ذلك من منظور المستخدم. ترجمة -وبتصرف- للمقال Web Animation In The Post-Flash Era لصاحبته Ana Gregurec
  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 لبدء العرض من الشريحة الحالية:
×
×
  • أضف...