البرمجة

دليل شامل لرسم الـ Canvas في JavaScript

JS Canvas 101: مقدمة شاملة إلى الرسم على اللوحة باستخدام JavaScript

يُعتبر عنصر في HTML5 من الأدوات الثورية التي أُدخلت على واجهات الويب الحديثة، حيث مكّن المطورين من إنشاء رسومات ديناميكية وتفاعلية داخل المتصفح باستخدام لغة JavaScript فقط، دون الحاجة إلى مكونات إضافية كـ Flash أو أدوات خارجية. يشكّل هذا العنصر مساحة يمكن للرسم عليها باستخدام أوامر برمجية مباشرة، ويُستخدم في تطبيقات متعددة تتراوح من الرسوم التوضيحية البسيطة وحتى محركات الألعاب ثنائية الأبعاد، وتحليل البيانات عبر الرسوم البيانية، ومعالجة الصور وغيرها.

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


تعريف عنصر في HTML

عنصر هو عنصر HTML يُستخدم لرسم الرسوميات بواسطة JavaScript. عند إدراج هذا العنصر داخل صفحة الويب، فإنه لا يعرض شيئًا في حد ذاته إلا عند التفاعل معه عبر كود JavaScript. يتم تحديد حجمه من خلال سمتي width وheight.

مثال على عنصر canvas:

html
<canvas id="myCanvas" width="500" height="400">canvas>

في هذا المثال، قمنا بإنشاء مساحة رسم بعرض 500 بكسل وارتفاع 400 بكسل، وحددنا لها معرفًا (id) باسم “myCanvas” حتى نتمكن من التعامل معها في JavaScript.


كيفية الوصول إلى canvas من خلال JavaScript

لرسم أي شيء داخل canvas، يجب أولاً الوصول إليه باستخدام DOM ثم استخراج السياق الخاص بالرسم. في الغالب، نستخدم سياق ثنائي الأبعاد “2d”، وهناك أيضًا سياق ثلاثي الأبعاد باستخدام WebGL.

javascript
const canvas = document.getElementById('myCanvas'); const ctx = canvas.getContext('2d');

ctx الآن هو كائن السياق الذي يسمح لنا بتنفيذ أوامر الرسم مثل fillRect، stroke, beginPath، وغيرها.


الأوامر الأساسية للرسم

1. رسم المستطيلات

  • fillRect(x, y, width, height) — يرسم مستطيلًا بلون التعبئة الحالي.

  • strokeRect(x, y, width, height) — يرسم فقط حدود المستطيل.

  • clearRect(x, y, width, height) — يمسح منطقة معينة داخل canvas.

مثال:

javascript
ctx.fillStyle = 'blue'; ctx.fillRect(50, 50, 150, 100);

2. رسم الخطوط

لرسم خطوط حرة، يتم استخدام سلسلة من الأوامر:

  • beginPath() — يبدأ مسارًا جديدًا.

  • moveTo(x, y) — ينقل نقطة البداية.

  • lineTo(x, y) — يرسم خطًا إلى نقطة محددة.

  • stroke() — يرسم الخط بناءً على المسار.

javascript
ctx.beginPath(); ctx.moveTo(100, 100); ctx.lineTo(200, 200); ctx.stroke();

3. رسم الدوائر والأقواس

يُستخدم الأمر arc لرسم الأقواس والدوائر:

javascript
ctx.beginPath(); ctx.arc(150, 150, 50, 0, Math.PI * 2); // دائرة كاملة ctx.fill();

4. تغيير ألوان التعبئة والحدود

javascript
ctx.fillStyle = 'red'; ctx.strokeStyle = 'black'; ctx.lineWidth = 3;

النصوص داخل canvas

يمكن أيضًا عرض نصوص باستخدام fillText و strokeText:

javascript
ctx.font = '24px Arial'; ctx.fillText('مرحبًا بك في canvas', 50, 50);

التعامل مع الصور

يمكن عرض الصور داخل canvas باستخدام drawImage:

javascript
const image = new Image(); image.src = 'image.jpg'; image.onload = function() { ctx.drawImage(image, 0, 0, 300, 200); };

الرسوم المتحركة داخل canvas

يتم إنشاء الرسوم المتحركة باستخدام الدالة requestAnimationFrame، التي تسمح بتحديث الرسم كل إطار:

javascript
let x = 0; function draw() { ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.fillRect(x, 50, 100, 100); x += 2; requestAnimationFrame(draw); } draw();

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

يمكن ربط أحداث الماوس ولوحة المفاتيح بالتفاعل مع canvas:

javascript
canvas.addEventListener('click', function(event) { const rect = canvas.getBoundingClientRect(); const x = event.clientX - rect.left; const y = event.clientY - rect.top; ctx.fillRect(x, y, 10, 10); });

التحويلات الهندسية (Transformations)

تشمل هذه العمليات التدوير، التحجيم، والتحريك.

  • translate(x, y) — لتحريك الرسم.

  • rotate(angle) — لتدوير الرسم.

  • scale(x, y) — لتكبير/تصغير الرسم.

javascript
ctx.translate(100, 100); ctx.rotate(Math.PI / 4); ctx.fillRect(0, 0, 100, 50);

حفظ واسترجاع الحالة

يُستخدم save() وrestore() لحفظ واسترجاع الحالة الحالية للـ canvas:

javascript
ctx.save(); // تغييرات في السياق ctx.restore();

الجدول التالي يوضح أهم دوال canvas واستخداماتها

الدالة الوظيفة
fillRect(x, y, w, h) رسم مستطيل بلون التعبئة الحالي
strokeRect(x, y, w, h) رسم حدود مستطيل
clearRect(x, y, w, h) مسح جزء من canvas
beginPath() بدء مسار جديد
moveTo(x, y) تحديد نقطة البداية للرسم
lineTo(x, y) رسم خط إلى نقطة محددة
arc(x, y, r, s, e) رسم دائرة أو قوس
fillText(text, x, y) عرض نص باستخدام التعبئة
drawImage(img, x, y) عرض صورة داخل canvas
translate(x, y) تحريك الإحداثيات
rotate(angle) تدوير الرسم حول النقطة الحالية
scale(x, y) تكبير/تصغير الكائن
save() / restore() حفظ واسترجاع حالة السياق

استخدامات متقدمة لـ canvas

1. معالجة البكسلات (Pixel Manipulation)

من خلال getImageData و putImageData يمكن الوصول إلى كل بكسل داخل canvas وتعديله:

javascript
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); const data = imageData.data; for (let i = 0; i < data.length; i += 4) { data[i] = 255 - data[i]; // عكس اللون الأحمر data[i + 1] = 255 - data[i+1]; // عكس اللون الأخضر data[i + 2] = 255 - data[i+2]; // عكس اللون الأزرق } ctx.putImageData(imageData, 0, 0);

2. الرسوم البيانية والتفاعلية

يمكن دمج canvas مع بيانات ديناميكية لعرض الرسوم البيانية أو خرائط الحرارة أو بيانات المستخدم في الوقت الفعلي، خاصة عند استخدام مكتبات مثل:


التوافق عبر المتصفحات

يدعم عنصر canvas معظم المتصفحات الحديثة مثل Chrome وFirefox وSafari وEdge. مع ذلك، يجب الحذر عند استخدام ميزات متقدمة أو دمج canvas مع WebGL، إذ قد تختلف درجة التوافق حسب الجهاز والمتصفح.


الأداء والتحسين

الرسم باستخدام canvas يتطلب وعيًا باستخدام الموارد، خصوصًا عند إنشاء رسوم متحركة أو عند التعامل مع ملايين البكسلات. من أهم نصائح تحسين الأداء:

  • تقليل عدد عمليات الرسم في كل إطار.

  • تجنب استخدام getImageData و putImageData بكثرة.

  • استخدام requestAnimationFrame بدلًا من setInterval أو setTimeout.

  • إعادة استخدام الكائنات بدلاً من إنشاء جديدة داخل الحلقات.


الخاتمة

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


المراجع: