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?