2012-06-19 8 views
6

Estoy creando una aplicación usando fabric.js, y estoy experimentando un comportamiento realmente extraño. Estoy agregando imágenes y ejemplos de texto, usando el fabric.Canvas normal (no el fabric.StaticCanvas), y no puedo mover o cambiar el tamaño de estos elementos después de la adición. Solo he agregado un par de cada tipo. La funcionalidad básica se envuelve en una devolución de llamada atado a un evento click en algún botón, pero la funcionalidad de tela núcleo se ve algo como esto (simplificado, pero casi todo es lo mismo por lo que el código relacionado con tela):El lienzo de FabricJS está "atascado" después de agregar los elementos

<canvas id="myCanvas" height=600 width=800></canvas> 
<input id="addStuff" type="button" value="Add!" /> 
.... 
var canvas = new fabric.Canvas('myCanvas'); 
canvas.renderOnAddition = true; 

$(function(){ 
    $('#addStuff').on('click', function(e) { 

     var text = new fabric.Text("Hello, world", { 
     top  : 100, 
     left  : 100, 
     fontSize : 12, 
     fontFamily : 'Delicious_500' 
     }); 
     text.hasControls = false; 

     canvas.add(text); 

     fabric.Image.fromURL('./img/pic.png', function(img) { 
     var imgX = img.set({ 
      top: 200, 
      left: 100, 
     }); 

     canvas.add(imgX); 
     }); 

     canvas.renderAll(); 
    }); 
}); 

El código anterior representa bien los elementos, pero no se pueden cambiar de tamaño ni moverse, y actuar de forma estática. Lo extraño es que si abro y cierro mi dev-panel de Chrome (usando F12 o [Ctrl/CMD] + SHIFT + I dos veces), el lienzo recupera la funcionalidad y todo vuelve a funcionar. Tengo algunas cosas del lado del servidor también (esto es solo una muestra falsa de lo que estoy haciendo), pero no tengo idea de cómo seguir el rastro de este extraño comportamiento. Estoy usando el código más reciente (construido desde github repo). ¿Pensamientos?

+2

Es posible que la lona offset interno y no se actualiza correctamente. Algo en la página podría cambiar las dimensiones/posición, haciendo que el lienzo se coloque en una ubicación diferente a la que tenía durante la inicialización. Intenta llamar a 'canvas.calcOffset()' después de la llamada 'renderAll', o después de agregar esos objetos. – kangax

+0

¡Eso lo resolvió! Por curiosidad, ¿por qué no se llama dentro de 'renderAll()'? Por favor, agrégalo como respuesta para que pueda marcarlo, ¡y gracias! – sa125

+1

Claro, agregado, con explicación. Me alegro de que haya ayudado. – kangax

Respuesta

22

Es posible que el desplazamiento interno del lienzo no se actualice correctamente. Algo en la página podría cambiar las dimensiones/posición, haciendo que el lienzo se coloque en una ubicación diferente a la que tenía durante la inicialización. Intente llamar al canvas.calcOffset() después de la llamada renderAll(), o después de agregar esos objetos.

El motivo calcOffset no se llama en renderAll es por motivos de rendimiento. renderAll es un redibujado de un lienzo completo. Sucede cada vez que algo cambia en el lienzo y el lienzo debe volver a dibujarse. Como se puede imaginar, se llama con bastante frecuencia (a veces docenas de veces por segundo), y sería un desperdicio de tiempo calcular el nuevo desplazamiento cada vez que ocurra el redibujado.

Considere también que, en la mayoría de los casos, la posición del lienzo no cambia a lo largo de la vida de la página. Probablemente sucede muy raramente. Principalmente durante la carga de la página.

En un entorno altamente dinámico, donde el lienzo cambia de posición a menudo, puede resolver el "problema" de desplazamiento llamando explícitamente al calcOffset().

7

Tuve el mismo problema, además de la solución de kangax, en un entorno MUY extremo, puede forzarlo a volver a calcular el desplazamiento en cualquier momento que ocurra el renderizado, con un evento.

canvas.on('after:render', function(){ this.calcOffset(); });

Cuestiones relacionadas