batiste / sprite.js

An efficient javascript sprite animation framework
MIT License
871 stars 98 forks source link

Sprite z ordering. #20

Closed thybag closed 12 years ago

thybag commented 12 years ago

Hello,

More a question than a proper feature request but;

I'm currently working on a game using your framework and came across the need to get a little more control over the z ordering of sprites (ideally without having to resort to giving everything its own layer.)

My issue is essentially that I'm creating units within my game that consist of 2 or 3 separate sprites each, and thus to ensure they display right I need to the sprites have a specific z-order. Initially I just added the sprites in the correct order when i created them (which for the dom render method seems to work fine). But later in the game, when i wanted to switch out one of the sprites i noticed there was no proper method for adjusting the z-ordering.

For my own usage I've added a very basic toFront and toBack method (code)on the sprites, which works by moving the dom nodes location. Although I'm not really sure if this will be much use to anyone else as i couldn't think how to get similar behaviour to work for canvas or webgl.

Are there any plans to any add similar functionality in to the main codebase at all, or is this a bit of a fringe feature?

Thanks, Carl

batiste commented 12 years ago

Hi!

I would avoid to manipulate the DOM the way you do it because I believe it could be very "slow" to do so. I have no proof because I didn't test it but you can probably make a test using the particle test.

As you know there is no z-index property right now with Sprite.js. With the HTML backend it would be quite easy to implement, you could just change the z-index property of the dom element. It shouldn't be a lot more complicated that the code you already written:

Sprite.prototype.toFront = function() { this.layer.lastZIndex = this.layer.lastZIndex + 1; this.setZIndex(this.layer.lastZIndex); };

And then change what is necessary in the update method:

if (this._dirty.zIndex) style.zIndex=this.zIndex;

For the canvas backend it could be more complicated. The only way I see this to happen would be to record all the draw/update events on the sprite and delaying them till the end of the paint event so the z-index can be emulated there. This is possible but it requires quite a bit of work.

I would gladly merge your code in the main branch, but I need to know which method is the fastest. As I said I have a strong intuition that manipulating the DOM will be way slower than just changing the CSS property.

Cheers

thybag commented 12 years ago

Thanks for getting back to me, plus I'd be happy to do a little benchmarking.

The reason I avoided using the zIndex initially was because (I'm not 100% sure if I'm correct on this) it would end up throwing the layers out of z-order since they are only 1 z-index apart (although i may test that as thinking about it I'm not sure the z-index of childnodes would actually end up having any effect on the ordering of the parent nodes). I'll do some testing anyway as the z-index does open up the possibility of simplifying any fine control over the z-order.

Thanks again, Carl

thybag commented 12 years ago

Hello,

I've spend a bit of time playing around with it the code and it looks like your suggested method (using the z-indexs) does make quite a bit more scene than my initial DOM swapping solution.

In terms of how they perform, I took your advice and modified the particle test to invoke the toFront method using the two implementations.

Chrome: Dom swapping: 590-620 particles z-index: 1000-1200 particles Firefox 11: Dom swapping: 300-314 particles z-index: 450-500 particles

Its a little rough, but it shows quite clearly that using the z-index to order items has the performance edge :)

I've committed the updated solution here: https://github.com/thybag/sprite.js/commit/9465c05e0db1850e63cf2bd270672b619e78e481

Thanks again, Carl