Files
Artstr-Studio/docs
thePR0M3TH3ANandClaude Opus 5 8702043abf Import animated GIFs into the pixel editor
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]>
2026-08-02 11:02:40 -04:00
..
2026-05-15 21:13:49 -04:00