Categories
Canvas event html5 javascript jQuery software libre

canvas-event: fácil interacción con el elemento canvas

Uno de los elementos HTML5 que sin duda ofrece mayores posibilidades es el elemento canvas, gracias a este es posible crear y manipular imágenes directamente en el navegador, pero a la hora de crear algo mas que imágenes estáticas  nos tropezamos con la falta de métodos para el manejo de eventos, aun así encontramos aplicaciones web que permiten la interacción por medio del teclado y el ratón.

¿Como logran esta interacción?, si vemos en el código de estas aplicaciones, todas siguen mas o menos el mismo patrón:

  1. Agregar evento mousemove al elemento canvas
  2. comparar coordenadas del cursor con las de Objetos dibujados
  3. Seleccionar objeto sobre el cual se encuentra el cursor
  4. Al ocurrir un evento, ejecutarlo sobre el Objeto seleccionado
  5. Redibujar el canvas
No es algo difícil, pero podría ser mucho mas fácil.

Con esto en mente y luego de robar algunas ideas y algo de código de otros proyectos como procesingjs, jQuery, jquery-hotkeys y canto-js, nació canvas-event, una librería que se encarga del manejo de los eventos, facilitando el desarrollo de aplicaciones interactivas en el elemento canvas; ademas cuenta con objetos predefinidos como círculos, rectángulos, rutas e imágenes entre otros.

Algunos ejemplos de lo que se puede hacer con canvas-event:

Cv = Cevent("id-canvas");

// encadenamiento de métodos
Cv.circle( 40, 40, 40 )
.attr({fill: 'red'})
.rotate( 30 );

// manejo de eventos al estilo jquery
Cv.click( function(e) {
this.fill = this.fill == 'green' ? 'red' : 'green';
});

// eventos del teclado asociados a combinación de teclas
Cv.keydown( 'ctrl+s', function(e){
alert( "el Objeto ha sido guardados");
return false;
});

// Drag and drop
Cv.ellipse( 30, 40, 50, 10 )
.drag({
start: function() { console.log( "drag start" ); },

move: function() { console.log( "move to ", this.x, this.y ); },

end: function() { console.log( "drag end" ); }
})

// identificadores de Objetos
Cv.image(50, 100, "ball.gif").addId("pelota").rect(100, 50, 20).draw();

// Recuperar elementos por su Id o tipo;
Cv.find('#pelota').attr("alpha", .5).redraw();

Cv.find('rect').click(function(){
alert( "Hola, soy un rectangulo" );
});

// Eventos live
Cv.mouseover( "#pelota", function(e){
alert( "Soy una pelota" );
});

// Este Objeto también tendrá el evento anterior
Cv.circle(175, 75, 20).addId('pelota');

Ademas, podemos definir nuestras propias figuras extendiendo el objeto Shape:

var Triangle = Cevent.Shape.extend({
// inicializador
init: function( x, y, size ){
this.size = size || 5;
this._super( x, y );
},

// ctx es el context en el que se debe dibujar
draw: function( ctx ) {

ctx.save();

// aplicamos estilo y trasformaciones
this.applyStyle( ctx );
this.setTransform( ctx );

// definimos el contexto en el cual dibujaremos
// para poder usar todos los métodos svg definidos en Cevent
// como M (move) c (cubicBlazier) etc
Cevent.beginPath( ctx )
.M( this.x, this.y )
.h( 1 * this.size )
.v( 1 * this.size )
.z();

if ( this.fill ) { ctx.fill(); }

if ( this.stroke ) { ctx.stroke(); }

ctx.restore();
}
});

// registramos el nuevo objeto
Cevent.registre( "triangle", Triangle );

// ahora podemos hacer uso del nuevo objeto
var Cv = Cevent( "canvas-id" );

Cv.triangle( 40, 30, 10 )
.attr({
fill: "#050",
alpha: .5
})
.focus(function() {
this.fill = "#999";
})
.blur(function() {
this.fill = "#050";
})
.draw();

Por el momento falta documentación pero se incluyen varios ejemplos de su uso, si tienen alguna duda y/o sugerencia por favor déjenla en los comentarios o en la pagina del proyecto en google code.

Categories
css html ie recordatorio

background transparent == problemas en IE

Este mas que un articulo es un recordatorio. Resulta que me pase todo un domingo tratando posicionar un div sobre un textarea para evitar que fuera editado; sí, ya se que para evitar que lo editen solo hay que usar el atributo disabled, pero en algunos navegadores esto no evita que el texto se pueda seleccionar.


Los oscuros motivos que me llevaron a intentar esto son irrelevantes, lo importante es que en la mayoria de exploradores la solucion fue muy sencilla: un div con posición absoluta y background transparente sobre el textarea y listo; pero no contaba con el siempre querido internet explorer (en todas sus presentaciones); resulta que al tener el div un background transparente, era como si colocara un marco sobre el textarea, por en medio del cual el cursor podía seleccionar todo lo de su interior (osease, no servia para nada); después de mucha lucha, cuando ya estaba a punto de rendirme, probé cambiando el color de fondo del div por blanco y como por arte de magia todo funciono, pero el contenido del textarea quedo oculto.

La solucion fue muy simple, ya que no podia usar un el background transparente use un png y listo todo funciono como quería.
/* en ie hace comportar al elemento como un marco */
div {
background: transparent;
}

/* esto si funciona */
div {
background: url(png-transparente.png);
}

Si algún día les sucede algo parecido quedan advertimos u_u