2011-08-04 19 views
5

estoy usando este script:Fabric.js - problema con el dibujo de varias imágenes ZIndex

var canvas = new fabric.Canvas('game_canvas', { selection: false }); 

fabric.Image.fromURL('images/bg.jpg', function(img) { 
    img.set('left', 1024/2).set('top', 600/2).set('zindex', 0); 
    canvas.add(img);   
}); 

fabric.Image.fromURL('images/panel-2-bg-l-r.png', function(img) { 
    img.set('left', 262/2).set('top', (390/2)+110).set('zindex', 1); 
    canvas.add(img);   
}); 

fabric.Image.fromURL('images/player-board.png', function(img) { 
    img.set('left', 254/2).set('top', (122/2)).set('zindex', 2); 
    canvas.add(img);   
}); 

fabric.Image.fromURL('images/player-board-top-red.png', function(img) { 
    img.set('left', 203/2).set('top', (109/2)).set('zindex', 3); 
    canvas.add(img).bringToFront(img);   
}); 

tercera imagen Drenaje está funcionando correctamente y que muestra una encima de la otra. Pero si agrego el 4to, se esconde detrás del tercero. Si especifico el zindex de la imagen, aún está debajo del 3er.

¿Qué pasa con esto? ¿Estoy haciendo algo mal aquí? Por favor ayuda.

Gracias
Peter

Respuesta

10

Hay dos cuestiones aquí.

1) No puede cambiar el zindex de las imágenes estableciendo su propiedad zindex. Las imágenes de la tela simplemente no tienen esa propiedad y su cambio no cambia el índice z de las imágenes en el lienzo. Esto hace que todos esos .set('zindex', 0), .set('zindex', 1), etc. prácticamente no hace falta.

2) bringToFront funciona como se esperaba aquí, llevando la última imagen hasta la parte superior de la pila de dibujos. Pero el problema es que la imagen "images/player-board-top-red.png" que está cargando por última vez es y no se garantiza que sea la última que se haya agregado. Esas 4 solicitudes son asincrónicas; vienen en cualquier orden, por lo que las devoluciones de llamada se ejecutan en cualquier orden también. En mi prueba, por ejemplo, la última imagen viene en segundo lugar, la devolución de llamada se ejecuta, la imagen se lleva al frente, pero luego se "sobrescribe" al seguir 2 devoluciones de llamada.

¿Cómo hacer que la última imagen se renderice en la parte superior? Bueno, podemos simplemente verificación de que todas las imágenes se cargan antes de intentar llevar último en la parte superior:

var img4; 
// ... 
function checkAllLoaded() { 
    if (canvas.getObjects().length === 4) { 
    canvas.bringToFront(img4); 
    } 
} 
// ... 
fabric.Image.fromURL('images/1.png', function(img) { 
    img.set('left', 0).set('top', 0); 
    canvas.add(img); 
    checkAllLoaded(img); 
}); 
// load other images, making sure to include `checkAllLoaded` in callback 
fabric.Image.fromURL('images/4.png', function(img) { 
    img4 = img.set('left', 0).set('top', 0); 
    canvas.add(img); 
    checkAllLoaded(img); 
}); 

Por cierto, no se olvide que usted puede pasar un objeto a set método de este modo:

img.set({ left: ..., top: ... }); 

y puesto que es set conexión en cadena y devuelve referencia a una instancia, incluso se lo puede transmitir a add así:

canvas.add(img.set({ left: ..., top: ... })); 

Espero que esto ayude.

+1

sí su respuesta me dio un básico de imágenes de renderizado sobre lienzo . Gracias :) Ahora precargué todas las imágenes antes de renderizarlas en lienzo. – peterkr

+0

Sin salida agregue _kangax_ un comentario, así que ... Dibujará muchas imágenes en lienzo, ¿Cuáles serán los problemas asíncronos? Cuando dibuje ('canvas.add (oImg)') un elemento, 'sum ++', Utilizo la imagen de carga 'fromUrl', _callback_ implement [jsfiddle] (https://jsfiddle.net/Charles_/y6b2yrng/3/) – Charles

4

Puede usar canvas.insertAt(object,index); en lugar de canvas.add(object) para establecer el zIndex del objeto según su elección.

También usted puede conseguir cualquier objeto mediante el uso de:

canvas_object = canvas.item(index); 

Si usted quiere traer a ese objeto delante, utilice:

canvas_object.bringForward() 

//or 

canvas_object.bringToFront() 
Cuestiones relacionadas