الرسوم المتحركة في أمثلة JS مع التعليمات البرمجية إنشاء الرسوم المتحركة في جافا سكريبت

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

تنشأ المشاكل عندما تحتاج إلى استخدام جافا سكريبت لتطوير الرسوم المتحركة CSS3. نعلم جميعًا أن جافا سكريبت في معظم الحالات هي الضرورة الأولى التي تسمح لنا بحساب القيم الفردية أو عملية الرسوم المتحركة ككل.

الجمع بين CSS وجافا سكريبت باستخدام طريقة animate() الجديدة

تسمح لنا طريقة javascript animate() الجديدة بالتحكم في الرسوم المتحركة من خلال برنامج نصي. بالطبع، ما زلنا بحاجة إلى استخدام مجموعة كاملة من معلمات CSS لتحديد إطاراتنا الرئيسية.


(الارتفاع: "0")،
(الارتفاع: "100%)"
], {
المدة: 3000،
التكرار: 2،
التأخير: 1000
});
في المثال أعلاه، قمنا بإرفاق طريقة animate() بالعنصر. داخل الأقواس المربعة، نحدد العدد الذي نحتاجه من حالات معلمة معينة، وفي مثالنا سنعمل على الارتفاع. تتم كتابة كل قيمة كحرف كائن، ويتم استخدام القيم لمعلمة فردية واحدة فقط. لا يُسمح بمجموعات مثل العرض والارتفاع. لاحظ أنه يجب نقل القيم نفسها، وتنسيقها في صيغة متوافقة مع جافا سكريبت، مما يعني استخدام "backgroundColor" بدلاً من "background-color". في حرف آخر من الكائن، مباشرة بعد إغلاق الأقواس المربعة، نحدد المزيد من الرسوم المتحركة. نريد تغيير طول الرسوم المتحركة باستخدام المدة، وتكرار التكرار باستخدام التكرار، ويمكننا اختياريًا تحديد التأخير باستخدام معلمة التأخير - تحدد هذه المعلمة اللحظة التي يجب أن تبدأ فيها الرسوم المتحركة. يتم تحديد جميع قيم الوقت بالمللي ثانية.

نحن ندير مجموعة الإطارات الرئيسية ومدتها

نحن بحاجة إلى تشغيل طريقة animate() بشكل منفصل عن كل معلمة نحتاج إلى تغييرها. هذا يعني أننا إذا أردنا تغيير كل من الارتفاع والعرض، فسنحتاج إلى إعادة تشغيل animate()‎.

Document.getElementById("العنصر").animate([
(العرض: "0"، الإزاحة: 0)،
(العرض: "10%"، الإزاحة، 1/3)،
(العرض: "100%"، الإزاحة: 1)
], {
المدة: 3000،
التكرار: 2،
التأخير: 1000
});
في المثال أعلاه نقوم بتغيير عرض العنصر. يجب أن يختلف العرض بدءًا من 0، ويصل إلى 10 بالمائة، ثم ينتهي عندما يصل إلى 100 بالمائة. كل هذا سيكون مصحوبًا برسوم متحركة سلسة بشكل طبيعي. تحدد معلمة الإزاحة الإضافية أن التغييرات من 0 إلى 10 بالمائة ستستغرق 1/3 من إجمالي وقت الحركة، وسيستغرق الانتقال من 10 إلى 100 2/3 من إجمالي وقت الحركة. وفي الوقت نفسه، يتم تحديد المدة الإجمالية للرسوم المتحركة بواسطة معلمة المدة. في هذه الحالة، سيتم تنفيذ الجزء الأول على مدار ثانية واحدة، والثاني على مدار ثانيتين.

بدلاً من تعريف القيمة ككسور، يمكنك أيضًا استخدام الكسور العشرية. تحتاج إلى استخدام الأرقام من 0 إلى 1. على سبيل المثال، بدلاً من 1/3، يمكنك استخدام 0.33.

المزيد من خيارات الرسوم المتحركة

إذا كنت معتادًا على معلمة الرسوم المتحركة CSS3، فمن المحتمل أنك تعلم أن طريقة animate() تسمح لك بالتحكم في عملية الرسوم المتحركة. يمكنك تغيير الاتجاه، وكذلك سرعة الرسوم المتحركة، وتسارعها. إذا كنت تريد تحديد أنه بعد الانتهاء، يجب أن تعود الرسوم المتحركة إلى البداية، يمكنك القيام بذلك.

Document.getElementById("العنصر").animate([

], {
المدة: 3000،
التكرار: 2،
تأخير: 1000،
الاتجاه: "عكس"،
التيسير: "التخفيف"،
ملء: "إلى الأمام"
});
تحتوي قيمة الاتجاه على معلومات حول اتجاه الرسوم المتحركة. إذا قمت بضبطه على الوضع العكسي، فسيتم تشغيل الرسوم المتحركة في الاتجاه المعاكس. ستسمح لك القيمة البديلة بتشغيل الرسوم المتحركة في الاتجاه القياسي، ثم في الاتجاه المعاكس. والقيمة العكسية البديلة تجمع بين القيمتين الأخيرتين.

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

التحكم في الرسوم المتحركة

يتيح لنا استخدام animate() على متغير التحكم في الرسوم المتحركة باستخدام جافا سكريبت. يمكننا أن نبدأ ونوقفه وفقًا لتقديرنا الخاص.

فار الرسوم المتحركة = document.getElementById("element").animate([
(الارتفاع: "0")،
(الارتفاع: "100%)"
], {
المدة: 3000،
التكرار: 2،
التأخير: 1000
});

document.getElementById("animation_start").addEventListener("انقر"، وظيفة() (
Animation.play();
)، خطأ شنيع)؛

document.getElementById("animation_pause").addEventListener("انقر"، وظيفة() (
Animation.pause();
)، خطأ شنيع)؛
في مثالنا، قمنا بإرفاق الرسوم المتحركة بمتغير الرسوم المتحركة، وهو أمر غريب بما فيه الكفاية. ثم نقوم بإرفاق مستمعين للأحداث بالعناصر ذات المعرف Animation_start و Animation_pause. سيهتم هؤلاء المستمعون بأداء وظائف معينة عند النقر عليها. يبدأ التشغيل الرسوم المتحركة، ويكون الإيقاف المؤقت واضحًا بالفعل ما يفعله، وسينقلك العكس على الفور إلى الإطار الرئيسي الأخير ويوقف الرسوم المتحركة تمامًا.

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

Animation.addEventListener("finish"، وظيفة() (
تنبيه("انتهت الرسوم المتحركة.");
)، خطأ شنيع)؛
في المثال أعلاه، نقوم ببساطة بإطلاق رسالة تشير إلى اكتمال الرسوم المتحركة.

دعم المتصفح

animate() حاليًا في مرحلة التطوير المبكرة وهي حاليًا مثقلة بالعلامة "التجريبية". سيظهر دعم هذا الخيار في Chrome بدءًا من الإصدار 36. إذا كنت تريد تجربته الآن، فيمكنك تنزيل Chrome Canary وتثبيته.

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

المبدأ الكامن وراء التلاشي هو أن لون خلفية عنصر التلاشي يتم ضبطه على اللون الأصفر، ثم من خلال سلسلة من الخطوات، يعود لونه إلى لونه الأصلي. لذا، إذا كان لون الخلفية الأصلي أحمر، فسيتم تعيين اللون بعد ذلك إلى الأصفر، ثم البرتقالي المصفر، ثم البرتقالي، ثم الأحمر البرتقالي، ثم الأحمر. يحدد عدد الخطوات المستخدمة مدى سلاسة حدوث تغيير اللون، ويحدد الوقت بين الخطوات مدة استمرار تغيير اللون. عند تغيير الألوان، يمكن استخدام حقيقة مفيدة من CSS: يمكن تعريف اللون على أنه ثلاثة أرقام عادية أو كسلسلة سداسية عشرية. لذلك يمكن أيضًا تعريف #FF0000 (اللون الأحمر) على أنه rgb(255,0,0) . التغيير من الأصفر إلى الأحمر في خمس خطوات يعني الانتقال من rgb(255,255,0) (أصفر) إلى rgb(255,0,0) في الخطوات الخمس التالية:

رغب (255،255،0) رغب (255،192،0) رغب (255،128،0) رغب (255،64،0) رغب (255،0،0)

مثال أكثر تعقيدًا: النقل وتغيير الحجم

على الرغم من أن طريقة التلاشي الأصفر توضح الرسوم المتحركة، إلا أنها مملة إلى حد ما. عندما يفكر معظم الناس في الرسوم المتحركة، فإنهم عادة ما يفكرون في الحركة. تقنية مثيرة للاهتمام لتحذير المستخدم من حدوث شيء ما دون مقاطعته سير العمل، يتكون من رسالة غير نموذجية. بدلاً من عرض مربع حوار التنبيه () الذي يتطلب من المستخدم النقر نعمقبل أن يتمكن من المتابعة، ضع الرسالة ببساطة في قسم عائم على الصفحة التي تظل هناك بشكل غير ملحوظ حتى تتلقى التأكيد. الشيء الثاني المثير للاهتمام هو السماح للمستخدم بالعودة إلى الرسالة التي أكد رغبته في قراءتها مرة أخرى. لذلك دعونا ننفذ رسالة عائمة، عند النقر عليها، تنهار في زاوية الشاشة ويمكن بعد ذلك استعادتها مرة أخرى عند النقر عليها. يمكنك مشاهدة عرض توضيحي قصير لهذه "الرسالة القابلة للطي" (http://dev.opera.com/articles/view/javascript-animation/moving_messages_jq.html) للحصول على الفكرة العامة.

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

يستخدم العرض التوضيحي أعلاه مكتبة jQuery (http://jquery.com/) لجعله يعمل، ولكن كما ذكرنا، توفر معظم المكتبات مفهومًا مشابهًا للرسوم المتحركة بدرجة كافية بحيث تكون قادرًا على تنفيذ الجزء الأساسي باستخدام مكتبتك المفضلة. في الأساس، عليك القيام بما يلي:

  1. إظهار رسالة عائمة في وسط الشاشة
  2. عندما يتم النقر عليه:
    1. حرك موضعه الأفقي إلى أقصى الموضع الأيمن
    2. حرك موضعه الرأسي لأعلى
    3. اضبط عرضه على 20 بكسل
    4. اضبط ارتفاعه على 20 بكسل
    5. اجعل كثافته تساوي 20%، بحيث يصبح شبه شفاف ويخفي النص الموجود فيه
  3. عند النقر على هذه النسخة "المصغرة" من الرسالة، قم باستعادتها إلى منتصف الشاشة (أي عكس ما فعلناه لضغطها) وحتى يحصل المستخدم على صورة واضحة عما حدث لرسالته، قفزًا من الحجم الكامل يجب أن تكون الرسائل المرسلة إلى الرسالة المصغرة متحركة (حتى يتمكنوا من رؤية الرسالة "تتقلص" في زاوية النافذة).

تعد الرسوم المتحركة باستخدام jQuery أمرًا سهلاً للغاية: ما عليك سوى استخدام ملف . تحريك ()وتقديم النتيجة النهائية المطلوبة للرسوم المتحركة (ومدة تشغيلها):

$(ourObject).animate(( العرض: "20px"، الارتفاع: "20px"، الأعلى: "20px"، اليمين: "20px"، الهامش الأيمن: "0px"، العتامة: "0.2" )، 300);

تأخذ الدالة كائننا الخاص بنا، وفي 300 مللي ثانية، تستبدل عرضه وارتفاعه بـ 20 بكسل، ومواضعه العلوية والأيمن بـ 20 بكسل، وخاصية نمط الهامش الأيمن بـ 0 بكسل، وكثافته (في المتصفحات التي تدعم كثافة الصورة) بـ 20%. إذن فالأمر يتعلق فقط بالبرمجة بأسلوب

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

لقد أصبح برنامج Flash غير مفضل تدريجيًا، وجعل رسامي الرسوم المتحركة الموهوبين HTML5 يفعل أشياء لم يفعلها من قبل. لقد احتاجوا إلى أدوات أكثر كفاءة للتأثيرات المعقدة والأداء المتميز.

jQuery ببساطة لم يتم تصميمه لهذا الغرض. لقد نضجت المتصفحات وبدأت في تقديم الحلول.

الحل الأكثر شهرة هو الرسوم المتحركة CSS. الرسوم المتحركة لـ CSS، باعتبارها محبوبة صناعة تكنولوجيا المعلومات، تمت مناقشتها بلا نهاية في المؤتمرات لعدة سنوات، حيث تم استخدام عبارات مثل " تسريع الأجهزة" و " ودية المحمول"مداعب آذان الجمهور.

كان يُنظر إلى الرسوم المتحركة المبنية على جافا سكريبت على أنها قديمة و"فاحشة". ولكن هل هذا حقا؟

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

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

لا يوجد مقياس مستقل/دوران/تحكم في الموضع

يعد تحريك حجم العنصر وتدويره وموضعه أمرًا شائعًا للغاية. في CSS، يتم حشو كل هذه المعلمات في خاصية التحويل، مما يجعل من المستحيل إنشاء رسم متحرك منفصل لكل معلمة من عنصر واحد.

على سبيل المثال، ماذا لو كنت تريد القيام بالتدوير وتحجيم الرسوم المتحركة بشكل مستقل عن بعضها البعض، مع حسابات وقت تشغيل مختلفة ووظائف التخفيف؟

ربما يكون العنصر ينبض باستمرار (مقياس التذبذب) وترغب في تدويره عند التمرير. وهذا ممكن فقط مع جافا سكريبت.

لغة البرمجة:

لاحظ أنه يمكن تحريك المقياس والتدوير والموضع بشكل مستقل عن بعضها البعض، باستخدام وظائف تخفيف مختلفة وأوقات البدء/الانتهاء المتداخلة (وهو أمر غير ممكن مع الرسوم المتحركة CSS).

التحويلات المستقلة

CSS:

الجسم ( لون الخلفية: أسود؛ الهامش: 0؛ الحشو: 0؛ عائلة الخط: Signika Negative، sans-serif؛ وزن الخط: 300؛ ) html، body ( الارتفاع: 100%؛ ) #demo ( العرض: جدول العرض: 100%؛ الارتفاع: 100%) #field (الموضع: نسبي؛ العرض: خلية الجدول؛ الارتفاع: 100%؛ الفائض: مخفي؛ محاذاة النص: المركز؛ محاذاة عمودية: الوسط؛) #box ( اللون: أسود، حجم الخط: 24 بكسل؛ الحد: 2 بكسل أسود خالص؛ #999؛ الأعلى: 0 بكسل؛ الحشو: 0 بكسل 20 بكسل؛ محاذاة النص: اليسار؛ محاذاة النص: المركز؛

شبيبة:

var $box = $("#box"), $field = $("#field"), Rotation = 0, RotationX = 0, RotationY = 0, WanderTween,ignoreRollovers; // قم بتطبيق المنظور على الحاوية حتى نتمكن من رؤية ثلاثية الأبعاد. TweenLite.set($field, (المنظور: 500)); // قم بإزاحة المصدر على طول المحور z لجعل التدوير أكثر إثارة للاهتمام. TweenLite.set($box, (transformOrigin:"center center -150px")); // اجعل المستطيل ينبض باستخدام ScaleX وscaleY TweenMax.to($box, 1.2, (scaleX:0.8,scaleY:0.8, force3D:true, yoyo:true, Repeat:-1, easy:Power1.easeInOut)); // عند التمرير، سنقوم بقلب المستطيل، ولكن لتجنب التدوير // المفرط، سنقوم بتقليل حساسية التمرير للثانية الأولى من // الرسوم المتحركة. $box.hover(function() ( if (!ignoreRollovers) (Rotation += 360; 1، الدالة() (ignoreRollovers = false; ) ) )، الدالة() ()); $("#rotation").click(function() ( Rotation += 360; TweenLite.to($box, 2, (rotation:rotation,easy:Elastic.easeOut)); )); $("#rotationX").click(function() ( RotationX += 360; TweenLite.to($box, 2, (rotationX:rotationX, easy:Power2.easeOut)); )); $("#rotationY").click(function() ( RotationY += 360; TweenLite.to($box, 2, (rotationY:rotationY, easy:Power1.easeInOut)); )); $("#move").click(function() ( if (wanderTween) (anderTween.kill();anderTween = null; TweenLite.to($box, 0.5, (x:0, y:0)); ) آخر ( تجول ()؛ ) ))؛ // حدد مكانًا على الشاشة بشكل عشوائي وابدأ الرسوم المتحركة هناك، ثم كرر هذا // مرارًا وتكرارًا. دالة Wander() ( var x = (($field.width() - $box.width()) / 2) * (Math.random() * 1.8 - 0.9), y = (($field.height()) - $box.height()) / 2) * (Math.random() * 1.4 - 0.7);anderTween = TweenLite.to($box, 2.5, (x:x, y:y, easy:Power1.easeInOut, onComplete:wander));

من الواضح أن هذه نقطة ضعف في CSS في رأيي، ولكن إذا كنت تقوم بإنشاء رسوم متحركة أبسط تتضمن تحويلات كاملة في أي وقت، فلن يمثل هذا مشكلة بالنسبة لك.

أداء

معظم المقارنات بين الرسوم المتحركة لـ CSS على الإنترنت مقابل مكتبة jQuery، نظرًا لأنها شائعة جدًا (كما لو كان "JavaScript" و"jQuery" مترادفين)، ولكن من المعروف على نطاق واسع أن jQuery بطيء جدًا من حيث أداء الرسوم المتحركة.

تعتمد مكتبة GSAP الأحدث أيضًا على JavaScript، ولكنها أسرع 20 مرة من jQuery، لذا فإن أحد أسباب حصول JavaScript على سمعة سيئة هو ما أسميه "عامل jQuery".

الحجة الأكثر شيوعًا لاستخدام CSS للرسوم المتحركة هي " تسريع الأجهزة" يبدو لذيذا، أليس كذلك؟

دعنا نقسمها إلى قسمين:

تورط GPU

وحدة معالجة الرسومات (GPU)تم تحسينه بدرجة كبيرة لمهام مثل تحريك وحدات البكسل وتطبيق الشفافية ومصفوفات التحويل، لذلك تحاول المتصفحات الحديثة إلغاء تحميل مثل هذه المهام من وحدة المعالجة المركزية (CPU) إلى وحدة معالجة الرسومات.

السر هو فصل العناصر المتحركة إلى طبقات GPU الخاصة بها، لأنه بمجرد إنشاء الطبقة (طالما لم تتغير وحدات البكسل الأصلية الخاصة بها)، فمن السهل على وحدة معالجة الرسومات تحريك تلك البكسلات ودمجها معًا.

بدلاً من حساب كل بكسل فردي 60 مرة في الثانية، يمكن لوحدة معالجة الرسومات تخزين مجموعات من البكسل (كطبقات) والقول ببساطة: حرك هذه المجموعة بمقدار 10 بكسل و5 بكسل للأسفل" (أو شيء من هذا القبيل).

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

يسمح الإعلان عن الرسوم المتحركة في CSS للمتصفح بتحديد العناصر التي يجب أن تتلقى طبقات GPU وتوزيعها وفقًا لذلك. عظيم!

لكن هل تعلم أنه باستخدام جافا سكريبت يمكنك القيام بذلك أيضًا؟ يؤدي تعيين تحويل بخاصية ثلاثية الأبعاد (مثل Translator3d() أو Matrix3d() ) إلى قيام المتصفح بإنشاء طبقة GPU لهذا العنصر. لذا فإن زيادة سرعة وحدة معالجة الرسومات لا تعمل فقط مع الرسوم المتحركة CSS، بل يمكن أن تستفيد منها الرسوم المتحركة JavaScript أيضًا!

لاحظ أيضًا أنه ليس كل خصائص CSS يتم تسريعها بواسطة GPU في الرسوم المتحركة CSS. في الواقع، معظمهم لا يحصلون على هذا التسارع. تعد التحويلات (الحجم والتدوير والقص والانحراف) والشفافية من العمليات الرئيسية التي تستفيد من تسريع وحدة معالجة الرسومات.

لذلك لا تعتقد أنه إذا قمت بإنشاء رسوم متحركة باستخدام CSS، فسيتم تسريع كل شيء بطريقة سحرية باستخدام GPU. هذا ببساطة غير صحيح.

إعادة توزيع الحسابات إلى موضوع آخر

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

بادئ ذي بدء، يمكن فقط تمرير تلك الخصائص التي لا تؤثر على تدفق المستند إلى مؤشر ترابط آخر.

ومرة أخرى، فإن التحول والشفافية هما المستفيدان الرئيسيان. عندما تكون الخيوط متشعبة، يكون هناك عبء مرتبط بإدارة هذه العملية.

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

على سبيل المثال، إذا كان 98% من العمل أثناء رسم متحرك معين هو عرض الرسومات وتخطيط المستند، و2% هو اكتشاف الموضع/التدوير/الشفافية/أي قيم جديدة، وحتى حسابها بشكل أسرع 10 مرات، فلن ترى سوى حوالي 1 في المجموع ٪ زيادة السرعة.

مقارنة الأداء

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

قم بتعيين عدد كبير من النقاط وشاهد مقارنة بين jQuery وGSAP وZepto.

نظرًا لأن Zepto يستخدم تحويلات CSS لجميع الرسوم المتحركة، فيجب أن يكون أدائه هو الأفضل، أليس كذلك؟

لغة البرمجة:

  • محرك:
  • ملكيات:
  • النقاط:
  • يبدأ
  • اختبار سرعة الرسوم المتحركة بتنسيق HTML5

    قارن أداء الرسوم المتحركة بناءً على تحويلات jQuery وGSAP (GreenSock Animation Platform) وتحويلات CSS (المستخدمة في Zepto). حدد الخيارات أعلاه ثم اضغط على "ابدأ". قم بزيادة عدد النقاط حتى ترى حركات متقطعة أو كتل/دوائر. لاحظ أيضًا الخصائص التي تتحرك بشكل أسرع: "أعلى"، و"يسار"، و"عرض"، و"ارتفاع" أو "تحويل: ترجمة (...) مقياس (...)". قد تتفاجأ.

    CSS:

    الجسم (لون الخلفية: أسود؛ الهامش: 0؛ الحشو: 0؛ اللون: #eee؛ عائلة الخط: Signika Negative، sans-serif؛ وزن الخط: 300؛ حجم الخط: 1.15em؛ تحديد المستخدم: لا شيء -webkit-user-select:none;) html، النص (الارتفاع: 100%؛ الفائض: مخفي؛) h1 (وزن الخط: 400؛ حجم الخط: 2em؛ ارتفاع الخط: 1em؛ الهامش السفلي: 0.1) em اللون: أبيض) أ، أ: تحويم، أ: تمت الزيارة (اللون: #71B200؛) #controls (العرض: صف الجدول؛ لون الخلفية: #555؛ الخلفية: التدرج الخطي (إلى الأسفل، #777؛ 0%,#444 100%); الحشو: 10px 10px 5px; z-index:1000; : 1px 1px 1px #000 ) #تعليمات ( العرض: 82%؛ الهامش الأيسر: 8%؛ الحشو العلوي: 1em؛ ارتفاع الخط: 1.5em؛ اللون: #ccc؛ ) #demo ( العرض: الجدول؛ العرض :100%; الارتفاع:100%;) #field (الموضع: نسبي; العرض: خلية جدول; العرض: 100%; الارتفاع: 100%; الفائض: مخفي; فهرس z:-100; الحد العلوي: 1 بكسل صلب #777) #بداية (اللون: أسود؛ نصف قطر الحدود: 6 بكسل؛ الحشو: 5 بكسل 18 بكسل؛ الحدود: 2 بكسل أسود خالص؛ الخلفية: #9af600; الخلفية: تدرج خطي (إلى الأسفل، #9af600 0%، #71B200 100%)؛ المؤشر: المؤشر؛ ظل النص: لا شيء؛ وزن الخط: 400؛ )

    شبيبة:

    فار $start = $("#start"), $dotQtyInput = $("#dotQuantity"), $engineInput = $("#engine"), $propertiesInput = $("#properties"), $instructions = $( "#تعليمات")، $field = $("#field")، $window = $(window)، $inputs = $("select")، inProgress = false، الاختبارات = ()، المدة، نصف القطر، centerX، centerY، dots، RawDots،currentTest، beginCSS؛ /** * الغرض من هذا الاختبار هو مقارنة كيفية أداء أدوات الرسوم المتحركة المختلفة تحت التحميل، وتنفيذ مهام الرسوم المتحركة الشائعة نسبيًا وتشغيلها بأعداد كبيرة لرؤية الأداء الأولي. الهدف ليس اكتشاف الطريقة الأكثر فعالية لتحريك النقاط في نمط الحقل النجمي. * * يتم استخدام نفس الكود في كل شيء ما عدا الرسوم المتحركة نفسها. يحتوي كل اختبار في كائن "الاختبار" على 4 خصائص: * * - ميلي ثانية - صحيح إذا كان يجب تحديد المدة بالميلي ثانية * * - WrapDot - عند كل نقطة يتم إنشاؤه، ويجب تمريره إلى طريقة WrapDot () ويتم تخزين ما يتم إرجاعه بواسطة الوظيفة في مصفوفة من النقاط للرسوم المتحركة. يعد هذا مفيدًا لتحسين أداء أشياء مثل jQuery، لأنه بدلاً من تمرير DOM الخاص بالعنصر إلى الأسلوب tween() (والذي قد يتطلب jQuery للاستعلام عن DOM ولف العنصر في كائن خاص بمحرك قبل استدعاء animate()) ، يمكن استخدام كائن طبيعي. ببساطة، سيسمح هذا بتخزين التفاف النقاط مؤقتًا لتحسين الأداء. * * - التوين هو جوهر الاختبار بأكمله. يتم استدعاء tween() لكل نقطة، ويتم تمرير النقطة كمعلمة. يجب أن تقوم الدالة tween()‎ بتعيين cssText للنقطة على قيمة startCSS (التي تضع النقطة ببساطة في منتصف الشاشة وتضبط عرضها وارتفاعها على 1 بكسل) ثم بعد تأخير عشوائي قدره 0 إلى وقت تنفيذ الرسوم المتحركة، يجب أن تقوم الوظيفة بتحريك النقطة تحت زاوية عشوائية عن طريق تغيير القيم اليسرى/العلوية أو تحويلات الترجمة () وتعيين الحجم إلى 32 بكسل في العرض والارتفاع باستخدام إما العرض/الارتفاع أو المقياس (). بعد ذلك، بعد اكتمال الرسوم المتحركة، يجب استدعاء طريقة tween() مرة أخرى في نفس النقطة. لذا فإن النقطة نفسها ستتحرك باستمرار بعيدًا عن المركز بزاوية عشوائية وبزمن تأخير عشوائي. * * - توقف – يتم استدعاء هذه الوظيفة عندما يتوقف المستخدم عن الاختبار. يتم تمرير النقطة كمعلمة. يجب أن تقوم الوظيفة بإيقاف/تدمير الرسوم المتحركة (أو الرسوم المتحركة) التي يتم تشغيلها على الفور لهذه النقطة (أو لجميع النقاط - وهذا أمر طبيعي أيضًا). * * - originalSize - صحيح إذا كان العرض/الارتفاع الأولي للصور يجب أن يكون بالحجم الطبيعي (عادةً ما يكون ضروريًا للتحويلات، ولكن ليس عندما نقوم بتحريك العرض/الارتفاع). * *لا أدعي أنني خبير في محركات الرسوم المتحركة المختلفة، لذا إذا كانت هناك تحسينات يمكن تطبيقها لتحسين أداء الاختبار، فيرجى إبلاغي بذلك. حاولت أن أفعل كل شيء بحيادية قدر الإمكان. **/ // jQuery قياسي عادي (أعلى/يسار/عرض/ارتفاع) الاختبارات.jquery_normal = ( ميلي ثانية: صحيح، WrapDot:function(dot) (return jQuery(dot); // قم بلف النقطة في كائن jQuery لتحسينها الأداء (بهذه الطريقة لا يتعين علينا الاستعلام عن DOM في كل مرة نقوم فيها بالتحريك - يمكننا فقط استدعاء animate() مباشرة على كائن jQuery)، tween:function(dot) ( var angle = Math.random() * Math. PI * 2 ; dot.style.cssText = beginCSS; dot.delay(Math.random() * Duration).animate((left:Math.cos(angle) * radius + centerX, top:Math.sin(angle) * نصف القطر + centerY، العرض: 32، الارتفاع: 32)، المدة، "cubicIn"، الوظيفة () ( الاختبارات.jquery_normal.tween(dot)))، الإيقاف: الوظيفة (dot) ( dot.stop(true); )، الحجم الأصلي: خطأ)؛ // معيار GSAP (أعلى/يسار/عرض/ارتفاع) الاختبارات.gsap_normal = ( ميلي ثانية: خطأ، WrapDot:function(dot) (نقطة الإرجاع؛ // لا حاجة للالتفاف)، tween:function(dot) ( var angle = Math.random() * Math. بي*2؛ dot.style.cssText = beginCSS; TweenLite.to(dot, Duration, (css:(left:Math.cos(angle) * radius + centerX, top:Math.sin(angle) * radius + centerY, width:32, height:32), تأخير:Math .random() * المدة، السهولة:Cubic.easeIn، الكتابة فوق:"none"، onComplete:tests.gsap_normal.tween، onCompleteParams:)); )، stop:function(dot) ( TweenLite.killTweensOf(dot); ), originalSize:false); // تحويلات GSAP (translate()/scale()) الاختبارات.gsap_transforms = ( ميلي ثانية: خطأ، WrapDot:function(dot) (نقطة الإرجاع؛ // لا حاجة للالتفاف)، tween:function(dot) ( var angle = Math.random() * Math.PI * 2 TweenLite.set(dot, (css:(x:0, y:0,scale:0.06), overwrite:"none"), (css:(x: (Math.cos(angle) * radius)، y:(Math.sin(angle) * radius)،scaleX:2،scaleY:2)، التأخير:Math.random() * المدة، السهولة:Cubic.easeIn، الكتابة الفوقية :"none"، onComplete:tests.gsap_transforms.tween، onCompleteParams:)); stop:function(dot) ( TweenLite.killTweensOf(dot); ), originalSize:true); // اختبارات Zepto القياسية (أعلى/يسار/عرض/ارتفاع). لا داعي للاستعلام عن DOM في كل مرة نقوم فيها بالتحريك - يمكننا فقط استدعاء animate() مباشرة على كائن jQuery)، tween:function(dot) ( var angle = Math.random() * Math.PI * 2; dot.style .cssText = beginCSS; // تعمل وظيفة التأخير في Zepto بشكل رهيب تحت الضغط، لذلك نستخدم setTimeout() بدلاً من ذلك لتحسين الأداء. مما يسمح لنا بإيقاف تشغيل الرسوم المتحركة، لذلك نقوم ببساطة بتعيين الخاصية isKilled الخاصة بنا على القيمة true عندما يُفترض أن يتم إيقاف الرسوم المتحركة ثم نوقف التكرار، مما يمنحنا التأثير الذي نحتاجه dot.animate((left:Math.cos (زاوية) * نصف القطر + centerX، أعلى: Math.sin(angle) * نصف القطر + centerY، العرض: 32، الارتفاع: 32)، المدة، "bezier مكعب (0.550، 0.055، 0.675، 0.190)"، وظيفة () ( tests.zepto_normal.tween(dot)); )))، المدة * Math.random()); ), stop:function(dot) ( dot.isKilled = true; ), originalSize:false ); // تحويلات Zepto (translate()/scale()) الاختبارات.zepto_transforms = ( ميلي ثانية: صحيح، WrapDot:function(dot) ( return Zepto(dot); // لف النقطة في كائن jQuery لتحسين الأداء (لذلك نحن ليست هناك حاجة للاستعلام عن DOM في كل مرة نقوم فيها بالتحريك - يمكننا فقط استدعاء animate() مباشرة على كائن jQuery) )، tween:function(dot) ( // لم أتمكن من تعيين وظيفة css() في Zepto (فشلت )، لذلك اضطررت إلى استخدام مكالمة animate() ذات مدة صفرية. على الرغم من أن هذا أمر عادل، لأنه بالنسبة لـ TweenLite، فإننا في الواقع نصنع رسومًا متحركة بمدة صفرية. dot.animate((translateX:"0px, TranslateY:"0px, RotateY:"0rad, RotateX:"0rad,scale:"0.06,0.06"),0); // تعمل وظيفة التأخير في Zepto بشكل رهيب تحت الضغط، لذلك نستخدم setTimeout() بدلاً من ذلك لتحسين الأداء. setTimeout(function() ( if (!dot.isKilled) ( // لا يحتوي Zepto على وظيفة تسمح لنا بإيقاف تشغيل الرسوم المتحركة، لذلك نقوم ببساطة بتعيين خاصية isKilled الخاصة بنا على true عندما نفترض أن الرسوم المتحركة قد توقفت ثم إيقاف العودية، مما يعطينا التأثير المطلوب var angle = Math.random() * Math.PI * 2; Math. sin(angle) * radius) + "px"، مقياس: "2,2"، التأخير: المدة * Math.random())، المدة، "cubic-bezier(0.550, 0.055, 0.675, 0.190)"، الوظيفة () ( الاختبارات.zepto_transforms.tween(dot); ) ) ) المدة * Math.random()); )، stop:function(dot) ( dot.isKilled = true; ), originalSize:true ); وظيفة toggleTest() ( var i, size; inProgress = !inProgress; if (inProgress) ( $inputs.prop("disabled", true); $field.css((pointerEvents:"none")); // تحسين الأداء - تجاهل أحداث المؤشر أثناء الرسوم المتحركة $start.html("STOP "); $start.css((background:"#C00")); TweenLite.to($instructions, 0.7, (autoAlpha:0, overwrite:"all ") ));currentTest = الاختبارات[$engineInput.val() + "_" + $propertiesInput.val()]; / 2; centerY = $field.height() / 2; beginCSS = "position:absolute; left:" + centerX + "px; top:" + centerY + "px; width:" + size + "; height: " + size + ";"; radius = Math.sqrt(centerX * centerY * centerY); Duration = currentTest.millithans ? 750: 0.75; // انتظر مللي ثانية قبل إنشاء النقاط وبدء الرسوم المتحركة، بحيث يتم تشغيل واجهة المستخدم للأمام ( تحويل زر "البدء" إلى "إيقاف")، وإلا فقد يرتبك المستخدمون أثناء التوقف المؤقت الطويل أثناء تحديد Zepto والتحويل، وذلك نظرًا لحقيقة أن المتصفح قد يستغرق بعض الوقت لوضع جميع النقاط بمفرده. طبقات. setTimeout(function() ( createDots(); i = dots.length; while (--i > -1) (currentTest.tween(dots[i]); ) ), 1); ) else ( $start.html(" START "); $start.css((backgroundColor:"#9af600"، الخلفية: "linear-gradient(to Bottom, #9af600 0%,#71B200 100%")); TweenLite .إلى(تعليمات $، 0. 7، (autoAlpha:1، التأخير:0.2))؛ $inputs.prop("disabled", false); calibrateInputs(); $field.css((pointerEvents:"auto")); // أوقف الرسوم المتحركة واحذف النقاط. أنا = النقاط. الطول؛ while (--i > -1) (currentTest.stop(dots[i]); $field.removeChild(rawDots[i]); // يزيل نقطة (أو نقاط) ) dots = null; RawDots = null; ) ) وظيفة createDots() ( var i = parseInt($dotQtyInput.val()), dot; dots = ; RawDots = ; while (--i > -1) ( dot = document.createElement("img"); dot .src = "https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/dot.png"; dot.width = 1; dot.id = "dot" + i; .style.cssText = beginCSS; $field.appendChild(dot); === "jquery") ( // لا يستطيع jQuery تحريك التحويلات بدون مكون إضافي لجهة خارجية، لذا قم بتعطيل هذا الخيار $propertiesInput.selectedIndex = 0; $propertiesInput.prop("disabled"، true); ) else ( $propertiesInput .prop("disabled", false ) ) $start.click(toggleTest); $inputs.change(calibrateInputs); jQuery.easing.cubicIn = $.easing.cubicIn = function(p, n, firstNum, diff) ( // نحتاج إلى إضافة دالة تخفيف CubicIn القياسية إلى jQuery return firstNum + p * p * p * diff; ) jQuery. الفاصل الزمني = 16; // يضمن تحديث jQuery بمعدل 60 إطارًا تقريبًا في الثانية، مثل GSAP وغيرها، لإظهار نتيجة أكثر مساواة/غير متحيزة. $propertiesInput.prop("disabled", true);

    تؤكد النتائج ما هو ملاحظ على نطاق واسع على الإنترنت، وهو أن الرسوم المتحركة لـ CSS أسرع بكثير من jQuery.

    ومع ذلك، في معظم الأجهزة والمتصفحات التي اختبرتها، يتمتع GSAP المستند إلى JavaScript بأداء أفضل من الرسوم المتحركة CSS (بهامش كبير في بعض الحالات، مثل Microsoft Surface RT حيث كانت مكتبة GSAP أسرع بخمس مرات على الأقل ) أسرع من تحويلات CSS التي تم إنشاؤها باستخدام Zepto، وكانت تحويلات iPad 3 مع iOS7 أسرع بكثير عند إجرائها باستخدام GSAP بدلاً من تحويلات CSS):

    خصائص الرسوم المتحركة أفضل مع جافا سكريبت أفضل مع CSS
    أعلى، يسار، عرض، ارتفاع Windows Surface RT، iPhone 5s (iOS7)، iPad 3 (iOS 6)، iPad 3 (iOS7)، Samsung Galaxy Tab 2، Chrome، Firefox، Safari، Opera، Kindle Fire HD، IE11
    التحولات (التحول/المقياس) ويندوز سيرفيس آر تي، آيفون 5 إس (iOS7)، آيباد 3 (iOS7)، سامسونج جالاكسي تاب 2، فايرفوكس، أوبرا، IE11 آي باد 3 (iOS6)، سفاري، كروم

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

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

    ومن المثير للاهتمام أن نلاحظ:

    • عند تحريك خصائص أعلى/يسار/عرض/ارتفاع (والتي تؤثر على تدفق المستند)، كانت JavaScript أسرع في جميع المجالات (GSAP، وليس jQuery)؛
    • تم تحسين بعض الأجهزة بشكل جيد لإجراء التحويلات، بينما كان البعض الآخر أفضل في التعامل مع الرسوم المتحركة ذات خصائص أعلى/يسار/عرض/ارتفاع. على وجه الخصوص، كان أداء نظام iOS6 الأقدم للتحويلات المستندة إلى CSS أفضل بكثير، ولكن نظام iOS7 الجديد قد غير الأولويات وأصبح الآن أبطأ بكثير؛
    • هناك تأخير كبير في الإطلاق الأولي للرسوم المتحركة المستندة إلى CSS حيث يقوم المتصفح بحساب الطبقات وتحميل البيانات إلى وحدة معالجة الرسومات. ينطبق هذا أيضًا على التحويلات ثلاثية الأبعاد في JavaScript، لذا فإن "تسريع وحدة معالجة الرسومات" لا يتم فقدانه؛
    • في ظل أحمال CSS الثقيلة، من المرجح أن يتم رش التحويلات على شكل خطوط أو حلقات (وهذا بسبب مشكلات المزامنة والجدولة، وربما بسبب التحكم في مؤشر ترابط آخر)؛
    • في بعض المتصفحات (مثل Google Chrome)، عندما تتضمن الرسوم المتحركة عددًا كبيرًا جدًا من النقاط، لم يكن هناك تلاشي تدريجي للنص على الإطلاق، ولكن هذا يحدث فقط عند استخدام الرسوم المتحركة CSS!

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

    دعونا نأمل أن يتغير بالرغم من ذلك. ومع ذلك، في معظم مشاريع الحياة الواقعية، لن تلاحظ أبدًا الفرق في الأداء.

    أنا أشجعك على إجراء الاختبار الخاص بك لمعرفة التكنولوجيا التي ستوفر رسومًا متحركة سلسة في مشروعك (مشاريعك) المحددة.

    لا تصدق الأسطورة القائلة بأن الرسوم المتحركة لـ CSS تكون دائمًا أسرع، ولا تفترض أن اختبار السرعة أعلاه يعكس ما ستراه في تطبيقك. اختبار واختبار واختبار مرة أخرى.

    ضوابط التنفيذ والأحداث

    تسمح لك بعض المتصفحات بإيقاف الرسوم المتحركة أو إعادة تشغيلها باستخدام إطارات CSS الرئيسية، ولكن هذا كل ما في الأمر.

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

    من ناحية أخرى، تمنحك JavaScript قدرًا كبيرًا من التحكم، كما ترون في المثال أدناه.

    لغة البرمجة:

    غير ممكن مع الرسوم المتحركة CSS.
    سرعة:

    CSS:

    الجسم ( عائلة الخط: Signika Negative، sans-serif؛ وزن الخط: 300؛ اللون: أبيض؛ لون الخلفية: أسود؛ محاذاة النص: المركز؛) #demo ( محاذاة النص: المركز؛ الهامش العلوي: 20 بكسل ) #bg (لون الخلفية: #000؛ الموضع: نسبي؛ الفائض: مخفي؛ العرض: كتلة مضمنة؛ العرض: 500 بكسل؛ الارتفاع: 70 بكسل؛ نصف قطر الحدود: 8 بكسل؛ الحدود: 2 بكسل صلب #777؛) #text ( الموضع: مطلق؛ محاذاة النص: المركز؛ العرض: 500 بكسل؛ الارتفاع: 70 بكسل؛ ارتفاع الخط: 68 بكسل؛ حجم الخط: 28 بكسل؛) #textspan ( -webkit-font-smoothing: antialiased؛ -moz-font- التنعيم: الحواف؛ الموضع: العرض النسبي: كتلة مضمنة؛) #slider (العرض: كتلة مضمنة؛ العرض: 500 بكسل؛ الارتفاع: 12 بكسل؛ الهامش: 8 بكسل 0 بكسل 8 بكسل 6 بكسل؛) # زر التحكم: 80 بكسل؛ (العرض: مضمن؛ الحشو: 2 بكسل؛ الهامش: 2 بكسل؛)

    شبيبة:

    فار $text = $("#text")، $pause = $("#pause")، $reverse = $("#reverse")، $restart = $("#restart")، $speed = $( "input"))، $slider = $("#slider")، //"tl" هو المقياس الذي سنضيف إليه الرسوم المتحركة الخاصة بنا. // ثم يمكننا بسهولة التحكم في تسلسل الرسوم المتحركة بالكامل ككائن واحد. tl = new TimelineLite((onUpdate:updateSlider, onComplete:onComplete, onReverseComplete:onComplete, Pause:true)); وظيفة updateSlider() ( $slider.slider("value"، tl.progress() * 100); ) وظيفة onComplete() ( tl.pause(); $pause.html("play"); ) // افعل شيئًا تقسيم النص ببساطة حتى نتمكن من تطبيق الرسوم المتحركة على كل // حرف (لا تحتاج إلى وظائف SplitText المتقدمة، لذا استخدم فقط Split() و // join()) $text.html(" " + $text.html().split("").join("").split("").join("") + ""); // تعيين المنظور على الحاوية TweenLite.set($text, (المنظور:500)); // يتم إنشاء جميع الرسوم المتحركة في سطر واحد : tl staggerTo($("#textspan"), 4, (transformOrigin:"50% 50% -30px", RotationY:-360, RotationX:360, Rotation:360,easy:Elastic.easeInOut), 0.02) ; ) ; $pause.html("play" ) )); $pause.click(function() ( if (tl.paused()) ( if (tl.progress() === 1 || (tl.progress) () === 0 && tl.reversed())) ( tl.restart(); ) else ( tl.resume(); ) $pause.html("pause" ) else ( tl.pause(); $pause .html("resume"); $reverse.click(function() ( if (tl.progress() === 0) ( if (tl.reversed()) ( tl.play() ; ) else ( tl. عكسي(0); .click(function())( tl.restart(); $pause.html("pause"); )); $speed.change(function(v, val) ( tl.timeScale(parseFloat($(this).val())); if (tl.progress() === 1) ( tl.restart(); $pause .html("pause"); ) else if (tl.paused()) ( tl.resume(); $pause.html("pause"); ) ));

    الرسوم المتحركة الحديثة تدور حول التفاعل إلى حد كبير، لذلك من المفيد للغاية أن تكون قادرًا على التحريك من القيم الأولية القابلة للتغيير إلى القيم النهائية القابلة للتغيير (اعتمادًا على المكان الذي ينقر فيه المستخدم، على سبيل المثال) أو تغيير شيء ما بسرعة، ولكن الرسوم المتحركة التعريفية تلك المستندة إلى CSS لا تسمح لك بالقيام بذلك.

    عملية العمل

    بالنسبة للانتقالات البسيطة بين حالتين (على سبيل المثال، قلب القائمة أو توسيعها، وما إلى ذلك) تعتبر تحويلات CSS رائعة.

    ومع ذلك، بالنسبة لتسلسل الأحداث، ستحتاج عادةً إلى استخدام رسوم CSS المتحركة مع الإطارات الرئيسية، الأمر الذي سيتطلب محددات النسبة المئوية، على سبيل المثال:

    CSS:

    @keyframes myAnimation ( 0% ( العتامة: 0; تحويل: ترجمة (0, 0); ) 30% ( العتامة: 1; تحويل: ترجمة (0, 0); ) 60% ( تحويل: ترجمة (100px, 0); ) 100% ( تحويل: ترجمة (100 بكسل، 100 بكسل)؛ ) ) #box ( الرسوم المتحركة: myAnimation 2.75s; )

    ولكن عندما تقوم بإنشاء رسم متحرك، ألا تركز على الفواصل الزمنية بدلاً من النسب المئوية؟ على سبيل المثال، " قم بزيادة الشفافية لمدة ثانية واحدة، ثم حرك إلى اليمين لمدة 0.75 ثانية، ثم اقفز لأسفل للثانية المتبقية».

    ماذا يحدث إذا قضيت ساعات في حساب تسلسل معقد من النسب المئوية، ثم قال العميل: " اجعل هذا الجزء في المنتصف أطول بثلاث ثوانٍ"؟ آه، سيكون عليك إعادة حساب جميع النسب المئوية!

    عادة، يتطلب إنشاء الرسوم المتحركة الكثير من التجارب، خاصة فيما يتعلق بوظائف التوقيت والتخفيف.

    يكون هذا مناسبًا عندما تكون طريقة البحث () مفيدة جدًا. تخيل إنشاء رسم متحرك مدته 60 ثانية قطعة قطعة ثم شحذها في الثواني الخمس الأخيرة: سيتعين عليك الجلوس خلال أول 55 ثانية في كل مرة تريد فيها رؤية نتيجة تعديلاتك في الأجزاء النهائية.

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

    أصبح إنشاء رسوم متحركة للكائنات المستندة إلى لوحة الرسم وكائنات مكتبة الطرف الثالث الأخرى منتشرًا على نطاق واسع، ولكن لسوء الحظ، فإن رسوم CSS المتحركة مخصصة فقط لعناصر DOM.

    هذا يعني أنه إذا استثمرت الكثير من الوقت والطاقة في رسوم CSS المتحركة، فلن تكون قابلة للتحويل إلى أنواع أخرى من المشاريع.

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

    هناك عدد قليل من الأدوات المفيدة الأخرى المتعلقة بسير العمل والتي لا تتضمنها الرسوم المتحركة لـ CSS:

    • القيم النسبية. على سبيل المثال، " بدوره 30 درجة أكثر" أو " حرك العنصر لأسفل بمقدار 100 بكسل من مكانه عند بدء الحركة»;
    • التعشيش. تخيل أنك قادر على إنشاء رسوم متحركة يمكن دمجها داخل رسم متحرك آخر، والذي يمكن أن يكون متداخلاً في حد ذاته، وما إلى ذلك. تخيل أنك تتحكم في الرسوم المتحركة الرئيسية بينما يظل كل شيء آخر متزامنًا تمامًا. مثل هذا الهيكل من شأنه أن يشجع التعليمات البرمجية المعيارية التي يكون إنشاؤها والمحافظة عليها أسهل بكثير؛
    • تقرير التطور. هل الرسوم المتحركة معينة كاملة؟ إذا لم يكن الأمر كذلك، ما هي مرحلة التنفيذ بالضبط؟
    • عمليات الإزالة المستهدفة. في بعض الأحيان يكون من المفيد للغاية تعطيل جميع الحركات التي تؤثر على مقياس عنصر ما (أو أي خاصية أخرى تريدها) مع السماح لجميع الحركات الأخرى؛
    • رمز قصير. تعتبر الرسوم المتحركة CSS المستندة إلى الإطار الرئيسي مطولة، حتى بدون الحاجة إلى جميع الإصدارات المتكررة التي يسبقها البائع. أي شخص حاول إنشاء أي شيء حتى ولو كان متوسط ​​التعقيد سيشهد على حقيقة أن الرسوم المتحركة لـ CSS سرعان ما تصبح غير عملية ومبتذلة. في الواقع، قد يتجاوز المقدار الفعلي لرموز CSS المطلوبة لتنفيذ مهام الرسوم المتحركة وزن مكتبة JavaScript (والتي يسهل تخزينها مؤقتًا وإعادة استخدامها عبر العديد من الرسوم المتحركة).

    تأثيرات محدودة

    لن تتمكن من القيام بأي مما يلي باستخدام الرسوم المتحركة لـ CSS:

    • الرسوم المتحركة على طول منحنى (على سبيل المثال، منحنى Bezier)؛
    • استخدم وظائف تليين مثيرة للاهتمام مثل التليين المرن أو النابض أو الخشن. يوجد خيار cube-bezier()، لكنه يسمح فقط بنقطتين رئيسيتين، وهو أمر مقيد للغاية؛
    • الحركات وفقا للقوانين الفيزيائية. على سبيل المثال، الحركة السلسة القائمة على القصور الذاتي وسهولة العودة إلى الخلف، والتي تم تنفيذها في هذا العرض التوضيحي القابل للسحب؛
    • انتقل الرسوم المتحركة الموقف.
    • الدوران الاتجاهي (على سبيل المثال، " تدوير بالضبط 270 درجة في أقصر اتجاه، في اتجاه عقارب الساعة أو عكس اتجاه عقارب الساعة»);
    • سمة الرسوم المتحركة.

    التوافق

    لا تعمل الرسوم المتحركة المستندة إلى CSS في IE9 والإصدارات الأقدم من المتصفح. يكره معظمنا تقديم الدعم للمتصفحات القديمة (خاصة IE)، ولكن الحقيقة هي أن البعض منا لديه عملاء يحتاجون إلى ذلك.

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

    خاتمة

    هل الرسوم المتحركة CSS سيئة؟ بالطبع لا. في الواقع، فهي رائعة بالنسبة لانتقالات الحالة البسيطة (مثل التقليب) حيث لا يلزم التوافق مع المتصفحات القديمة.

    تتمتع التحويلات ثلاثية الأبعاد عمومًا بأداء جيد (يعد iOS7 استثناءً ملحوظًا) ويمكن أن تكون الرسوم المتحركة CSS جذابة جدًا للمطورين الذين يفضلون وضع كل الرسوم المتحركة ومنطق العرض التقديمي في طبقة CSS.

    ومع ذلك، توفر الرسوم المتحركة المستندة إلى JavaScript مرونة أكبر بكثير، وعملية تطوير أكثر راحة للرسوم المتحركة المعقدة، والتفاعل الغني، وغالبًا ما تكون الرسوم المتحركة المستندة إلى JavaScript سريعة (أو حتى أسرع) من الرسوم المتحركة المستندة إلى CSS، على الرغم من أنك قد تكون لديك سمع.

    أستطيع أن أرى لماذا كانت الرسوم المتحركة CSS جذابة للغاية مقارنة بـ jQuery.animate() . من منا بكامل قواه العقلية لن يغتنم الفرصة للحصول على زيادة في الإنتاجية بمقدار 10 أضعاف؟

    لم تعد هناك حاجة للاختيار بين الرسوم المتحركة jQuery وCSS؛ فالأدوات المستندة إلى JavaScript مثل GSAP تفتح إمكانيات جديدة تمامًا وتسد فجوة الأداء.

    هذه المقالة لا تتعلق بـ GSAP أو أي مكتبة محددة؛ المغزى من هذه المقالة هو أن الرسوم المتحركة المبنية على جافا سكريبت لا تستحق السمعة السيئة. في الواقع، JavaScript هو الخيار الوحيد لنظام رسوم متحركة قوي ومرن حقًا.

    بالإضافة إلى ذلك، أردت إلقاء بعض الضوء على بعض الجوانب المحبطة للرسوم المتحركة CSS (التي لم يتحدث عنها أحد) حتى تتمكن الآن من اتخاذ قرارات أكثر استنارة حول كيفية إنشاء الرسوم المتحركة.

    هل ستحل مواصفات الرسوم المتحركة على الويب المشكلات الحالية؟

    تعمل W3C على مواصفات جديدة تسمى "رسوم الويب المتحركة" والتي تهدف إلى معالجة العديد من أوجه القصور في الرسوم المتحركة والتحويلات في CSS، مما يوفر تحكمًا أفضل في التنفيذ ووظائف إضافية.

    بالطبع، يبدو هذا بمثابة خطوة إلى الأمام في كثير من النواحي، ولكن لا يزال هناك عدد من أوجه القصور (بعضها ربما يكون من المستحيل التغلب عليه بسبب الحاجة إلى دعم الإصدارات الأقدم من مواصفات CSS الموجودة، لذلك، على سبيل المثال، التحكم المستقل من مكونات التحويل غير محتمل).

    على الرغم من أن هذه قصة مختلفة تمامًا. علينا أن ننتظر ونرى كيف ستسير الأمور. هناك بالتأكيد رجال أذكياء يعملون على هذه المواصفات.

    هذا المنشور هو ترجمة للمقال " خرق الأسطورة: الرسوم المتحركة CSS مقابل الرسوم المتحركة جافا سكريبت"، من إعداد فريق المشروع الصديق

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

    استخدام تأثيرات الرسوم المتحركة المختلفة(الانتقالات، الحركات، التحولات، وما إلى ذلك) تعمل على "تنشيط" موقع الويب بشكل كبير، وتسمح لك بالتحكم في انتباه المستخدم، وتحويله إلى العنصر المطلوب وإعطاء إشارات مرئية معينة.

    عند الحديث عن الرسوم المتحركة، لا يسع المرء إلا أن يذكر المبادئ الـ 12 المعروفة التي صاغها رسامي الرسوم المتحركة في استوديو ديزني، والتي يعد استخدامها مهمًا للغاية للاستخدام المعقول والعالي الجودة لتأثيرات الرسوم المتحركة.

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

    Dynamics.js

    ربما سأبدأ ب Dynamics.js. هذه مكتبة جادة وقوية تسمح لك بإنشاء رسوم متحركة واقعية ماديًا (مثل التذبذبات التوافقية المخمدة لنقطة ما على الصفحة الرئيسية لموقع الويب). المكتبة قادرة على إدارة خصائص أي عنصر DOM. يتم استخدام Dynamics.js لإنشاء القوائم والأزرار ومؤشرات العملية والعلامات. في هذه الحالة، تتوفر مجموعة واسعة من المعلمات، مثل التردد، وتقليل التخميد، والمعلمات التي تميز المرونة أو مدة العملية، وما إلى ذلك.

    Cta.js

    صغير الحجم مكتبة cta.jsمنوي لإنشاء تأثيرات الرسوم المتحركة على الصفحةنوع "تأثير الفعل"، أي. يؤدي تحريك مؤشر الماوس أو النقر فوقه فوق كائن إلى الحصول على تأثير محدد. إنه مناسب جدًا للاستخدام عند تطوير واجهات مبلطة، عندما يؤدي النقر فوق عنصر إلى فتحه كنافذة مشروطة، أو على الصفحة بأكملها، أو كلوحة شريحة جانبية.

    Beep.js

    مكتبة مثيرة للاهتمام تستخدم WebAudio API لإنشاء مركب موسيقى على الصفحة. يمكن استخدامها في تطوير كتاب مدرسي للموسيقى عبر الإنترنت أو كلعبة ممتعة.

    Rainyday.js

    تأثير المطر جميل بشكل لا يصدق مع قطرات بأحجام مختلفة تتدفق للأسفل. ومع ذلك، في رأيي، قطرات كبيرة تفتقر إلى الواقعية (ربما نفس الفيزياء الموجودة في Dynamics.js؟). ومع ذلك، تسمح لك واجهة برمجة التطبيقات (API) الحالية بإنشاء كائناتك الخاصة والتحكم في سلوكها، مما يؤدي إلى إنشاء المزيد من التأثيرات المذهلة.

    Dom-Animator.js

    Dom-Animator.js هو ما يسمى "بيضة عيد الفصح". وتأثيرها لا يرى بالعين المجردة، أي. لأولئك الذين يشاهدون الصفحة في نافذة متصفح عادية. ولكن أولئك الذين يقومون بتحليل الكود الخاص بك سوف يرونه في وحدة التحكم (إذا كنت لا تزال لا تفهم ما نتحدث عنه، فهناك مقطع فيديو هنا سيجعل كل شيء واضحًا).

    مشهور

    مشهور - يحركه الحدث مكتبة JS لإنشاء الرسوم المتحركة الحديثة. يحتوي على نواة هندسية قوية تسمح لك بمعالجة الكائنات ثلاثية الأبعاد المختلفة - النقطية والحجمية - وتطبيق القوى والتسارع عليها وفرض القيود والتحكم في الاصطدامات.

    ترتد.js

    ليس سيئًا مكتبة جافا سكريبت لإنشاء رسوم متحركة رائعةباستخدام CSS. يتيح لك تطبيق أنواع مختلفة من الحركة والتدوير والقياس والتحويل على الكائنات.

    سنابت.js

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

    ريكابي

    يتيح لك Rekapi استخدام كليهما الرسوم المتحركة للإطار الرئيسي CSS(قاعدة @keyframes) ورسوم DOM المتحركة باستخدام JavaScript. تتيح لك هذه المكتبة إنشاء كائنات ديناميكية معقدة للغاية، مثل المخططات الدائرية والخطية والجداول الزمنية وعناصر واجهة المستخدم الأخرى.

    داهية

    Shifty هي مكتبة تحتوي على كل ما تحتاجه لإكماله الرسوم المتحركة الإطار الرئيسي(ما يسمى بـ "التوأمة")، ويمكن أن يكون عدد الأشياء هائلاً بكل بساطة. إنها مكتبة منخفضة المستوى يمكن استخدامها كنواة للمنصات أو المكتبات ذات المستوى الأعلى. في الواقع، يتم استخدام Shifty باعتباره جوهر Rekapi المذكور أعلاه.