دليل خطوة بخطوة لتطبيق تأثير مضاعف في React

لنكن صريحين. لقد سمعت عن التصميم متعدد الأبعاد ، وتريد تطبيق تأثير مضاعف في تطبيقات React الخاصة بك. بالطبع هناك مكتبات مثل material-ui نفذتها بالفعل ، لكنك لا تشعر حقًا باستخدام واحدة منها. أنت فقط تريد مكونًا واحدًا من نوع & lt؛ Ripple & gt؛ والذي يمكنك تطبيقه على عناصر أخرى (زر أو مفتاح تبديل أو عنصر قائمة أو أي شيء).



إذن هذا هو ما قمت بإنشائه ، إعادة t -touch-ripple. إنه خفيف الوزن وسهل الاستخدام ويمكنك استخدامه في أي مكان تريده لراحتك. إذا كنت لا تهتم بطريقة عملها ، يمكنك التوقف عن القراءة الآن والاستيلاء عليها من npm.

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

ماذا نصنع؟

سنقسم إلى مكونين: Ripple و RippleWrapper .

المكوِّن Ripple هو شيء الدائرة الصغيرة نفسه. سيظهر عندما تنقر في مكان ما (يبدو أننا نريده أن يظهر في الموضع المحدد حيث تنقر) وينتشر بعد فترة قصيرة من الزمن.

إن مكون RippleWrapper هو في الأساس غلاف. إنها حاوية لـ Ripple (s) ، حيث يمكن أن يكون لديك مكون ripple متعدد إذا كنت تنقر بسرعة. بالإضافة إلى ذلك ، سنلزم جميع المستمعين بمكوِّن RippleWrapper لذلك فهو يتحمل مسؤولية التعامل مع كل المنطق.

& lt؛ Ripple & gt؛

مكون Ripple بسيط للغاية. تتكون من مرحلتين: دخول و خروج.

لذلك ، يمكننا كتابة بعض CSS مثل هذه إلى حد كبير:

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

يقبل

Ripple ثلاث دعائم مهمة: rippleX و rippleY (وهي موضع ظهورها) و rippleSize الذي يشير إلى الحجم الهائل للمكون. يتم حساب هذه العناصر في مكون RippleWrapper لذا سنتحدث بعد ذلك عن كيفية اكتشافها.

يمكنك بالتأكيد كتابة تعليمات برمجية أكثر قوة من هذا ، ولكن كما ذكرت سابقًا ، فإنني أقدم لك فقط جوهر التنفيذ أو الهيكل الرئيسي لتطبيقي.

العلامة & lt؛ RippleWrapper & gt؛

معالجة الأحداث

أولاً ، نربط الأحداث التي نهتم بها.

عند تشغيل الحدثين mousedown أو touchstart ، نحتاج إلى إنشاء تموج جديد. لذلك سوف نسمي this.start . عندما يتم تشغيل الأحداث الأربعة الباقية ، فهذا يعني أنه يجب إزالة التموج ، لذلك سنقوم فقط بالاتصال بـ this.stop .

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

start () و stop()

في وظيفة start ، يتعين علينا إكمال ثلاث مهام:

لاحظ أنه بالنسبة إلى rippleX و rippleY ، نريد نوعًا من الإحداثيات “النسبية” لذلك e.clientX و e. لا يمكن استخدام قيمة clientY مباشرة لأنها إحداثيات “مطلقة”. ما نفعله بدلاً من ذلك هو طرحها بواسطة الإحداثيات المطلقة لـ RippleWrapper نفسها. (يمكننا الحصول على هذه الإحداثيات باستخدام getBoundingClientRect )

بالنسبة إلى stop ، لا يوجد الكثير ليقوله. الشيء الوحيد الذي نقوم به هو إزالة العنصر الأول من rippleArray .

createRipple ()

الآن يمكننا أخيرًا تجميعها معًا وإنشاء مكون Ripple وإلحاقه بـ rippleArray .

ملاحظة حول nextKey هنا. يطلب React منا أن يكون لدينا مفتاح فريد لكل عنصر قائمة لاكتساب كفاءة أفضل للمصلح. لذلك سنزيد nextKey بمقدار 1 في كل مرة نقوم فيها بإنشاء تموج.

الخطأ

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

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

دون أدنى شك ، لجأت إلى مسودة عمل w3 في محاولة لمعرفة ما إذا كان سيتم تشغيل حدث “onclick” هذا. وهذا ما قدمه لنا w3:

قد يسبق حدث click الحدثين الماوس و mouseup على نفس العنصر ، مع تجاهل التغييرات بين أنواع العقد الأخرى (على سبيل المثال ، العقد النصية).

بمعنى ، يجب تشغيل الماوس و mouseup على نفس العنصر قبل تنشيط onclick . والأشياء التي مررنا بها هي ، عندما نضغط على العنصر fast ، نشغل في الواقع mousedown في السابق Ripple ، الذي تم تدميره بعد ذلك بوقت قصير ، ثم يتم تشغيل mouseup على Current Ripple . تم تشغيلها على عناصر مختلفة ونتيجة لذلك ، لن يتم تنشيط onclick .

بالنسبة للحل ، يمكن حل هذه المشكلة عن طريق إضافة سطر واحد من كود CSS على عنصر Ripple :

لماذا يعمل هذا؟ عند ضبط pointer-events على none :

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

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

النهاية

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

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