mano lineas lienzo imagen guardar firma dibujar crear con como alzada javascript canvas html5-canvas

javascript - lineas - guardar canvas como imagen



¿Cómo saber si el evento mousedown se produce en el lugar que queremos en el lienzo? (1)

Una explicación de lo que tu código está probando.

Esta parte de tu código ...

((dx * dx) + (dy * dy) < circleRadius * circleRadius)

... usa el Teorema de Pitágoras para probar matemáticamente si el mouse está dentro de la circunferencia de un círculo.

(dx * dx) + (dy * dy) mide la distancia entre el punto central del círculo y el mouse. En realidad, mide la distancia al centro del ratón al cuadrado, pero como Math.sqrt es una operación costosa, simplemente comparamos la distancia cuadrada del mouse con el radio del círculo al cuadrado . Obtenemos el mismo resultado pero evitamos el costoso Math.sqrt .

Aquí hay un tutorial sobre cómo determinar distancias usando el Teorema de Pitágoras:

https://www.youtube.com/watch?v=We3LG8pK-LU

No podemos decir por qué se realiza la prueba sin ver más de su código.

Pero, presumiblemente, si el mouse está dentro del círculo, estás decidiendo que el usuario tiene la intención de arrastrar el círculo.

Y a la inversa, si el mouse está fuera del círculo, está decidiendo que el usuario tiene la intención de ejecutar un clic.

Un clic alternativo frente a la prueba de arrastre:

Esta prueba alternativa es agradable porque puede dejar que el uso haga clic en el círculo o arrastre el círculo. Esta alternativa intenta "leer la intención" del usuario.

  1. En mousedown, guarde la posición inicial del mouseX y mouseY.

    var isDown,startX,startY,itIsADrag; function handleMouseDown(e){ // save the mouse position at mousedown startX=parseInt(e.clientX-offsetX); startY=parseInt(e.clientY-offsetY); // initially set the "itIsADrag" flag to false itIsADrag=false; // set the "isDown" flag to true isDown=true; ... any other code ... }

  2. En mousemove, prueba si el mouse se ha movido a menos de 5 píxeles en total (o 10px o lo que sea).

    • Si se mueve <5 píxeles, no haga nada antes de que se trate de un clic.
    • Si se mueve> = 5 píxeles, comienza una operación de arrastre.

      function handleMouseMove(e){ // return if the mouse is not down if(!isDown){return;} // get the current mouse position mouseX=parseInt(e.clientX-offsetX); mouseY=parseInt(e.clientY-offsetY); // do nothing if the mouse has moved less than 5 total pixels since mousedown if(!itIsADrag && Math.abs(mouseX-startX)+Math.abs(mouseY-startY)<5){return;} // Set the dragging flag to true // This flag prevents the Math.abs test above if we know we''re dragging itIsADrag=true; // start a drag operation ... do drag stuff ... }

  3. En el momento en que ocurre el mouseup, podemos simplemente leer nuestro indicador itIsADrag para determinar si el usuario hizo clic o lo arrastró.

    function handleMouseUp(e){ if(itIsADrag){ console.log("You have been dragging"); }else{ console.log("You''ve did a click"); } // clean up by clearing the isDown flag isDown=false; }

Código de ejemplo y una demostración:

var canvas=document.getElementById("canvas"); var ctx=canvas.getContext("2d"); function reOffset(){ var BB=canvas.getBoundingClientRect(); offsetX=BB.left; offsetY=BB.top; } var offsetX,offsetY; reOffset(); window.onscroll=function(e){ reOffset(); } var isDown=false; var isDown,startX,startY,itIsADrag; $("#canvas").mousedown(function(e){handleMouseDown(e);}); $("#canvas").mousemove(function(e){handleMouseMove(e);}); $("#canvas").mouseup(function(e){handleMouseUp(e);}); $("#canvas").mouseout(function(e){handleMouseOut(e);}); function handleMouseDown(e){ // tell the browser we''re handling this event e.preventDefault(); e.stopPropagation(); // save the mouse position at mousedown startX=parseInt(e.clientX-offsetX); startY=parseInt(e.clientY-offsetY); // initially set the "itIsADrag" flag to false itIsADrag=false; // set the "isDown" flag to true isDown=true; } function handleMouseUp(e){ // tell the browser we''re handling this event e.preventDefault(); e.stopPropagation(); // report if this was a click or a drag if(itIsADrag){ alert("You have been dragging"); }else{ alert("You''ve did a click"); } // clean up by clearing the isDown flag isDown=false; } function handleMouseOut(e){ // clean up by clearing the isDown flag isDown=false; } function handleMouseMove(e){ // return if the mouse is not down if(!isDown){return;} // tell the browser we''re handling this event e.preventDefault(); e.stopPropagation(); // get the current mouse position mouseX=parseInt(e.clientX-offsetX); mouseY=parseInt(e.clientY-offsetY); // do nothing if the mouse has moved less than 5 total pixels since mousedown if(!itIsADrag && Math.abs(mouseX-startX)+Math.abs(mouseY-startY)<5){return;} // Set the dragging flag to true // This flag prevents the Math.abs test above if we know we''re dragging itIsADrag=true; }

body{ background-color: ivory; } #canvas{border:1px solid red;}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <h4>Click or drag in the canvas.</h4> <canvas id="canvas" width=300 height=300></canvas>

Aquí tengo un ejemplo de código relacionado con mover un elemento en el lienzo. Para mover un círculo a otra posición en el lienzo, el código siguiente está comprobando si el evento de mousedown se activó en el elemento del círculo o no para que se pueda iniciar el arrastre con mousemove. Pero no entiendo la lógica que se ha usado para saber si el mouse está o no doblemente en el círculo correcto para arrastrarlo.

// start dragging function DragStart(e) { //coordinates of mouse from mousedown event e{x,y} e = MousePos(e); var dx, dy; //initialCirclePosition is the centre (x,y) of the circle dx = initialCiclePosition.x - e.x; dy = initialCiclePosition.y - e.y; if ((dx * dx) + (dy * dy) < circleRadius * circleRadius) { //Yes, user is trying to move the circle only ........ } }

Cuando el usuario mantiene el control del mouse en cualquier elemento (al hacer clic en él), ocurre un evento de mousedown. Luego, cuando intenta arrastrar el elemento, se produce el evento mousemove. Pero, antes de permitir que mousemove se active, debemos encontrar si el usuario está tratando de arrastrar el elemento correcto (círculo aquí). Si ve el código anterior, se usó la lógica en la declaración if () para verificarlo. No puedo entender esa lógica y de eso se trata la pregunta. Gracias.