تحريك مكونات React باستخدام GreenSock

نشرت: 2022-03-10
ملخص سريع ↬ GreenSock Animation Platform (GSAP) هي مجموعة من وظائف JavaScript التي تتيح لك دمج قيمة / سمة / خاصية CSS بمرور الوقت وإدراج هؤلاء المراهقات في مخطط زمني لرسوم متحركة أكثر تعقيدًا. في هذه المقالة ، يشرح Blessing كيف يعمل GSAP بشكل جيد مع مكتبة React من خلال دمج وظائفها في مكون React في بناء نموذج صفحة مقصودة مع مجموعة متنوعة من الرسوم المتحركة.

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

ومع ذلك ، في حالة عدم القيام بذلك بشكل صحيح ، يمكن أن تعيق الرسوم المتحركة تفاعلات المستخدم مع منتجك وتؤثر سلبًا على الجر. تعد GreenSock Animation Platform AKA (GSAP) مكتبة جافا سكريبت قوية تمكن مطوري الواجهة الأمامية ورسامي الرسوم المتحركة والمصممين من إنشاء رسوم متحركة فعالة قائمة على الخط الزمني. يسمح لعشاق الرسوم المتحركة بالتحكم الدقيق في تسلسلات الرسوم المتحركة الخاصة بهم بدلاً من keyframe المقيدة أحيانًا وخصائص animation التي توفرها CSS.

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

ستكون هذه المقالة مفيدة لك إذا:

  • لقد قمت بإنشاء رسوم متحركة على تطبيقات الويب باستخدام HTML و CSS و JavaScript.
  • أنت تقوم بالفعل بإنشاء صفحات ويب متحركة في تطبيقات React مع حزم مثل animate.css و React-motion و Framer-motion و React-Spring ، بالإضافة إلى أنك تريد التحقق من البدائل.
  • أنت متحمس لـ React ، وترغب في إنشاء رسوم متحركة معقدة على تطبيقات الويب القائمة على React.

سننظر في كيفية إنشاء مجموعة متنوعة من الرسوم المتحركة من مشروع ويب موجود. دعنا نذهب اليها!

ملاحظة : تفترض هذه المقالة أنك مرتاح لاستخدام HTML و CSS و JavaScript و React.js.

ما هو GSAP؟

منصة GreenSock Animation Platform المعروفة أيضًا باسم GSAP عبارة عن رسوم متحركة فائقة الأداء وذات درجة احترافية للويب الحديث تسمح للمطورين بتحريك تطبيقاتهم بطريقة معيارية وتوضيحية وقابلة لإعادة الاستخدام. إنه غير محدد الإطار ويمكن استخدامه عبر أي مشروع قائم على JavaScript ، وله حجم حزمة ضئيل للغاية ولن يؤدي إلى تضخيم تطبيقك.

يمكن لـ GSAP تنفيذ رسوم متحركة للوحة ، تُستخدم لإنشاء تجارب WebGL ، وإنشاء رسوم متحركة SVG ديناميكية ودعم متصفح رائع.

المزيد بعد القفز! أكمل القراءة أدناه ↓

لماذا نستخدم GSAP؟

ربما لم تكن مستعدًا تمامًا لخيانة الأطر الأخرى بعد ، أو لم تكن مقتنعًا باحتضان الأشياء الجيدة التي تأتي مع GSAP. اسمح لي أن أقدم لك بعض الأسباب التي تجعلك ترغب في التفكير في GSAP.

يمكنك إنشاء رسوم متحركة معقدة

تتيح مكتبة GSAP JavaScript للمطورين إنشاء رسوم متحركة بسيطة إلى معقدة للغاية قائمة على الفيزياء كما في حالة هذه المواقع ، فهي تتيح للمطورين والمصممين تسلسل الحركة والتحكم في الرسوم المتحركة ديناميكيًا. يحتوي على الكثير من المكونات الإضافية مثل DrawSVGPlugin و MorphSVGPlugin والمزيد ، مما يجعل إنشاء رسوم متحركة مبنية على SVG ورسوم متحركة ثنائية / ثلاثية الأبعاد حقيقة واقعة. إلى جانب دمج GSAP في عناصر DOM ، يمكنك استخدامها في الرسوم المتحركة المستندة إلى السياق WebGL / Canvas / Three.js.

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

أداء

يتميز GSAP بأداء عالٍ مذهل عبر المتصفحات المختلفة.

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

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

يمكنك التحقق من المزيد من الفوائد على GSAP أو الاطلاع على ما تقوله Sarah Drasner عنها هنا.

سلبيات GSAP

هل تقول أنه يجب علي دائمًا استخدام GSAP لكل مشروع؟ بالطبع لا! أشعر أن هناك سببًا واحدًا قد يجعلك لا ترغب في استخدام GSAP. هيا نكتشف!

  • GSAP هي مكتبة رسوم متحركة تعتمد على JavaScript فقط ، ومن ثم فهي تتطلب بعض المعرفة بمعالجة JavaScript و DOM للاستفادة الفعالة من أساليبها وواجهات برمجة التطبيقات. يترك الجانب السلبي لمنحنى التعلم مجالًا أكبر للمضاعفات للمبتدئين الذين يبدأون باستخدام JavaScript.
  • لا يلبي GSAP الرسوم المتحركة المستندة إلى CSS ، وبالتالي إذا كنت تبحث عن مكتبة لمثل هذا ، فيمكنك أيضًا استخدام keyframes في الرسوم المتحركة لـ CSS.

إذا كان لديك أي سبب آخر ، فلا تتردد في مشاركته في قسم التعليقات.

حسنًا ، الآن بعد أن تم حل شكوكك ، دعنا ننتقل إلى بعض التفاصيل الدقيقة في GSAP.

أساسيات GSAP

قبل إنشاء الرسوم المتحركة الخاصة بنا باستخدام React ، دعنا نتعرف على بعض الأساليب والكتل الأساسية لـ GSAP.

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

توين

توين هو حركة واحدة في الرسوم المتحركة. في GSAP ، يحتوي tween على البنية التالية:

 TweenMax.method(element, duration, vars)

دعونا نلقي نظرة على ما يمثله هذا النحو ؛

  1. تشير method إلى طريقة GSAP التي ترغب في استخدامها.
  2. element هو العنصر الذي تريد تحريكه. إذا كنت تريد إنشاء مراهقات لعناصر متعددة في نفس الوقت ، يمكنك تمرير مجموعة من العناصر إلى element .
  3. duration هي مدة توينك. إنه عدد صحيح بالثواني (بدون اللاحقة s !).
  4. vars هو كائن من الخصائص التي تريد تحريكها. المزيد عن هذا لاحقًا.

طرق GSAP

يوفر GSAP طرقًا عديدة لإنشاء الرسوم المتحركة. في هذه المقالة ، نذكر القليل فقط مثل gsap.to ، gsap.from ، gsap.fromTo . يمكنك التحقق من طرق أخرى رائعة في وثائقهم. سيتم استخدام الطرق التي تمت مناقشتها في هذا القسم في بناء مشروعنا لاحقًا في هذا البرنامج التعليمي.

  • gsap.to() القيم التي يجب تحريك الكائن إليها ، مثل قيم خاصية النهاية لكائن متحرك - كما هو موضح أدناه:
     gsap.to('.ball', {x:250, duration: 5})

لإثبات طريقة to ، يوضح العرض التوضيحي لملف الشفرة أدناه أن عنصرًا بفئة كرة 250px سيتحرك عبر x-axis في خمس ثوانٍ عند تركيب المكونات. إذا لم يتم تحديد المدة ، فسيتم استخدام الافتراضي 500 مللي ثانية.

راجع القلم [GSAP REACT DEMO1] (https://codepen.io/smashingmag/pen/LYNrzMB) بواسطة Blessing Krofegha.

شاهد Pen GSAP REACT DEMO1 بواسطة Blessing Krofegha.

ملاحظة : يمثل المحور x و y-axis الأفقي والعمودي على التوالي ، وأيضًا في خصائص تحويل CSS مثل translateX و translateY يتم تمثيلهما على أنهما x و y للتحويلات pixel-measured بالبكسل و xPercent و yPercent على النسبة المئوية.

لعرض مقتطف الكود الكامل ، تحقق من ملعب الرمز.

  • gsap.from() - يحدد القيم التي يجب تحريك الكائن منها - على سبيل المثال ، قيم البداية للرسوم المتحركة:
     gsap.from('.square', {duration:3, scale: 4})

يُظهر العرض التوضيحي لـ codepen كيف يتم تغيير حجم عنصر بفئة square من مقياس 4 في 3 3seconds عند تركيب المكونات. تحقق من وجود مقتطف الشفرة الكامل في هذا الرمز.

راجع القلم [GSAP REACT DEMO2] (https://codepen.io/smashingmag/pen/bGpKoPV) بواسطة Blessing Krofegha.

شاهد Pen GSAP REACT DEMO2 بواسطة Blessing Krofegha.
  • gsap.fromTo() - يتيح لك تحديد قيم البداية والنهاية للرسوم المتحركة. وهي عبارة عن مزيج من الطريقة from() to() .

هنا كيف يبدو.

 gsap.fromTo('.ball',{opacity:0 }, {opacity: 1 , x: 200 , duration: 3 }); gsap.fromTo('.square', {opacity:0, x:200}, { opacity:1, x: 1 , duration: 3 });

هذا الرمز يحرك العنصر بفئة ball من عتامة 0 إلى عتامة 1 عبر x-axis في 3 seconds ويتم تحريك فئة square من عتامة من 0 إلى 1 في 3 seconds عبر x-axis فقط عندما يتصاعد المكون. لمعرفة كيفية عمل طريقة fromTo الشفرة الكامل ، تحقق من العرض التوضيحي على CodePen أدناه.

راجع القلم [React GSAP FromTo demo] (https://codepen.io/smashingmag/pen/WNwyXex) بواسطة Blessing Krofegha.

انظر Pen React GSAP FromTo demo by Blessing Krofegha.

ملاحظة : عندما نقوم بتحريك الخصائص الموضعية ، مثل left top ، يجب أن نتأكد من أن العناصر المعنية يجب أن تحتوي على خاصية موضع CSS إما relative أو absolute أو fixed .

التخفيف

حددت وثائق GSAP الرسمية التخفيف كطريقة أساسية لتغيير توقيت المراهقين. يحدد كيف يغير الكائن موضعه في نقاط مختلفة. يتحكم Ease في معدل تغيير الرسوم المتحركة في GSAP ويستخدم لتعيين نمط الرسوم المتحركة للكائن.

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

هناك ثلاثة أنواع من التسهيلات ، وهي تختلف في عملياتها.

  1. in() - تبدأ الحركة ببطء ، ثم تلتقط السرعة في نهاية الرسم المتحرك.
  2. out() - يبدأ الرسم المتحرك بسرعة ثم يتباطأ في نهاية الرسم المتحرك.
  3. inOut() - يبدأ الرسم المتحرك ببطء ، ويزيد من السرعة في منتصف الطريق وينتهي ببطء.

راجع عرض Pen [React GSAP Easing demo] (https://codepen.io/smashingmag/pen/abNKLaE) بواسطة Blessing Krofegha.

شاهد العرض التوضيحي للتخفيف من Pen React GSAP بواسطة Blessing Krofegha.

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

الجداول الزمنية

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

يمكن كتابة المخططات الزمنية عن طريق إنشاء مثيل لجدول زمني مثل:

 gsap.timeline();

يمكنك أيضًا ربط عدة مراهقات بجدول زمني بطريقتين مختلفتين ، في الكود أدناه:

 ##Method 1 const tl = gsap.timeline(); // create an instance and assign it a variable tl.add(); // add tween to timeline tl.to('element', {}); tl.from('element', {}); ##Method 2 gsap.timeline() .add() // add tween to timeline .to('element', {}) .from('element', {})

دعنا نعيد إنشاء المثال السابق بخط زمني:

 const { useRef, useEffect } = React; const Balls = () => { useEffect(() => { const tl = gsap.timeline(); tl.to('#ball1', {x:1000, ease:"bounce.in", duration: 3}) tl.to('#ball2', {x:1000, ease:"bounce.out", duration: 3, delay:3 }) tl.to('#ball3', {x:1000, ease:"bounce.inOut", duration: 3, delay:6 }) }, []); } ReactDOM.render( , document.getElementById('app')); const { useRef, useEffect } = React; const Balls = () => { useEffect(() => { const tl = gsap.timeline(); tl.to('#ball1', {x:1000, ease:"bounce.in", duration: 3}) tl.to('#ball2', {x:1000, ease:"bounce.out", duration: 3, delay:3 }) tl.to('#ball3', {x:1000, ease:"bounce.inOut", duration: 3, delay:6 }) }, []); } ReactDOM.render( , document.getElementById('app'));

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

راجع عرض Pen [React GSAP (Easing with Timeline) demo] (https://codepen.io/smashingmag/pen/zYqaEmE) بواسطة Blessing Krofegha.

شاهد العرض التوضيحي لـ Pen React GSAP (التيسير مع الجدول الزمني) بواسطة Blessing Krofegha.

الآن بعد أن تعرفنا على بعض اللبنات الأساسية لـ GSAP ، دعنا نرى كيف يمكننا إنشاء رسم متحرك كامل في تطبيق React نموذجي في القسم التالي. لنبدأ الرحلة!

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

دعنا نحرك تطبيق React. تأكد من استنساخ الريبو قبل أن تبدأ وتشغيل npm install من أجل تثبيت التبعيات.

ماذا نبني؟

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

  • حرك النص والشعار على الصفحة الرئيسية ، بحيث يخفف عند تركيب المكون.
  • حرك القائمة ، بحيث تنخفض لأسفل عند النقر فوق القائمة.
  • اجعل الصور في صفحة المعرض 20deg عند تمرير الصفحة.
صفحة متحركة
صفحة متحركة.

تحقق من العرض على codeandbox.

سنقسم عملية الصفحة المقصودة إلى مكونات ، لذلك سيكون من السهل فهمها. ها هي العملية.

  • تحديد طرق الرسوم المتحركة ،
  • تحريك النص والشعار ،
  • تبديل القائمة ،
  • اجعل الصور 20deg عند تمرير الصفحة.

عناصر

  • Animate.js - تم تحديد جميع طرق الرسوم المتحركة ،
  • Image.js - استيراد صور لوح المطبخ ،
  • Menu.js - يحتوي على وظيفة تبديل القائمة ،
  • Header.js - يحتوي على روابط تنقل.

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

قم بإنشاء مجلد component داخل دليل src ، وأنشئ ملف animate.js . انسخ والصق الكود التالي فيه.

 import gsap from "gsap" import { ScrollTrigger } from "gsap/ScrollTrigger"; //Animate text export const textIntro = elem => { gsap.from(elem, { xPercent: -20, opacity: 0, stagger: 0.2, duration: 2, scale: -1, ease: "back", }); };

هنا ، قمنا باستيراد gsap . كتبنا وظيفة سهم مُصدَّر تعمل على تحريك النص في الصفحة المقصودة. تذكر أن طريقة gsap.from() تحدد القيم التي يجب تحريك الكائن منها. تحتوي الوظيفة على معلمة elem تمثل الفئة التي يجب أن تكون متحركة. يأخذ بعض الخصائص ويعين قيمًا مثل xPercent: -20 (يحول الكائن بنسبة -20٪) ، ولا يعطي الكائن أي عتامة ، ويجعل scale الكائن بمقدار -1 ، ويجعل الكائن ease في 2sec .

لمعرفة ما إذا كان هذا يعمل ، توجه إلى App.js وقم بتضمين الكود التالي.

 ... //import textIntro import {textIntro} from "./components/Animate" ... //using useRef hook to access the textIntro DOM let intro = useRef(null) useEffect(() => { textIntro(intro) }, []) function Home() { return ( <div className='container'> <div className='wrapper'> <h5 className="intro" ref={(el) => (intro = el)}></h5> The <b>SHOPPER</b>, is a worldclass, innovative, global online ecommerce platform, that meets your everyday daily needs. </h5> </div> </div> ); }

هنا ، نقوم باستيراد طريقة textIntro من المكون Aminate . للوصول إلى DOM اعتدنا على useRef Hook. أنشأنا intro متغير تم ضبط قيمتها على قيمة null . بعد ذلك ، داخل الخطاف useEffect ، أطلقنا على طريقة textIntro ومتغير intro . داخل المكون الرئيسي لدينا ، في علامة h5 ، حددنا الخاصية ref وقمنا بتمريرها في متغير intro .

نص متحرك.
نص متحرك.

بعد ذلك ، لدينا قائمة ، لكنها لا تنخفض عند النقر عليها. دعونا نجعلها تعمل! داخل مكون Header.js ، أضف الكود أدناه.

 import React, { useState, useEffect, useRef } from "react"; import { withRouter, Link, useHistory } from "react-router-dom"; import Menu from "./Menu"; const Header = () => { const history = useHistory() let logo = useRef(null); //State of our Menu const [state, setState] = useState({ initial: false, clicked: null, menuName: "Menu", }); // State of our button const [disabled, setDisabled] = useState(false); //When the component mounts useEffect(() => { textIntro(logo); //Listening for page changes. history.listen(() => { setState({ clicked: false, menuName: "Menu" }); }); }, [history]); //toggle menu const toggleMenu = () => { disableMenu(); if (state.initial === false) { setState({ initial: null, clicked: true, menuName: "Close", }); } else if (state.clicked === true) { setState({ clicked: !state.clicked, menuName: "Menu", }); } else if (state.clicked === false) { setState({ clicked: !state.clicked, menuName: "Close", }); } }; // check if out button is disabled const disableMenu = () => { setDisabled(!disabled); setTimeout(() => { setDisabled(false); }, 1200); }; return ( <header> <div className="container"> <div className="wrapper"> <div className="inner-header"> <div className="logo" ref={(el) => (logo = el)}> <Link to="/">SHOPPER.</Link> </div> <div className="menu"> <button disabled={disabled} onClick={toggleMenu}> {state.menuName} </button> </div> </div> </div> </div> <Menu state={state} /> </header> ); }; export default withRouter(Header);

في هذا المكون ، حددنا القائمة وحالة الزر ، داخل الخطاف useEffect ، استمعنا إلى تغييرات الصفحة باستخدام الخطاف useHistory ، إذا تغيرت الصفحة ، فقمنا بتعيين قيم الحالة التي تم clicked و menuName على false و Menu على التوالي.

للتعامل مع قائمتنا ، تحققنا مما إذا كانت قيمة حالتنا الأولية خاطئة ، وإذا كانت صحيحة ، نقوم بتغيير القيمة initial ، clicked ، و menuName إلى null ، و true ، و Close . وإلا فإننا نتحقق مما إذا كان الزر قد تم النقر عليه ، وإذا كان صحيحًا menuName بتغيير اسم القائمة إلى Menu . بعد ذلك ، لدينا وظيفة " disabledMenu " التي تعطل الزر الخاص بنا لمدة 1sec واحدة عند النقر فوقه.

أخيرًا ، في زرنا ، قمنا بتعيين disabled إلى " disabled " وهي قيمة منطقية ستعمل على تعطيل button عندما تكون قيمته true . ويكون معالج onClick للزر مرتبطًا بوظيفة toggleMenu . كل ما فعلناه هنا هو تبديل نص menu ومرر الحالة إلى مكون Menu ، والذي سننشئه قريبًا. دعنا نكتب الطرق التي ستجعل القائمة المنسدلة لدينا قبل إنشاء مكون Menu الفعلي. توجه إلى Animate.js والصق هذا الرمز فيه.

 .... //Open menu export const menuShow = (elem1, elem2) => { gsap.from([elem1, elem2], { duration: 0.7, height: 0, transformOrigin: "right top", skewY: 2, ease: "power4.inOut", stagger: { amount: 0.2, }, }); }; //Close menu export const menuHide = (elem1, elem2) => { gsap.to([elem1, elem2], { duration: 0.8, height: 0, ease: "power4.inOut", stagger: { amount: 0.07, }, }); };

هنا ، لدينا وظيفة تسمى menuShow ، والتي تحرف القائمة أفقيًا بمقدار 2 درجة ، وتسهل القائمة ، 2degrees الرسوم المتحركة باستخدام خاصية stagger ، وتحول القائمة من right to top في 0.7sec ، نفس الخصائص تذهب إلى menuHide وظيفة. لاستخدام هذه الوظائف ، قم بإنشاء ملف Menu.js داخل components ولصق هذا الرمز فيه.

 import React, {useEffect, useRef} from 'react' import { gsap } from "gsap" import { Link } from "react-router-dom" import { menuShow, menuHide, textIntro, } from './Animate' const Menu = ({ state }) => { //create refs for our DOM elements let menuWrapper = useRef(null) let show1 = useRef(null) let show2 = useRef(null) let info = useRef(null) useEffect(() => { // If the menu is open and we click the menu button to close it. if (state.clicked === false) { // If menu is closed and we want to open it. menuHide(show2, show1); // Set menu to display none gsap.to(menuWrapper, { duration: 1, css: { display: "none" } }); } else if ( state.clicked === true || (state.clicked === true && state.initial === null) ) { // Set menu to display block gsap.to(menuWrapper, { duration: 0, css: { display: "block" } }); //Allow menu to have height of 100% gsap.to([show1, show2], { duration: 0, opacity: 1, height: "100%" }); menuShow(show1, show2); textIntro(info); } }, [state]) return ( <div ref={(el) => (menuWrapper = el)} className="hamburger-menu"> <div ref={(el) => (show1 = el)} className="menu-secondary-background-color" ></div> <div ref={(el) => (show2 = el)} className="menu-layer"> <div className="container"> <div className="wrapper"> <div className="menu-links"> <nav> <ul> <li> <Link ref={(el) => (line1 = el)} to="/about-us" > About </Link> </li> <li> <Link ref={(el) => (line2 = el)} to="/gallery" > Gallery </Link> </li> <li> <Link ref={(el) => (line3 = el)} to="/contact-us" > Contact us </Link> </li> </ul> </nav> <div ref={(el) => (info = el)} className="info"> <h3>Our Vision</h3> <p> Lorem ipsum dolor sit amet consectetur adipisicing elit.... </p> </div> </div> </div> </div> </div> </div> ); } export default Menu

ما فعلناه في مكون Menu هو استيراد الوظائف المتحركة ، وهي menuShow ، و menuHide ، و textIntro . بعد ذلك ، قمنا بتعيين متغيرات لكل refs تم إنشاؤه لعناصر DOM الخاصة بنا باستخدام الخطاف useRef وتمرير القيمة null كقيم لها. داخل خطاف useEffect ، نتحقق من حالة menu ، إذا تم clicked فوق false ، فإننا نسمي وظيفة menuHide ، وإلا ، إذا كانت الحالة التي تم clicked صحيحة ، فإننا نسمي وظيفة menuShow . أخيرًا ، تأكدنا من تمرير عناصر DOM المعنية refs المحددة وهي menuWrapper و show1 و show2 . مع ذلك ، لدينا قائمة متحركة لدينا.

دعونا نرى كيف يبدو.

قائمة متحركة.
قائمة متحركة.

آخر الرسوم المتحركة التي ننفذها هي جعل صورنا في معرضنا skew عند التمرير. دعونا نرى حالة معرضنا الآن.

معرض بدون رسوم متحركة.
معرض بدون رسوم متحركة.

لتنفيذ الرسوم المتحركة المنحرفة في معرضنا ، دعنا ننتقل إلى Animate.js ونضيف بعض الرموز إليها.

 .... //Skew gallery Images export const skewGallery = elem1 => { //register ScrollTrigger gsap.registerPlugin(ScrollTrigger); // make the right edge "stick" to the scroll bar. force3D: true improves performance gsap.set(elem1, { transformOrigin: "right center", force3D: true }); let clamp = gsap.utils.clamp(-20, 20) // don't let the skew go beyond 20 degrees. ScrollTrigger.create({ trigger: elem1, onUpdate: (self) => { const velocity = clamp(Math.round(self.getVelocity() / 300)); gsap.to(elem1, { skew: 0, skewY: velocity, ease: "power3", duration: 0.8, }); }, }); }

أنشأنا وظيفة تسمى skewGallery ، ومررنا elem1 ، ScrollTrigger .

ScrollTrigger هو مكون إضافي في GSAP يمكّننا من تشغيل الرسوم المتحركة القائمة على التمرير ، كما هو الحال في هذه الحالة من تحريف الصور أثناء تمرير الصفحة.

لجعل الحافة اليمنى تلتصق بشريط التمرير ، قمنا بتمرير قيمة right center إلى خاصية transformOrigin ، قمنا أيضًا بتعيين خاصية force3D على true في أخرى لتحسين الأداء.

أعلنا عن متغير clamp يقوم بحساب الانحراف لدينا ويضمن أنه لا يتجاوز 20degs . داخل كائن ScrollTrigger ، قمنا بتعيين خاصية trigger إلى معلمة elem1 ، والتي ستكون العنصر الذي يجب تشغيله عند استدعاء هذه الوظيفة. لدينا دالة رد onUpdate ، بداخلها متغير velocity يحسب السرعة الحالية ويقسمها على 300 .

أخيرًا ، نقوم بتحريك العنصر من قيمه الحالية عن طريق تعيين قيم أخرى. قمنا بتعيين skew ليكون مبدئيًا عند 0 ويكون skewY هو متغير velocity عند 0.8 .

بعد ذلك ، علينا استدعاء هذه الوظيفة في ملف App.js بنا.

 .... import { skewGallery } from "./components/Animate" function Gallery() { let skewImage = useRef(null); useEffect(() => { skewGallery(skewImage) }, []); return ( <div ref={(el) => (skewImage = el)}> <Image/> </div> ) } ....

هنا ، قمنا باستيراد skewGalley من ./components/Animate ، وقمنا بإنشاء مرجع skewImage يستهدف عنصر الصورة. داخل خطاف useEffect ، أطلقنا على دالة skewGallery بتمرير skewImage ref كمعامل. أخيرًا ، مررنا skewImage إلى ref إلى السمة.

كنت تتفق معي أنها كانت رحلة رائعة حتى الآن. ها هي المعاينة على CodeSanbox

الريبو الداعم لهذه المقالة متاح على جيثب.

خاتمة

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

موارد

  1. وثائق GSAP ، GreenSock
  2. "دليل المبتدئين لمنصة الرسوم المتحركة GreenSock ،" نيكولاس كرامر ، freeCodeCamp
  3. "مقدمة إلى الرسوم المتحركة باستخدام واجهة برمجة تطبيقات الرسوم المتحركة Greensock (GSAP)" ، زيل ليو