mirror of
https://github.com/PR0M3TH3AN/Artstr-Studio.git
synced 2026-11-03 12:10:39 +00:00
Add an inline GIF89a decoder - the mirror of the existing encoder, so still no vendored dependency - and wire it into "From image / GIF...". Every frame of an animated GIF becomes a frame in the pixel editor. A browser <img> only ever exposes frame 0 to canvas, so decoding is the only route to the rest; the decoder covers LZW, interlacing, local colour tables, transparency and all three disposal methods. The whole animation is quantized against one shared palette (per-frame palettes made colours shimmer and burned through the 256-entry cap), playback FPS is derived from the median GIF frame delay, and a Frames control samples long animations down evenly. Frame count and working resolution are bounded so a large GIF cannot exhaust memory, and whatever gets dropped is reported rather than silently truncated. Fix the reported pixel-editor import bugs: - Dead canvas. applyLayout() tore the pixel editor down before its "layout unchanged" early return, and only the render() at the end rebuilds a standalone one - so clicking Pixel art while already in Pixel art left the grid on screen with nothing behind it and painting, the palette and import all silently did nothing. - Locked W/H with no explanation, and a multi-image batch forced to the New frame target could never set dimensions at all. Batches can now target Whole sprite, and the lock states why and how to change it. - Cover/Fit/Stretch previews were indistinguishable: the pixelized canvas rendered at its natural size (32 CSS px in a 250px box). Both panes now fill the box, and the source pane is framed exactly as the conversion frames it, so the two read as before/after. - Photos were point-sampled on the way down, which threw away almost the whole image and read as noise. Area-average via progressive halving, switching to nearest at 1:1 and integer ratios so pixel-art sources stay crisp and import exactly. Also fixed while verifying: - Standalone pixel work was lost on refresh - pixelCommitIfStandalone() mutates state without calling render(), which is what writes the autosave. persistAutosave() existed for this case but was never called here. - The quantizer always split to the requested colour count, padding small palettes with duplicate dead entries that cost event-size budget. It now keeps the source's exact colours when there are fewer than requested. - sanitizePixelArtBlob truncated imported palettes at 64 though the model allows 256 (cells past the cut rendered transparent) and dropped per-frame durations. - Stale grid-size pill after a resize, zoom not refitting when the grid grows, and a dead pixelImportFromImage() pointing at a nonexistent element. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>