Arrastrar y soltar

facebook-svg gplus-svg twitter-svg

Una de las cosas muy divertidas que podemos hacer en el <canvas> de HTML5 es mover objetos. Empezamos con un ejemplo fácil. Después de dibujar una estrella vamos a arrastrarla y soltarla en otro punto del <canvas>.

Dibujar una estrella

Para dibujar una estrella hemos escrito la función dibujarUnaEstrella(). Para entender mejor esta función por favor vea como dibujar estrellas en el <canvas> de HTML5


function dibujarUnaEstrella(R,L,paso,X,Y){
               ctx.fillStyle = "#6ab150";
               var estrella= L / paso
               var rad = (2*Math.PI) / estrella;
                                                   
               ctx.beginPath();
                     for( var i = 0; i < L; i++ ){
                     x = X + R * Math.cos( rad*i );
                     y = Y + R * Math.sin( rad*i );
                     ctx.lineTo(x, y);
                     }
               ctx.closePath();
               ctx.fill();
}

Vamos a utilizar también la función oMousePos() que ya hemos utilizado varias veces.
La función oMousePos() detecta la posición del ratón en el <canvas> y devuelve un objeto con las coordinadas x e y de este.


function oMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
		return {// devuelve un objeto
		x: Math.round(evt.clientX - rect.left),
		y: Math.round(evt.clientY - rect.top)
		};
}

Eventos del ratón utilizados:

Para arrastrar y soltar necesitamos:

  • 1. Presionar el botón del ratón, para "coger" el objeto. El evento del ratón involucrado en este caso es mousedown ( literalmente : ratón abajo ).
  • 2. Mantener presionado y arrastrar el ratón a la ubicación deseada. El evento del ratón involucrado en este caso es mousemove (literalmente : ratón moviendose).
  • 3. Soltar el objeto arrastrado, soltando el botón del ratón. El evento del ratón involucrado en este caso es mouseup. ( literalmente : ratón arriba ).
  • Si queremos podemos también tomar en consideración la salida del ratón del <canvas>: mouseout (literalmente : ratón fuera).

canvas.addEventListener("mousedown", function(evt) {
// haz algo
}, false);

canvas.addEventListener("mousemove", function(evt) {
// haz otra cosa
}, false);

canvas.addEventListener("mouseup", function(evt) {
// haz algo más
}, false);';

Poniendolo todo junto

Dibujamos una estrella

Al presionar el botón del ratón (mousedown)

  • - Detectamos la posición del ratón (el punto delta).
  • - Volvemos a dibujar la estrella.
  • - Utilizando el método isPointInPath() nos aseguramos que el usuario hizo clic sobre la estrella.
  • - Si hizo clic sobre la estrella arrastrar = true (podemos arrastrar).
  • - Calculamos la distancia entre el punto delta y el centro de la estrella y la guardamos en una variable (var delta).

Al mover el ratón (mousemove)

  • - Detectamos la posición del ratón en cada momento.
  • - Si podemos arrastrar if(arrastrar) limpiamos el canvas con clearRect().
  • - Volvemos a calcular la posición del centro de la estrella en función de la posición del ratón y la distancia entre el punto delta y el centro de la estrella.
  • - Dibujamos de nuevo la estrella.

Al soltar el botón del ratón (mouseup) arrastrar = false (ya no podemos arrastrar).

Su navegador no soporta canvas :( 

var canvas = document.getElementById("lienzo");
if (canvas && canvas.getContext) {
  var ctx = canvas.getContext("2d");
  if (ctx) {
    var arrastrar = false;
    var delta = new Object();
    var L = 5;
    var paso = 2;
    var R = 100;
    var X = canvas.width / 2;
    var Y = canvas.height / 2;

    function dibujarUnaEstrella(R, L, paso, X, Y) {

      ctx.fillStyle = "#6ab150";
      var estrella = L / paso
      var rad = (2 * Math.PI) / estrella;

      ctx.beginPath();
      for (var i = 0; i < L; i++) {
        x = X + R * Math.cos(rad * i);
        y = Y + R * Math.sin(rad * i);
        ctx.lineTo(x, y);
      }
      ctx.closePath();
      ctx.fill();
    }

    dibujarUnaEstrella(R, L, paso, X, Y);

    function oMousePos(canvas, evt) {
      var rect = canvas.getBoundingClientRect();
      return { // devuelve un objeto
        x: Math.round(evt.clientX - rect.left),
        y: Math.round(evt.clientY - rect.top)
      };
    }

    canvas.addEventListener("mousedown", function(evt) {
      var mousePos = oMousePos(canvas, evt);

      dibujarUnaEstrella(R, L, paso, X, Y);
      if (ctx.isPointInPath(mousePos.x, mousePos.y)) {
        arrastrar = true;
        delta.x = X - mousePos.x;
        delta.y = Y - mousePos.y;
      }
    }, false);

    canvas.addEventListener("mousemove", function(evt) {
      var mousePos = oMousePos(canvas, evt);

      if (arrastrar) {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        X = mousePos.x + delta.x, Y = mousePos.y + delta.y

        dibujarUnaEstrella(R, L, paso, X, Y);
      }
    }, false);

    canvas.addEventListener("mouseup", function(evt) {
      arrastrar = false;
    }, false);
  }
}
Su navegador no soporta canvas :(

A continuación haremos lo mismo, pero esta vez vamos a dibujar y arrastrar varias estrellas. Continúa leyendo...