giniedp / spritespin

jQuery plugin for spriteanimation.
http://giniedp.github.com/spritespin/
MIT License
377 stars 122 forks source link

Browser locks up (no scroll) when DOM is updated with stage and canvas elements #47

Open danhumaan opened 6 years ago

danhumaan commented 6 years ago

I'm running into a bit of a problem where as the plugin initialises, it loads all the images but then locks up the browser and I can't scroll until it's updated the DOM and injected the spritespin-stage and spritespin-canvas elements. Other elements that animate (in or out of viewport) also freeze in the last DOM update state.

I have 225 frames, each ~53kb so a total of about 12mb. Given the weight, i'm not initialising the instance on page load, but waiting until the user has reached it near enough. I've notice that it doesn't happen, or isn't as noticeable if I reduce the number of frames. but it still happens. It happens regardless of whether i init on page load, or on scroll.

I also don't have a visible loading indicator (not by choice - side question: how do I get this in there?) and could this be part of the problem?

Have you experienced this before, and if so what would be the best method to stop it occurring, or debug why the SpriteSpin is locking up the browser when the new markup is being injected.

giniedp commented 6 years ago

Can you explain the "lock up" in more detail? I'm asking, because on mobile devices you cant swipe over the spritespin container to scroll, you have to double tap'n'scroll. So my question is, does the "lock up" as you say, a mobile device issue, or does it happen on desktop also? If this also occurs on desktop, could you try to set the option detectSubsampling to false, and see if that helps?

If you want to show a loading indicator, you can use CSS. During the loading phase, the container will have the "loading" CSS class attached, so you can style your container with it.

If you want a progress bar you can utilise the onProgress callback which is called every time an image is finished loading. The arguments contain the spritespin data, which in turn contains a progress object where you can find the progress counting state. From this you can build your own progress indicator showing the percentage.

danhumaan commented 6 years ago

hey @giniedp

Thanks for the quick reply. The lock up happens on desktop (macOS Sierra) in Chrome 65 - other browsers untested as of yet.

The best way to describe it is, if I am scrolling down the page as the instance is being loaded and as spritespin-stage and spritespin-canvas are being added to the DOM, the scrolling along with other page acitivity and browser-based feedback stop entirely like the browser freezes up.

I could be scrolling the page, I could be scrolling the inspector, it all stops momentarily. I also have render FPS meter open and that also freezes, leading me to believe it's at a higher level than just the individual page.

As for your your suggestion regarding detectSubsampling to false, that appears to have completely fixed the problem we were having, so first of all thank you for that! I'll treat the issue as fixed for the moment until I can test other browsers in more depth. But I suppose it is worth noting that, that setting seems to be the trigger for the behaviour occuring when I set it back to true, it happens once more.

In case you were curious, this is the JS we're using to initialise the spritespin instance:

$('#my-id').spritespin({
    source: SpriteSpin.sourceArray('./img/path/to/asset_{frame}.jpg', {
        frame: [0, 179],
        digits: 3
    }),
    animate: false,
    detectSubsampling: false,
    width: 1600,
    height: 1040,
    frame: 1,
    sense: 1
});

Side note, thanks for the tip on loading, we'll work that in as well 👍 Your tip on the api playTo previously and onFrame check has also worked perfectly. Thanks again for a great plugin, it's so far ticked all the boxes we were looking for in our unique interface.

giniedp commented 6 years ago

thanks for reporting. This is an issue with the detect subsampling code then.

Some Browsers (iOS Safari) might reduce the image resolution, if the image is too large. But the image object would still tell us its original width and height. This is then a problem when rendering the images to canvas

To avoid that, SpriteSpin has a subsampling detection code https://github.com/giniedp/spritespin/blob/master/src/utils/detectSubsampling.ts#L25

However, the usage of the code is not optimized. I think SpriteSpin runs the algorithm on every image, which locks down the browser.

giniedp commented 6 years ago

In your case the image is 1600x1040 i think it is safe to run SpriteSpin without subsampling detection in this case. Safari would subsample the image if it exceeds 2Megapixels (210241024)

danhumaan commented 6 years ago

Awesome, glad we were able to help identify and area for optimisation. Thanks again mate!