2012-06-19 24 views
6

Tôi đang tạo ứng dụng bằng cách sử dụng fabric.js và gặp phải hành vi thực sự lạ. Tôi đang thêm cả hình ảnh và văn bản, sử dụng thông thường fabric.Canvas (không phải fabric.StaticCanvas) và không thể di chuyển hoặc đổi kích thước các mục này sau khi thêm. Tôi chỉ thêm một vài loại. Các chức năng cơ bản được bọc trong một callback gắn liền với một sự kiện click trên một số nút, nhưng chức năng vải lõi trông giống như thế này (giản thể, nhưng hầu như tất cả mọi thứ là như nhau như xa như vải mã liên quan):Vải FabricJS bị "kẹt" sau khi thêm các thành phần

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

Đoạn mã trên hiển thị các phần tử tốt, nhưng chúng không thể thay đổi kích cỡ hoặc di chuyển xung quanh và hoạt động tĩnh. Điều lạ lẫm là nếu tôi mở và đóng bảng điều khiển chrome của mình (sử dụng F12 hoặc [Ctrl/CMD] + SHIFT + I hai lần), canvas sẽ lấy lại chức năng và mọi thứ hoạt động trở lại. Tôi có một số công cụ serverside xảy ra là tốt (đây chỉ là một mẫu giả của những gì tôi đang làm), nhưng tôi không có ý tưởng làm thế nào để tiếp tục theo dõi này xuống hành vi kỳ lạ này. Tôi đang sử dụng mã mới nhất (được xây dựng từ repo github). Suy nghĩ?

+2

Có thể bù đắp nội bộ canvas không được cập nhật đúng cách. Một cái gì đó trên trang có thể thay đổi kích thước/vị trí, làm cho canvas được đặt ở vị trí khác với vị trí trong quá trình khởi tạo. Hãy thử gọi 'canvas.calcOffset()' sau lệnh 'renderAll' hoặc sau khi thêm các đối tượng đó. – kangax

+0

Điều đó đã giải quyết được! Trong tò mò - tại sao nó không được gọi bên trong 'renderAll()'? Vui lòng thêm nó làm câu trả lời để tôi có thể đánh dấu nó - và cảm ơn! – sa125

+1

Chắc chắn, được thêm vào, với lời giải thích. Vui mừng nó đã giúp. – kangax

Trả lời

22

Có khả năng bù đắp nội bộ canvas không được cập nhật đúng cách. Một cái gì đó trên trang có thể thay đổi kích thước/vị trí, làm cho canvas được đặt ở vị trí khác với vị trí trong quá trình khởi tạo. Thử gọi canvas.calcOffset() sau khi gọi renderAll() hoặc sau khi thêm các đối tượng đó.

Lý do calcOffset không được gọi trong số renderAll là vì lý do hiệu suất. renderAll là vẽ lại toàn bộ canvas. Nó xảy ra mỗi khi có thay đổi gì đó trên canvas và canvas cần được vẽ lại. Như bạn có thể tưởng tượng, nó được gọi khá thường xuyên (đôi khi hàng chục lần mỗi giây), và nó sẽ là khá lãng phí để tính toán bù đắp mới mỗi khi vẽ lại xảy ra.

Cũng nên xem xét rằng trong hầu hết các trường hợp vị trí canvas không thay đổi trong suốt thời gian của trang. Nó có thể xảy ra khá hiếm khi. Chủ yếu trong khi tải trang.

Trong môi trường năng động cao - nơi canvas thay đổi vị trí thường xuyên - bạn có thể giải quyết lỗi "sự cố" bằng cách gọi rõ ràng calcOffset().

7

Tôi đã có cùng một vấn đề, trong adition để giải pháp kangax, trong một môi trường cực kỳ cực đoan, bạn có thể buộc nó tính toán lại bất cứ lúc nào kết xuất xảy ra, với một sự kiện.

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

Các vấn đề liên quan