- Set texture to Texture.EMPTY before destroying sprites in
AnimatedGifSprite and PdfPageSprite (matches VideoSprite pattern)
- Add full-screen loading overlay that blocks interaction until
scene and assets finish loading
Override destroy() in AnimatedGifSprite to call releaseGif() when
a loaded GIF item is deleted from the board. Without this, the
gifCache refCount stays elevated until full canvas teardown.
1. Move GIF loading behind TextureManager.loadGif/releaseGif with
ref-counting (fixes shared-source invalidation on duplicate GIFs)
2. Strip query strings/fragments before .gif extension check
3. GIFs now load paused — separate MAX_PLAYING_GIFS=8 budget in
culling system, only nearest N animate (others show static frame)
Register GifAsset extension for .gif loading, create AnimatedGifSprite
wrapper with lazy load/unload matching ImageSprite pattern, and detect
.gif assets in SceneManager to use animated rendering. GIFs stored as
type 'image' in scene format — no schema changes needed.