Mi tarea es crear dos lienzos (grande y pequeño). En grande crea 5 estrellas de diferentes colores.
Tarea: haciendo clic en la estrella, cambie el color del lienzo pequeño al color de la estrella. Ahora el problema es que addEventListener solo funciona en el último elemento. ¿Algunas ideas?
Plantilla .html :
<canvas style="background-color:rgb(255, 255, 255); border: 1px solid black" id='big'>Обновите браузер</canvas> <canvas style="background-color:rgb(255, 255, 255); border: 1px solid black" id='small'>Обновите браузер</canvas> Guión .js :
const big = document.getElementById("big"); const small = document.getElementById("small"); big.height = 600; big.width = 600; small.height = 600; small.width = 50; function createStar(moveToX, moveToY, lineToX1, lineToY1, lineToX2, lineToY2, lineToX3, lineToY3, lineToX4, lineToY4, color) { ctx = big.getContext('2d'); ctx.beginPath(); ctx.moveTo(moveToX, moveToY); ctx.lineTo(lineToX1, lineToY1); ctx.lineTo(lineToX2, lineToY2); ctx.lineTo(lineToX3, lineToY3); ctx.lineTo(lineToX4, lineToY4); ctx.closePath(); ctx.strokeStyle = color; ctx.fillStyle = color; ctx.fill(); ctx.stroke(); }; const red = new createStar(20, 60, 100, 60, 35, 110, 60, 25, 85, 110, 'red'); const blue = new createStar(120, 60, 200, 60, 135, 110, 160, 25, 185, 110, 'blue'); const green = new createStar(120, 160, 200, 160, 135, 210, 160, 125, 185, 210, 'green'); const black = new createStar(220, 460, 400, 460, 235, 560, 300, 400, 385, 560, 'black'); const yellow = new createStar(220, 260, 300, 260, 235, 310, 260, 225, 285, 310, 'yellow'); big.addEventListener('click', function(e){ if(ctx.isPointInPath(e.offsetX, e.offsetY)) { small.style.backgroundColor = 'red'; } else { small.style.backgroundColor = 'white'; } });context.isPointInPath(x, y) verificará si el punto en las coordenadas x e y está dentro de la ruta secundaria actual que se está rastreando en el contexto.
Cada vez que llama a ctx.beginPath() , esta ruta secundaria se borra.
Para solucionarlo, tendría que volver sobre la lista completa de estrellas y verificar una por una si el punto cae allí.
Sin embargo, también hay una interfaz Path2D que puede usar.
Esta interfaz permite mantener dicha subruta como su propio objeto, y puede ser utilizada por el contexto en lugar de la ruta del contexto interno, por ejemplo, ctx.fill(path) , ctx.stroke(path) , ctx.clip(path) , ctx.scrollPathIntoView(path) , ctx.drawFocusIfNeeded(path, element) , y probablemente lo haya adivinado, ctx.isPointInPath(path, x, y) o ctx.isPointInStroke(path, x, y) .
Entonces, puede reescribir su código para que cada estrella se almacene en su propia instancia de Path2D, almacene todas estas instancias en un Array y luego recorra ese Array para verificar si alguno de estos fue alcanzado por el punto:
const stars = []; const big = document.getElementById("big"); const small = document.getElementById("small"); big.height = 600; big.width = 500; small.height = 600; small.width = 50; const ctx = big.getContext("2d"); function createStar(moveToX, moveToY, lineToX1, lineToY1, lineToX2, lineToY2, lineToX3, lineToY3, lineToX4, lineToY4, color) { const path = new Path2D(); // store our path in an object also hodling the color stars.push({path, color}); path.moveTo(moveToX, moveToY); path.lineTo(lineToX1, lineToY1); path.lineTo(lineToX2, lineToY2); path.lineTo(lineToX3, lineToY3); path.lineTo(lineToX4, lineToY4); ctx.strokeStyle = color; ctx.fillStyle = color; ctx.fill(path); ctx.stroke(path); }; const red = new createStar(20, 60, 100, 60, 35, 110, 60, 25, 85, 110, 'red'); const blue = new createStar(120, 60, 200, 60, 135, 110, 160, 25, 185, 110, 'blue'); const green = new createStar(120, 160, 200, 160, 135, 210, 160, 125, 185, 210, 'green'); const black = new createStar(220, 460, 400, 460, 235, 560, 300, 400, 385, 560, 'black'); const yellow = new createStar(220, 260, 300, 260, 235, 310, 260, 225, 285, 310, 'yellow'); big.addEventListener('click', function(e) { // find the first star that got clicked const touched = stars.find((star) => ctx.isPointInPath(star.path, e.offsetX, e.offsetY) ); if (touched) { small.style.backgroundColor = touched.color; } else { small.style.backgroundColor = 'white'; } }); canvas { background-color: rgb(255, 255, 255); border: 1px solid black; } <canvas id='big'>Обновите браузер</canvas> <canvas id='small'>Обновите браузер</canvas>