Most appropriate sub-area of p5.js?
p5.js version
2.0.5
Web browser and version
149.0.7827.54 (Official Build) (64-bit) (cohort: Stable)
Operating system
Windows 11 Pro
Steps to reproduce this
Steps:
- Run the sketch below and wait until
frameCount exceeds 300 (canvas turns dark, circle grows large)
- Note the frame number displayed on screen — this is where the animation currently is
- Click "Save GIF", then open the downloaded file
- Observe: the first frames of the GIF show a bright background, tiny circle, and a frame number near the
delay value — not where the animation actually was
Snippet:
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/2.0.5/p5.min.js"></script>
</head>
<body>
<script>
function setup() {
createCanvas(480, 480);
colorMode(HSB, 360, 100, 100);
noStroke();
let btn = createButton('Save GIF');
btn.mousePressed(() => saveGif('demo', 3, { units: 'frames', delay: 30 }));
}
function draw() {
let brightness = map(frameCount, 0, 600, 95, 5, true);
let saturation = map(frameCount, 0, 600, 10, 90, true);
background((frameCount * 0.3) % 360, saturation, brightness);
let sz = map(frameCount, 0, 600, 20, 380, true);
fill(((frameCount * 0.3) + 180) % 360, 80, 100);
ellipse(width/2, height/2, sz);
fill(0, 0, brightness > 50 ? 10 : 95);
textSize(18);
textAlign(CENTER, CENTER);
text('frame ' + frameCount, width/2, height/2);
}
</script>
</body>
</html>
Description:
saveGif has two related bugs in the same block of code that together make the delay option actively harmful rather than helpful.
Bug 1 — frameCount is overwritten with the delay value
Before recording begins, saveGif does:
let frameIterator = nFramesDelay;
this.frameCount = frameIterator; // ← line 39298 in 2.0.5
This teleports the sketch's frameCount to the delay value. If the animation has been running for 400 frames and you call saveGif('out', 3, { delay: 5, units: 'frames' }), the sketch's frameCount is set to 5 and the GIF renders from the animation's frame-5 state — not from frame 400 where you actually were.
Bug 2 — the delay renders zero warmup frames
The capture loop starts at frameIterator = nFramesDelay and runs until frameIterator < totalNumberOfFrames (nFrames + nFramesDelay). That's exactly nFrames iterations — every one of which is captured. There are no un-captured pre-capture renders. The delay parameter only changes where frameIterator starts counting; it never actually renders any warmup frames before capture begins.
This means the two bugs compound: even if you try to use a large delay to "skip past" the bad frames, Bug 1 ensures those frames are now from the wrong point in the animation entirely.
Why it matters: Coders often utilize frameCount as a variable guiding some aspect of their visuals. Because saveGif resets frameCount, that means the sketch gets set back to the first frame despite calling saveGif elsewhere. So the intended visuals are not saved. AND - the delay doesn't work as documentation intends.
Most appropriate sub-area of p5.js?
p5.js version
2.0.5
Web browser and version
149.0.7827.54 (Official Build) (64-bit) (cohort: Stable)
Operating system
Windows 11 Pro
Steps to reproduce this
Steps:
frameCountexceeds 300 (canvas turns dark, circle grows large)delayvalue — not where the animation actually wasSnippet:
Description:
saveGif has two related bugs in the same block of code that together make the delay option actively harmful rather than helpful.
Bug 1 — frameCount is overwritten with the delay value
Before recording begins, saveGif does:
let frameIterator = nFramesDelay;
this.frameCount = frameIterator; // ← line 39298 in 2.0.5
This teleports the sketch's frameCount to the delay value. If the animation has been running for 400 frames and you call saveGif('out', 3, { delay: 5, units: 'frames' }), the sketch's frameCount is set to 5 and the GIF renders from the animation's frame-5 state — not from frame 400 where you actually were.
Bug 2 — the delay renders zero warmup frames
The capture loop starts at frameIterator = nFramesDelay and runs until frameIterator < totalNumberOfFrames (nFrames + nFramesDelay). That's exactly nFrames iterations — every one of which is captured. There are no un-captured pre-capture renders. The delay parameter only changes where frameIterator starts counting; it never actually renders any warmup frames before capture begins.
This means the two bugs compound: even if you try to use a large delay to "skip past" the bad frames, Bug 1 ensures those frames are now from the wrong point in the animation entirely.
Why it matters: Coders often utilize frameCount as a variable guiding some aspect of their visuals. Because saveGif resets frameCount, that means the sketch gets set back to the first frame despite calling saveGif elsewhere. So the intended visuals are not saved. AND - the delay doesn't work as documentation intends.