كما نعلم جميعًا، القماش عبارة عن صورة نقطية، في الصورة النقطية، يمكننا رسم أشياء مختلفة فيها، بما في ذلك الصور والخطوط وما إلى ذلك. فماذا يجب أن نفعل إذا أردنا إضافة حدث نقرة إلى صورة معينة في اللوحة القماشية. ويمكن لـ js فقط مراقبة أحداث اللوحة القماشية. ومن الواضح أن هذه الصورة غير موجودة وأن الصور الموجودة في الدوم مرسومة فقط في اللوحة القماشية. بعد ذلك، سأقوم ببساطة بتنفيذ ربط الحدث لكل صورة داخل اللوحة القماشية.
اسمحوا لي أن أتحدث أولاً عن مبدأ التنفيذ: فهو في الواقع يربط الأحداث ذات الصلة باللوحة القماشية، من خلال تسجيل إحداثيات اللوحة القماشية التي تقع فيها الصورة، ويتم الحكم على الصورة التي يعمل عليها الحدث. بهذه الطريقة، يبدو الأمر مشابهًا بعض الشيء لعامل الحدث. ومع ذلك، لا يزال التنفيذ معقدًا بعض الشيء.
ملاحظة: لقد كتبت الكود التالي في ts. يمكنك فقط قراءته كـ es6. يمكنك التحقق منه إذا كان مختلفًا قليلاً.
توثيق الآلة الكاتبة (الآلة الكاتبة سهلة الاستخدام حقًا، وأوصيك بمعرفة المزيد عنها).
1. قم بإنشاء اتصال بين الصورة والقماش (هنا أستخدم كتل الألوان بدلاً من الصور)نحتاج هنا إلى إنشاء اتصال معين بين كتلة الألوان واللوحة القماشية، بدلاً من مجرد العرض. سجل أيضًا إحداثيات وعرض وارتفاع كتلة الألوان. دعونا ننفذها خطوة بخطوة
اكتب أولاً صفحة html أساسية لإنشاء لوحة قماشية:
<!DOCTYPE html><html lang=en><head> <meta charset=UTF-8> <meta name=viewport content=width=device-width, virtual-scale=1.0> <meta http-equiv=X-UA -المحتوى المتوافق=ie=edge> <title>حدث القماش</title> <style> html, body { height: 100% الخلفية: #eee } قماش { الخلفية: #fff؛ العرض: كتلة؛ الهامش: 0 تلقائي } </style></head><body> <canvas width=500 height=500 id=canvas></canvas></body>بعد ذلك، نحتاج إلى تحديد فئة Canvas. ما هي الوظائف التي يجب أن تحتوي عليها هذه الفئة؟
نظرًا لأن كتل الألوان تحتوي أيضًا على بعض المعلمات الخاصة بها، فمن أجل تسهيل التوسع، قمنا أيضًا بتحديد فئة لمكعبات الألوان والوظائف المطلوبة لهذا النوع هي:
العرض، والارتفاع، واللون، والإحداثيات (x، y)، ومثال Canvas؛ فلنقرر ذلك في البداية.
حسنًا، ابدأ بالكتابة
// فئة قماش فئة قماش { blockList: Block[] ctx: أي قماش: أي createBlock (option) { option.Canvas = this this.blockList.push(new Block(option)) this.painting() } تقديم (block) { // عرض وظيفة كتلة اللون this.ctx.fillStyle = block.color this.ctx.fillRect(block.x, block.y, block.w, block.h) } Painting () { // قم بعرض كافة المربعات الملونة الموجودة في الحاوية على اللوحة القماشية // امسح اللوحة القماشية (يجب مسح اللوحة القديمة قبل العرض) this.ctx.fillStyle = '#fff' this.ctx.fillRect(0, 0, this.canvas. العرض، هذا .canvas.height) this.blockList.forEach(ele => { this.rendering(ele) }) } المُنشئ (ele) { // وظيفة التهيئة (المدخل هو قماش) // تعيين قماش this.canvas = ele this.ctx = this.canvas.getContext('2d') // حاوية كتلة اللون this.blockList = [] }}class Block { w: number h: number x: number y: number color : string Canvas: التسلسل الهرمي للقماش: مُنشئ الأرقام ({ w, h, x, y, color, Canvas }) { // تهيئة وتعيين الخصائص المرتبطة بكتلة الألوان this.w = w this.h = h this.x = x this.y = y this.color = color this.Canvas = Canvas }}دعونا نحاول تشغيل موجة أدناه
// قم بإنشاء مثيل Canvas وأضف كتلة لون زرقاء بعرض وارتفاع 100 بكسل، وموضع (100,100)، (300,100) كتل ملونة حمراء وزرقاء var Canvas = new Canvas(document.getElementById('canvas')) Canvas. createBlock({ // أحمر x: 100، y: 100، w: 100، h: 100، color: '#f00' }) Canvas.createBlock({ // أزرق x: 100، y: 100، w: 300، h: 100، color: '#00f' })نتائج التشغيل هي كما يلي:
2. أضف حدث نقرة إلى كتلة الألوانهنا لا يمكنك إضافة حدث نقرة مباشرة إلى كتلة اللون، لذلك تحتاج إلى استخدام الإحداثيات لتحديد كتلة اللون التي يتم النقر عليها حاليًا.
class Block { // ...حذف جزء من الكود checkBoundary (x, y) { // تحديد طريقة الحدود return x > this.x && x < (this.x + this.w) && y > this.y && y < (this.y + this.h) } mousedownEvent () { // انقر فوق الحدث console.log(`تم النقر على كتلة اللون ذات اللون ${this.color}`) }}class Canvas { // .. .مُنشئ رمز الجزء المحذوف (ele) { this.canvas = ele this.ctx = this.canvas.getContext('2d') this.blockList = [] // ربط الحدث (هناك شيء واحد يجب ملاحظته هنا. لقد استخدمت طريقة الربط هنا، وهي من أجل تبديل هذا المؤشر في طريقة mousedownEvent إلى Canvas) this.canvas.addEventListener('click', this.mousedownEvent.bind(this)) // انقر فوق الحدث} mousedownEvent () { // حدث النقر const x = e.offsetX const y = e.offsetY // هنا يتم تمرير إحداثيات النقرة إلى جميع الكتل الملونة، ويتم استخدام طريقة الحكم الحدودي لتحديد ما إذا كانت النقرة بالداخل. إذا كانت الإجابة بنعم، فقم بتنفيذ طريقة الحدث الخاصة بكتلة الألوان. this.blockList.forEach(ele => { if (ele.checkBoundary(x, y)) ele.mousedownEvent(e) }) }}لقد قمنا حتى الآن بتنفيذ ربط أحداث النقر المقابلة بكتل ألوان مختلفة في لوحات فنية مختلفة. ومع ذلك، فإن حدث النقر هذا ليس مثاليًا، لأننا لم نقدم حتى الآن مفهوم التسلسل الهرمي، مما يعني أنه إذا تم النقر على كتلتين لونيتين متداخلتين، فسيتم تشغيل كليهما. لذلك نحتاج أيضًا إلى إضافة سمات هرمية إلى كتل الألوان. إذا قمت بالنقر فوق كتلة اللون لتغيير كتلة اللون، فسيتم رفع مستوى كتلة اللون إلى أعلى مستوى.
class Block { // ...حذف جزء من مُنشئ الكود ({ w, h, x, y, color, Canvas, hierarchy }) { // تهيئة وتعيين الخصائص المتعلقة بكتلة الألوان this.w = w this .h = h this.x = x this.y = y this.color = color this.Canvas = Canvas this.hierarchy = 0 }}class Canvas { // ...حذف جزء من مُنشئ الكود (ele) { this .canvas = ele this.ctx = this.canvas.getContext('2d') this.blockList = [] // ربط الحدث (هناك شيء واحد يجب ملاحظته هنا. لقد استخدمت طريقة الربط هنا لتبديل هذا المؤشر في طريقة mousedownEvent إلى Canvas) هذا .canvas .addEventListener('click', this.mousedownEvent.bind(this)) // انقر فوق الحدث this.nowBlock = null // كتلة اللون المحددة حاليًا} createBlock (option) { // إنشاء وظيفة كتلة اللون (كتلة هنا هي فئة كتلة اللون) option.Canvas = this // يجب أن يكون مستوى إنشاء أحدث كتلة لون هو الأعلى option.hierarchy = this.blockList.length this.blockList.push(new Block (خيار)) this.rendering() } mousedownEvent (e) { // حدث النقر const x = e.offsetX const y = e.offsetY // احصل على كتلة الألوان ذات المستوى الأعلى في النقطة this.nowBlock = (this.blockList.filter(ele => ele.checkBoundary(x, y))).pop() // إذا لم يكن هناك كتلة ألوان تم التقاطها، فاخرج مباشرة إذا (!this .nowBlock) return // رفع مستوى كتلة اللون التي تم النقر عليها إلى أعلى this.nowBlock.hierarchy = this.blockList.length // إعادة الترتيب (من الصغير إلى الكبير) this.blockList.sort((a, b) = > a.hierarchy - b.hierarchy) // أعد تخصيص التسلسل الهرمي من 0 this.blockList.forEach((ele, idx) => ele.hierarchy = idx) // أعد الفرز بترتيب عكسي ثم أعد العرض. this.painting() this.nowBlock.mousedownEvent(e) // تشغيل الأحداث لمربع اللون المحدد فقط}}// هنا يتعين علينا إضافة كتلة لون ثالثة تتداخل مع كتلة اللون الأحمر Canvas.createBlock({ x: 150 ، ص: 150، عرض: 100، ح: 100، اللون: '#0f0'})الكود الموجود في طريقة mousedownEvent في Canvas معقد بعض الشيء، ويرجع ذلك أساسًا إلى أنه معقد بعض الشيء.
التأثير بعد التشغيل هو كما يلي:
3. قم بسحب وإسقاط كتل الألوان المختلفةأعلاه قمنا بتنفيذ الحصول على كتل ألوان مختلفة وتعديل مستوياتها. بعد ذلك، نحتاج إلى تنفيذ سحب الكتل الملونة، وذلك بشكل أساسي للحصول على التغييرات في إحداثيات الموضع أثناء حركة الماوس وعند النقر بالماوس في البداية. هذا المبدأ هو نفسه مبدأ السحب والإفلات العادي في DOM.
احصل على النقطة التي يتم فيها النقر على كتلة اللون والمسافة (disX، disY) من يسار وأعلى كتلة اللون.
عندما يتحرك الماوس، اطرح (disX، disY) من المسافة الحالية للماوس من يسار وأعلى اللوحة القماشية. هذه هي إحداثيات x وy لكتلة الألوان.
class Block { // ...حذف جزء من الكود mousedownEvent (e: MouseEvent) { /* طريقة حساب disX وdisY هنا: تحصل e.offsetX على المسافة بين نقرة الماوس والجانب الأيسر من اللوحة القماشية، وهذا .x هي مسافة كتلة اللون المسافة إلى يسار اللوحة القماشية. e.offsetX-this.x هي المسافة إلى يسار كتلة اللون. يجب أن يكون هذا سهل الفهم */ const disX = e.offsetX - this.x // المسافة من الجانب الأيسر لمربع اللون عند النقر عليه const disY = e.offsetY - this.y // المسافة من أعلى كتلة اللون عند النقر عليها // ربط حدث انزلاق الماوس هنا، mouseEvent.offsetX هو أيضًا المسافة بين الماوس والجانب الأيسر من اللوحة القماشية، mouseEvent.offsetX - disX هو إحداثي x لكتلة الألوان. وبنفس الطريقة، يتم حساب y بنفس الطريقة. وأخيرا، مجرد إعادة تقديم. document.onmousemove = (mouseEvent) => { this.x = mouseEvent.offsetX - disX this.y = mouseEvent.offsetY - disY this.Canvas.painting() } // امسح جميع الأحداث عند تحرير الماوس document.onmouseup = ( ) => { document.onmousemove = document.onmousedown = null } // console.log("تم النقر على المربع اللوني 22 باللون ${this.color}") }}التأثير هو كما يلي:
تم لصق الكود الكامل أدناه (لن يتم تضمين HTML وطريقة الاستدعاء). هذا المثال هو مجرد تنفيذ بسيط لأحداث الربط بالمحتوى الموجود في اللوحة القماشية. يمكنك تنفيذ أحداث أكثر تعقيدًا، مثل استبدال الكتل الملونة بالصور بالإضافة إلى السحب، يمكنك تكبير الصور وتدويرها وحذفها وما إلى ذلك.
class Canvas { blockList: Block[] ctx: Any Canvas: Any nowBlock: Block createBlock (option) { option.hierarchy = this.blockList.length option.Canvas = this this.blockList.push(new Block(option)) this. Painting() } rendering (block) { this.ctx.fillStyle = block.color this.ctx.fillRect(block.x, block.y, block.w, block.h) } Painting () { // امسح اللوحة القماشية this.ctx.fillStyle = '#fff' this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height) this.blockList.forEach(ele => { this.rendering(ele) }) } mousedownEvent (e: MouseEvent) { // حدث النقر const x = e.offsetX const y = e.offsetY // احصل على كتلة الألوان ذات المستوى الأعلى في النقطة this.nowBlock = (this.blockList.filter(ele => ele.checkBoundary(x, y))).pop() // إذا لم يكن هناك كتلة ألوان تم التقاطها، فاخرج مباشرة إذا (!this .nowBlock) return // رفع مستوى كتلة اللون التي تم النقر عليها إلى أعلى this.nowBlock.hierarchy = this.blockList.length // إعادة الترتيب (من الصغير إلى الكبير) this.blockList.sort((a, b) = > a.hierarchy - b.hierarchy) // أعد تخصيص التسلسل الهرمي من 0 this.blockList.forEach((ele, idx) => ele.hierarchy = idx) // أعد الفرز بترتيب عكسي ثم أعد العرض. this.painting() this.nowBlock.mousedownEvent(e) // this.blockList.forEach(ele => { // if (ele.checkBoundary(x, y)) ele.clickEvent(e) // }) } المُنشئ (ele) { this.canvas = ele this.ctx = this.canvas.getContext('2d') this.blockList = [] // ربط الحدث this.canvas.addEventListener('mousedown', this.mousedownEvent.bind(this)) }}class Block { w: number h: number x: number y: number color: string Canvas: التسلسل الهرمي للقماش: مُنشئ الأرقام ( { w، h، x، y، اللون، اللوحة القماشية، التسلسل الهرمي }) { this.w = w this.h = h this.x = x this.y = y this.color = color this.Canvas = قماش this.hierarchy = hierarchy } checkBoundary (x, y) { return x > this.x && x < (this.x + this.w) && y > this.y && y < (this.y + this.h) } mousedownEvent (e: MouseEvent) { const disX = e.offsetX - this.x const disY = e.offsetY - this.y document.onmousemove = (mouseEvent) => { this.x = mouseEvent.offsetX - disX this.y = mouseEvent.offsetY - disY this.Canvas.painting() } document.onmouseup = () => { document.onmousemove = document.onmousedown = null } // console.log("تم النقر على المربع الملون 22 مع اللون ${this.color}`) }}ما ورد أعلاه هو المحتوى الكامل لهذه المقالة وآمل أن يكون مفيدًا لدراسة الجميع وآمل أيضًا أن يدعم الجميع شبكة VeVb Wulin.