الرسوميات والرسوم المتحركة (Canvas وأصدقاؤه)
🎯 السؤال الجوهري
في الماضي، كانت صفحات الويب تعرض نصوصًا وصورًا جافة فقط. لكن إذا كنت تريد صنع لعبة كسر الطوب، أو تأثيرات ديناميكية رائعة، أو تقارير بيانات يمكن سحبها بحرية، فإن <div> وحده لا يكفي أبدًا. هذا هو السبب الذي أدى إلى ولادة Canvas (اللوحة القماشية).
سيأخذك هذا الدليل من رسم الخط الأول، وتطوير مهاراتك بالتدريج، حتى تكتب بنفسك محرك جسيمات يعمل بسلاسة عند 60 إطارًا في الثانية في المتصفح.
1. ما هو Canvas؟
إذا كانت صفحات الويب المبكرة تُجمع باستخدام قطع الليغو (علامات HTML)، فإن علامة <canvas> في HTML5 تمنحك ورقة بيضاء رقمية ضخمة، وتسلمك فرشاة تُتحكم بها بالكود، والباقي يعتمد على إبداعك الحر.
هنا لا توجد بنية علامات لما ترسمه. ما ترسمه بالفرشاة، بمجرد أن يلمس اللوحة يتحول إلى "أصباغ بكسل" نقية.
1.1 Canvas مقابل SVG: فنانان بفلسفتين مختلفتين
في عالم الرسم في الواجهة الأمامية، لدى Canvas منافس تقليدي يُدعى SVG. يمثلان مفهومين مختلفين تمامًا للرسم:
- Canvas (لوحة صور نقطية):
- المبدأ: مثل التلوين الحقيقي على الورق، بضع ضربات فرشاة تتحول إلى بقعة لون (بكسلات).
- الميزة: الكمبيوتر "ينثر اللون" فقط على الشاشة، الأداء يرتفع! يمكنه رسم آلاف الجسيمات المتلألئة المتحركة في نفس الوقت.
- العيوب: بعد الرسم لا يمكنك التراجع بشكل فردي (لا يمكنك الاختيار عبر عقد DOM)، وعند التكبير يصبح ضبابيًا وموزايكيًا.
- SVG (تجميع رسومات متجهة):
- المبدأ: مثل صنع عرض تقديمي PPT. ترسم دائرة، فيتم إنشاء علامة "كيان دائري" مستقلة توضع على اللوحة.
- الميزة: سواء كبرت 100 مرة أو 100,000 مرة، ستكون دائمًا واضحة للغاية. كل شكل هو عقدة DOM مستقلة، يمكنك تغيير لونه بـ CSS أو ربط أحداث النقر بـ JS في أي وقت.
- العيوب: إذا حاولت وضع عشرات الآلاف من الأشياء تطير بلا نظام، فإن شجرة DOM الثقيلة ومحرك التخطيط سيجمدان المتصفح مباشرة.
🎮 ملخص بسيط: للألعاب الديناميكية والتأثيرات الخلابة استخدم Canvas؛ للشعارات الدقيقة والرسوم البيانية التفاعلية استخدم SVG.
2. الضربة الأولى: فهم نظام الإحداثيات غير البديهي
2.1 لماذا هذه الورقة مقلوبة أعلاه وأسفلها؟
عندما تستعد للرسم، يجب أن تفهم أولاً أن مسطرة Canvas معكوسة. في نظام الإحداثيات التقليدي لدرس الرياضيات، نقطة الأصل الصفر في المنتصف، وكلما صعدت زادت القيمة. لكن في مجال عرض شاشات الكمبيوتر، في جميع الأجهزة تقريبًا يتم تحديد "نقطة الأصل (0, 0)" في الزاوية العلوية اليسرى من الشاشة. التحرك يمينًا يزيد المحور X بدون مشكلة، لكن بالتحرك للأسفل، يزيد المحور Y.
المبادئ الأساسية لنظام إحداثيات Canvas:
- الوحدة الأصلية: بكسل (px)، تطابق 1:1 مع البكسلات المادية للشاشة.
- المحور X: الاتجاه الموجب لليمين، من
0إلىcanvas.width. - المحور Y: الاتجاه الموجب للأسفل، من
0إلىcanvas.height.
👇 اسحب النقطة الصغيرة أدناه، وشعر بشكل حدسي بنقطة الأصل واتجاه الإحداثيات في الرسوميات الحاسوبية:
2.2 إضافة التوابل لفرشاتك السحرية
بنظام الإحداثيات، يمكننا استدعاء الفرشاة (تسمى Context في الكود، أو اختصارًا ctx). تمامًا مثل الرسم بلوحة ألوان حقيقية، يتبع تصميم API في Canvas ثلاث خطوات من الرسم الفيزيائي بشكل مثالي:
- خلط الألوان (State): ضبط لون التعبئة عبر
fillStyle، ولون الخط الخارجي عبرstrokeStyle. - تشكيل المسار (Path): التفكير فيما إذا كنت سترسم خطًا (
lineTo)، أو دائرة (arc)، أو مستطيلاً (rect). - الرسم بأقل ما يمكن (Render): تحديد ما إذا كنت ستملأ الداخل (
fill()) أم ترسم الحدود (stroke()).
بما أن Canvas لوحة صور نقطية بحتة، "ما سُدُّ لا يُسترد"، بمجرد الرسم يجف فورًا كبيكسلات ولا يمكن التراجع عنه ككائن مستقل.
👇 جرب اختيار أشكال وألوان مختلفة في العرض التوضيحي أدناه، وانظر كيف ينفذ الكود "الخطوات الثلاث" المذكورة:
3. كتاب الرسوم المتحركة المصفوع: كيف تجعل الصورة تتحرك بسلاسة فائقة
بما أن Canvas بمجرد تعبئته يتحول إلى بكسلات دائمة، فكيف تُصنع الشخصيات التي تركض في كل مكان على الشاشة في ألعاب HTML5؟
الجواب هو "خداع عينيك". هذا هو نفس مبدأ كتب الرسوم المتحركة المصفوعة أو أفلام السينما:
- مسح السبورة (Clear): استخدام
clearRect()لمسح كل محتوى اللوحة بلا رحمة. - حساب الموقع الجديد (Update): جعل إحداثي X للشخصية يتقدم سرًا بمقدار 2 بكسل.
- إعادة الرسم (Render): إعادة رسم الشخصية في الموقع الجديد.
- الحلقة المجنونة (Loop): الدمج مع آلة الإيقاع الدقيقة المدمجة في المتصفح
requestAnimationFrame. سيعيد هذه الإجراءات الثلاثة بمعدل تحديث الشاشة (عادة 60 مرة في الثانية، أي 60 FPS).
بفضل "استمرارية الرؤية" في العين البشرية، في 60 مرة في الثانية من [مسح ← تحديث ← إعادة رسم]، لا ترى سبورة وامضة، بل رسومًا متحركة سلسة كالحرير.
👇 اضبط سرعة التشغيل في العرض أدناه، ولاحظ كيف إزاحة كل إطار تترابط لتشكل حركة سلسة:
4. الأعمى يلمس الفيل: كيف تفعل التفاعل بالنقر داخل Canvas؟
لأن لوحة Canvas في نظر المتصفح مجرد "قماش ألوان" بدون أي بنية. لنفترض أنك رسمت وحشًا باستخدام arc() على اللوحة، عندما تريد تنفيذ "النقر على الوحش لخصم الصحة"، لا يمكنك أبدًا استخدام document.getElementById التقليدي للحصول على هذا الوحش. لأنه في بنية HTML، لا يوجد سوى علامة <canvas> البالغة عرضها 600 بكسل.
هذه هي المشكلة الكلاسيكية في برمجة الرسوميات: اكتشاف التصادم (Collision Detection) وتفويض الأحداث.
بما أن المتصفح يعرف فقط أن الماوس نقر على إحداثيات الشاشة (x, y) للـ Canvas، يجب عليك الحساب بنفسك باستخدام هندسة المرحلة الإعدادية:
- للدوائر: حساب المسافة من
نقطة نقر الماوسإلىمركز الدائرةبنظرية فيثاغورس، إذا كانت المسافة أقل من نصف القطر فمعنى ذلك "تم الإصابة". - للمستطيلات: التحقق مما إذا كان
xالمنقور ضمن الحدود اليمنى واليسرى للمستطيل، وyضمن الحدود العلوية والسفلية في نفس الوقت.
بغض النظر عن عدد العناصر على لوحتك، فإن أحداث التمرير أو النقر تُربط دائمًا على حاوية Canvas الفريدة، وهذا هو "تفويض الأحداث" المطلق.
👇 جرب استخدام الماوس (نقر، سحب، تمرير) أو لوحة المفاتيح (مفاتيح الأسهم للتحريك) أدناه، واختبر منطق التفاعل الأساسي هذا بـ "الحساب اليدوي للمسافة":
Instructions / 操作说明
- Click Mode:点击画布创建圆形,按住 Shift 可创建不同颜色
Event Log / 事件日志
5. تحرير قوة الحوسبة: أنظمة الجسيمات والسحر البصري
عند هذه النقطة، عندما ندمج "نظام الإحداثيات" و"حلقة الرسوم المتحركة" و"الألوان والأشكال"، ونضاعف عددها إلى مئات الآلاف من الشظايا الصغيرة، تكون قد امتلكت السلاح النهائي لإشعال البصيرة: نظام الجسيمات (Particle System).
فكرته الأساسية فجة للغاية لكنها فعالة:
- إنشاء مصفوفة ضخمة، مليئة بمئات "كائنات الجسيمات" المستقلة.
- كل كائن لديه دورة حياة مستقلة (
life)، وتسارع (vx/vy)، وتخميد الجاذبية (gravity). - في كل مرة يتم تشغيل
requestAnimationFrame، يتم المرور عبر هذه المئات من الجسيمات وتحديثها، ثم رسمها، وأخيرًا تنظيف الجسيمات "الميتة" (استنفدت قيمة الحياة/سقطت خارج الشاشة) بهدوء.
يمكن لمتصفحك في لحظة أن يصبح مصنعًا لإنتاج الألعاب النارية والثلوج والانفجارات.
👇 انقر على تأثيرات مختلفة، اضبط الجاذبية وعدد الجسيمات، ولاحظ كيف تقدم معادلات الرياضيات والفيزياء البسيطة رؤية جماعية معقدة:
6. حماية مجد FPS: كيف تواجه ارتفاع حرارة المعالج؟
جعل آلاف الكائنات تُحسب وتُعاد رسمها 60 مرة في ثانية يستهلك أداءً كبيرًا. إذا فعلت ذلك بشكل عشوائي، مروحة حاسوبك ستقلع قريبًا.
إليك "التقنيات الوقائية" التي يستخدمها خبراء المحركات الحقيقيون لإنقاذ معدل الإطارات:
مسح السبورة الجزئي (المستطيل المتسخ Dirty Rect): شخصية تركض في سهل واسع، لا تستخدم
clearRectعلى كل السهل في كل إطار! حيث تمر الشخصية بكتلة صغيرة، امسح تلك الكتلة فقط وأعد رسمها، وسيرتفع الأداء بشكل مفاجئ.سحر البديل الخلفي (Offscreen Canvas): إذا كانت الخلفية سماء مرصعة بالنجوم مع جبال معقدة وجميلة، فإن إعادة التصيير في كل مرة أمر غبي. عادةً نبني سرًا
<canvas>مخفيًا في الذاكرة، ونرسمه بشكل رائع مرة واحدة. في كل تحديث للإطار بعد ذلك، نحتاج فقط لصق "السالب الثابت" المُجمع عبرdrawImage()، مما يوفر حسابات أساسية هائلة.غسل الفرش بالجملة (Batching): التبديل من الأحمر إلى الأزرق في لوحة الألوان مكلف على المستوى الأدنى. إذا كان على اللوحة 1000 دائرة حمراء و1000 دائرة زرقاء متناثرة بالتبادل. أسرع طريقة هي: تحضير اللون الأحمر أولاً، والمرور لرسم جميع الدوائر الحمراء، ثم التبديل إلى اللون الأزرق لرسم جميع الدوائر الزرقاء. هذه هي فكرة التصيير بالجملة (Batch Rendering) الشهيرة.
👇 ارفع عدد الكائنات فوق 3000، شاهد صفحة الويب تسقط في هاوية التشنج، ثم شغل مفاتيح "تقنيات التحسين" في الزاوية اليمنى السفلية واحدة تلو الأخرى، وشاهد بنفسك إنقاذ معدل الإطارات الفعلي:
7. ملخص المصطلحات المهنية
| المصطلح | الشرح المبسط |
|---|---|
| Canvas | لوحة رسم ثنائية الأبعاد يوفرها HTML5. الرسم سريع جدًا، لكن بعد الرسم يتحول إلى بكسلات ألوان، ولا يدعم معالجة المحتوى عبر DOM. |
| SVG | رسومات متجهة. عند التكبير لا تضحي أبدًا بالوضوح، وكل شكل هو عنصر علامة مستقل يمكن ربط أنماط CSS وتفاعلاته بسهولة. |
| Context (ctx) | "الفرشاة السحرية ثنائية الأبعاد" التي تحصل عليها، تُستخدم لخلط الألوان وتعيين الأشكال ورسم التأثيرات الخاصة المختلفة. |
| requestAnimationFrame | آلة الإيقاع الإلهية المدمجة في المتصفح، تنفذ عمليات الاستدعاء بدقة وفقًا لمعدل تحديث الشاشة، وهي الخيار الأمثل لصنع رسوم متحركة سلسة. |
| FPS (معدل الإطارات) | معدل الإطارات. 60 FPS يعني أن المتصفح مسح لوحتك 60 مرة وأعاد رسم 60 صورة جديدة بسلاسة في ثانية واحدة. |
| المستطيل المتسخ (Dirty Rect) | المسح وإعادة الرسم بدقة فقط في المنطقة الصغيرة التي حدث فيها تغيير، مما يحافظ على الأداء بقوة. |
| Offscreen Canvas | "اللوحة الظل" المخفية في الذاكرة. رسم المشاهد المعقدة ولكن الثابتة مسبقًا، ثم استخدامها كنسيج ثابت قابلة لإعادة الاستخدام. |
من خط مستقيم بسيط، إلى نظام جسيمات رائع وضخم؛ كل التأثيرات الخاصة التي تبدو سحرًا ليست سوى 60 دورة من حساب الإحداثيات وإعادة الرسم في الثانية.