modelo eventos evento ejecutar desde capturar basico javascript jquery html5 canvas html5-canvas

javascript - ejecutar - Cómo usar eventos de clics múltiples en un lienzo



modelo basico de eventos javascript (2)

Dibujé un círculo con canvas usando el siguiente código.

<div class="abc"><canvas id="myCanvas">HTML5 canvas tag.</canvas></div> <script> var c = document.getElementById("myCanvas"); var ctx = c.getContext("2d"); ctx.beginPath(); ctx.arc(100,75,50,-0.1*Math.PI,1.7*Math.PI); ctx.lineWidth = 15; ctx.strokeStyle = "#c32020"; ctx.stroke(); var c2 = document.getElementById("myCanvas"); var ctx2 = c2.getContext("2d"); ctx2.beginPath(); ctx2.arc(100,75,50,1.7*Math.PI,-0.1*Math.PI); ctx2.lineWidth = 15; ctx2.strokeStyle = "#a9a9a9"; ctx2.stroke(); </script>

Aquí está el resultado en el navegador web.

Ahora necesito llamar a dos function javascript diferentes cuando el usuario hace clic en la parte roja y en la parte gris del círculo.

Al click en la parte roja, debe llamar a function1 y al hacer clic en la parte gris, debe llamar a function2 .

Lo intenté mucho pero no tuve éxito. Necesito la ayuda de un experto para implementarlo.


Dejar que el navegador haga (la mayoría de) el trabajo

Al hacer clic en la parte roja, debe llamar a function1 y al hacer clic en la parte gris, debe llamar a function2.

Puede usar objetos de ruta reutilizables para almacenar las diferentes rutas que desea probar y luego utilizar isPointInPath() con ruta y coordenadas como argumentos.

Al marcar cada ruta para un hit, puede asignar una llamada diferente según, por ejemplo, índice.

Y no hay necesidad de hacer esto:

var c2 = document.getElementById("myCanvas"); var ctx2 = c2.getContext("2d");

Esto simplemente hará referencia al mismo contexto ya que un lienzo solo puede tener uno: si se solicita más de una vez, se dará el mismo (o nulo si es de otro tipo).

Cómo usar eventos de clics múltiples en un lienzo

Puede compartir el controlador de clics para hacer lo que quiera, como se muestra a continuación:

Para los navegadores modernos, puede usar ambos objetos Path2D para almacenar la información de ruta que quiera usar más adelante (me referiré a navegadores más antiguos en el segundo ejemplo).

Ejemplo

var c = document.getElementById("myCanvas"); var ctx = c.getContext("2d"); var p1 = new Path2D(); var p2 = new Path2D(); var paths = [p1, p2]; // store paths in array for check later // store arc parts to respective path objects p1.arc(100, 75, 50, -0.1 * Math.PI, 1.7 * Math.PI); // red part p2.arc(100, 75, 50, 1.7 * Math.PI, -0.1 * Math.PI); // grey part // render the two path objects using a common context, but different style ctx.lineWidth = 15; ctx.strokeStyle = "#c32020"; ctx.stroke(p1); ctx.strokeStyle = "#a9a9a9"; ctx.stroke(p2); // check for clicks on common canvas c.onclick = function(e) { var rect = this.getBoundingClientRect(), // adjust click coordinates x = e.clientX - rect.left, y = e.clientY - rect.top; // iterate through path array to test each path for hits for(var i = 0; i < paths.length; i++) { if (ctx.isPointInStroke(paths[i], x, y)) { // check which path console.log("Path " + (i+1) + " clicked"); break; } } };

<canvas id="myCanvas"></canvas>

Compatibilidad del navegador

Los navegadores antiguos, sin embargo, no admitirán el isPointInStroke() , como IE11.

Para este escenario, puede usar matemática simple para descubrir si el clic está dentro del radio de los arcos:

var c = document.getElementById("myCanvas"); var ctx = c.getContext("2d"); ctx.lineWidth = 15; ctx.arc(100, 75, 50, -0.1 * Math.PI, 1.7 * Math.PI); // red part ctx.strokeStyle = "#c32020"; ctx.stroke(); ctx.beginPath(); ctx.arc(100, 75, 50, 1.7 * Math.PI, -0.1 * Math.PI); // grey part ctx.strokeStyle = "#a9a9a9"; ctx.stroke(); // check for clicks on common canvas c.onclick = function(e) { var rect = this.getBoundingClientRect(), // adjust click coordinates x = e.clientX - rect.left, y = e.clientY - rect.top, diffX = 100 - x, diffY = 75 - y, len = diffX*diffX + diffY*diffY, // we don''t need to square-root it: r1 = 43*43, // it''s faster to scale up radius (50-50% of linewidth) r2 = 57*57; // radius + 50% of linewidth // are we on the edge of the circle? if (len >= r1 && len <= r2) { // now find angle to see if we''re in red or grey area var angle = Math.atan2(diffY, diffX); if (angle > 0.7 * Math.PI && angle < 0.9 * Math.PI) { console.log("Grey part"); } else { console.log("Red part"); } } };

<canvas id="myCanvas"></canvas>

Tenga en cuenta que un caso especial en el último ejemplo, es decir, cuando el arco cruza el punto de 0/360 °, querrá dividir las comprobaciones [0, ángulo> y [ángulo, 360>.


Deberá agregar un evento de clic al elemento de lienzo y calcular si se hace clic en rojo o gris. Aquí hay un código para comenzar, pero igual tendrá que averiguar qué coordenadas tiene el área de su círculo.

var elem = document.getElementById(''myCanvas''), elemLeft = elem.offsetLeft, elemTop = elem.offsetTop; // Add event listener for `click` events. elem.addEventListener(''click'', function(event) { var x = event.pageX, y = event.pageY; // use x and y to determine if the colored regions are clicked and execute code accordingly }, false);

Código obtenido aquí: ¿cómo agrego un controlador de eventos onClick simple a un elemento canvas?