2012-06-19 3 views
6

Ich erstelle eine Anwendung mit fabric.js, und erlebt wirklich seltsames Verhalten. Ich füge sowohl Bilder als auch Textinstanzen unter Verwendung der regulären fabric.Canvas (nicht fabric.StaticCanvas) hinzu und kann diese Elemente nach dem Hinzufügen nicht verschieben oder ihre Größe ändern. Ich habe nur ein paar von jedem Typ hinzugefügt. Die Basisfunktionalität wird in einem Rückruf eingewickelt auf einigen Tasten gebunden an ein Click-Ereignis, aber die Core Fabric-Funktionalität sieht ungefähr so ​​aus (vereinfachte, aber fast alle sind gleich so weit wie Stoff bezogenen Code):FabricJS Canvas ist nach dem Hinzufügen von Elementen "stecken geblieben"

<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(); 
    }); 
}); 

Der obige Code rendert die Elemente gut, aber sie können nicht skaliert oder bewegt werden und wirken statisch. Das seltsame Ding ist, dass, wenn ich mein chrome dev-panel öffne und schließe (mit F12 oder [Ctrl/CMD] + SHIFT + I zweimal), die Leinwand wieder funktioniert und alles wieder funktioniert. Ich habe auch ein paar Server-Sachen (das ist nur eine Probe von dem, was ich mache), aber ich habe keine Ahnung, wie ich das weiter auf dieses seltsame Verhalten zurückführen kann. Ich benutze den neuesten Code (gebaut von Github Repo). Gedanken?

+2

Es ist möglich, dass Leinwand interne Offset ordnungsgemäß nicht aktualisiert. Ein Element auf der Seite kann die Abmessungen/Position ändern, sodass die Arbeitsfläche an einer anderen Position positioniert wird als während der Initialisierung. Versuchen Sie, 'canvas.calcOffset()' nach dem Aufruf 'renderAll' oder nach dem Hinzufügen dieser Objekte aufzurufen. – kangax

+0

Das hat es gelöst! Aus Neugier - warum heißt es nicht innerhalb von 'renderAll()'? Bitte fügen Sie es als Antwort hinzu, damit ich es abzeichnen kann - und danke! – sa125

+1

Sicher, hinzugefügt, mit Erklärung. Froh, dass es geholfen hat. – kangax

Antwort

22

Es ist möglich, dass der Canvas-interne Offset nicht ordnungsgemäß aktualisiert wird. Ein Element auf der Seite kann die Abmessungen/Position ändern, sodass die Arbeitsfläche an einer anderen Position positioniert wird als während der Initialisierung. Versuchen Sie, canvas.calcOffset() nach renderAll() Aufruf oder nach dem Hinzufügen dieser Objekte aufzurufen.

Der Grund calcOffset wird nicht in renderAll genannt, ist aus Leistungsgründen. renderAll ist eine Neuzeichnung eines gesamten Canvas. Es passiert jedes Mal, wenn sich etwas auf der Leinwand und der Leinwand verändert. Wie Sie sich vorstellen können, wird es ziemlich oft aufgerufen (manchmal Dutzende von Malen pro Sekunde), und es wäre ziemlich verschwenderisch, bei jeder Neuzeichnung einen neuen Offset zu berechnen.

Beachten Sie auch, dass sich die Canvas-Position in den meisten Fällen nicht im gesamten Seitenleben ändert. Es passiert wahrscheinlich ziemlich selten. Hauptsächlich während des Ladens der Seite.

In einer hochdynamischen Umgebung - in der Canvas häufig die Position ändert - können Sie das Offset- "Problem" lösen, indem Sie explizit calcOffset() aufrufen.

7

Ich hatte das gleiche Problem, zusätzlich zu Kangax-Lösung, in einer sehr extremen Umgebung, können Sie es zwingen, den Offset jederzeit zu berechnen, wenn das Rendern auftritt, mit einem Ereignis.

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