viernes, 19 de noviembre de 2010

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:
  1. Cv = Cevent("id-canvas");  
  2.   
  3. // encadenamiento de métodos  
  4. Cv.circle( 40, 40, 40 )  
  5. .attr({fill: 'red'})  
  6. .rotate( 30 );  
  7.   
  8. // manejo de eventos al estilo jquery  
  9. Cv.click( function(e) {  
  10.   this.fill = this.fill == 'green' ? 'red' : 'green';  
  11. });  
  12.   
  13. // eventos del teclado asociados a combinación de teclas  
  14. Cv.keydown( 'ctrl+s'function(e){  
  15.   alert( "el Objeto ha sido guardados");  
  16.   return false;  
  17. });  
  18.   
  19. // Drag and drop  
  20. Cv.ellipse( 30, 40, 50, 10 )  
  21. .drag({  
  22.   start: function() { console.log( "drag start" ); },  
  23.     
  24.   move: function() { console.log( "move to "this.x, this.y ); },  
  25.   
  26.   end: function() { console.log( "drag end" ); }  
  27. })  
  28.   
  29. // identificadores de Objetos  
  30. Cv.image(50, 100, "ball.gif").addId("pelota").rect(100, 50, 20).draw();  
  31.   
  32. // Recuperar elementos por su Id o tipo;  
  33. Cv.find('#pelota').attr("alpha", .5).redraw();  
  34.   
  35. Cv.find('rect').click(function(){  
  36.   alert( "Hola, soy un rectangulo" );  
  37. });  
  38.   
  39. // Eventos live  
  40. Cv.mouseover( "#pelota"function(e){  
  41.    alert( "Soy una pelota" );  
  42. });  
  43.   
  44. // Este Objeto también tendrá el evento anterior  
  45. Cv.circle(175, 75, 20).addId('pelota');  
Ademas, podemos definir nuestras propias figuras extendiendo el objeto Shape:
  1. var Triangle = Cevent.Shape.extend({  
  2.   // inicializador  
  3.   init: function( x, y, size ){  
  4.     this.size = size || 5;  
  5.     this._super( x, y );  
  6.   },  
  7.   
  8.   // ctx es el context en el que se debe dibujar  
  9.   draw: function( ctx ) {  
  10.   
  11.     ctx.save();  
  12.   
  13.     // aplicamos estilo y trasformaciones  
  14.     this.applyStyle( ctx );  
  15.     this.setTransform( ctx );  
  16.   
  17.     // definimos el contexto en el cual dibujaremos  
  18.     // para poder usar todos los métodos svg definidos en Cevent  
  19.     // como M (move) c (cubicBlazier) etc  
  20.     Cevent.beginPath( ctx )  
  21.     .M( this.x, this.y )  
  22.     .h( 1 * this.size )  
  23.     .v( 1 * this.size )  
  24.     .z();  
  25.   
  26.     if ( this.fill ) { ctx.fill(); }  
  27.   
  28.     if ( this.stroke ) { ctx.stroke(); }  
  29.   
  30.     ctx.restore();  
  31.   }  
  32. });  
  33.   
  34. // registramos el nuevo objeto  
  35. Cevent.registre( "triangle", Triangle );  
  36.   
  37. // ahora podemos hacer uso del nuevo objeto  
  38. var Cv = Cevent( "canvas-id" );  
  39.   
  40. Cv.triangle( 40, 30, 10 )  
  41. .attr({  
  42.   fill: "#050",  
  43.   alpha: .5  
  44. })  
  45. .focus(function() {  
  46.   this.fill = "#999";  
  47. })  
  48. .blur(function() {  
  49.   this.fill = "#050";  
  50. })  
  51. .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.

martes, 2 de noviembre de 2010

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.
  1. /* en ie hace comportar al elemento como un marco */  
  2. div {  
  3.   backgroundtransparent;  
  4. }  
  5.   
  6. /* esto si funciona */  
  7. div {  
  8.   backgroundurl(png-transparente.png);  
  9. }  
Si algún día les sucede algo parecido quedan advertimos u_u
 
© 2009 NovatoZ. All Rights Reserved | Powered by Blogger
Design by psdvibe | Bloggerized By LawnyDesignz