2012-06-19 4 views
6

Tworzę aplikację przy użyciu fabric.js i doświadczam naprawdę dziwnego zachowania. Dodaję zarówno obrazy, jak i instancje tekstowe, używając zwykłego fabric.Canvas (nie fabric.StaticCanvas) i nie jestem w stanie przenieść ani zmienić ich rozmiaru po dodaniu. Dodałem tylko kilka każdego rodzaju. Podstawowa funkcjonalność jest zawinięty w zwrotnego przywiązany do zdarzenia click na jakiegoś przycisku, ale funkcjonalność rdzeń tkanina wygląda mniej więcej tak (uproszczony, ale prawie wszystko jest takie samo ile kodu związanego tkaniny):Płaszczyzna FabricJS "utknęła" po dodaniu elementów

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

Powyższy kod poprawnie renderuje elementy, ale nie można ich zmienić ani przesuwać, i działają statycznie. Dziwne jest to, że jeśli otworzę i zamknę mój chrome-dev-panel (używając F12 lub [Ctrl/CMD] + SHIFT + I dwa razy), płótno odzyska funkcjonalność i wszystko znowu zadziała. Mam również coś na serwerach (to tylko fałszywa próbka tego, co robię), ale nie mam pojęcia, jak dalej prześledzić to dziwne zachowanie. Używam najnowszego kodu (zbudowanego z repozytorium github). Myśli?

+2

Możliwe, że przesunięcie wewnętrzne płótna nie jest poprawnie aktualizowane. Coś na stronie może zmienić wymiary/pozycję, dzięki czemu płótno zostanie umieszczone w innym miejscu niż to, które było podczas inicjalizacji. Spróbuj wywołać 'canvas.calcOffset()' po wywołaniu 'renderAll' lub po dodaniu tych obiektów. – kangax

+0

To rozwiązało! Z ciekawości - dlaczego nie jest wywoływana wewnątrz 'renderAll()'? Dodaj ją jako odpowiedź, aby ją oznaczyć - i dzięki! – sa125

+1

Pewnie, dodał, z wyjaśnieniem. Cieszę się, że to pomogło. – kangax

Odpowiedz

22

Możliwe, że przesunięcie wewnętrzne płótna nie jest poprawnie aktualizowane. Coś na stronie może zmienić wymiary/pozycję, dzięki czemu płótno zostanie umieszczone w innym miejscu niż to, które było podczas inicjalizacji. Spróbuj wywołać canvas.calcOffset() po wywołaniu renderAll() lub po dodaniu tych obiektów.

Powód calcOffset nie jest wywoływany w renderAll ze względu na wydajność. renderAll to przerysowanie całego płótna. Zdarza się to za każdym razem, gdy coś zmienia się na płótnie i płótnie, należy przerysować. Jak można sobie wyobrazić, jest wywoływana dość często (czasami kilkadziesiąt razy na sekundę), a obliczanie nowego przesunięcia za każdym razem, gdy nastąpi odrysowanie, byłoby dość niecelowe.

Należy również pamiętać, że w większości przypadków pozycja na płótnie nie zmienia się przez cały okres użytkowania strony. Zdarza się to dość rzadko. Głównie podczas ładowania strony.

W środowisku wysoce dynamicznym - gdzie płótno często zmienia położenie - można rozwiązać problem "odsunięcia" poprzez jawne wywołanie calcOffset().

7

Miałem ten sam problem, w połączeniu z rozwiązaniem kangax, w bardzo ekstremalnym środowisku można zmusić go do ponownego obliczenia przesunięcia w dowolnym momencie renderowania, ze zdarzeniem.

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