saveGif issue when used with translucent background
Open
Nobody has claimed this yet.
Area:Image
Bug
- Dominant language
- JavaScript
- Stars
- 24k
- Forks
- 3.8k
- Avg merge
- 3d 16h
- Merged PRs (30d)
- 25
Description
Most appropriate sub-area of p5.js?
- Accessibility
- Color
- Core/Environment/Rendering
- Data
- DOM
- Events
- Image
- IO
- Math
- Typography
- Utilities
- WebGL
- Build Process
- Unit Testing
- Internalization
- Friendly Errors
- Other (specify if possible)
p5.js version
1.5.0
Web browser and version
Firefox 108.0
Operating System
Linux, Mac
Steps to reproduce this
Steps:
- Create a sketch that uses a translucent background and then use
saveGif - The call to saveGif reuslts in the canvas being cleared due to
pixelDensitycall here: https://github.com/processing/p5.js/blob/1246fc26daf558522a60b693b4e0059027aae8b4/src/image/loading_displaying.js#L286 - The resulting GIF starts without the faded past frames, resulting in a jump:

Compared to how the GIF should look:

Snippet:
Example sketch that saves two gifs, one with the bug (test.gif) and one using the workaround of overriding pixelDensity (testFix.gif)
function setup() {
createCanvas(100, 100);
angleMode(DEGREES);
background(0, 0, 0, 255);
pixelDensity(1);
}
function draw() {
background(0, 0, 0, 25);
color(255, 255, 255);
const angle = 10 * frameCount % 360;
circle(50 + 25 * sin(angle), 50 + 25 * cos(angle), 10);
// Wait for a full rotation before saving a gif:
if (frameCount === 36) {
setTimeout(
() => saveGif(
'test.gif',
36,
{
delay: 0,
units: 'frames',
},
),
0,
);
}
if (frameCount === 108) {
// Override pixelDensity to prevent the canvas being cleared
p5.instance.pixelDensity = () => {};
setTimeout(
() => saveGif(
'testFix.gif',
36,
{
delay: 0,
units: 'frames',
},
),
0,
)
}
}
Suggestions
- It might be worth changing
saveGifto not override thepixelDensityof the current sketch, which would require more complicated maths for the buffers but prevents the change - It might be worth having an option on
saveGifto rendernframes before starting the recording. This option might be useful anyway, as you'd be able to rewrite the sketch above to something like:
function setup() {
createCanvas(100, 100);
angleMode(DEGREES);
background(0, 0, 0, 255);
pixelDensity(1);
noLoop();
setTimeout(
() => saveGif(
'test.gif',
36,
{
delay: 0,
// Wait for a full rotation before saving a gif:
preamble: 36,
units: 'frames',
},
),
0,
);
}
function draw() {
background(0, 0, 0, 25);
color(255, 255, 255);
const angle = 10 * frameCount % 360;
circle(50 + 25 * sin(angle), 50 + 25 * cos(angle), 10);
}
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in src/image/loading_displaying.js at the pixelDensity call linked in the issue, then reproduce the translucent-background case using the provided p5.js Web Editor sketch. Compare saveGif output with and without the pixelDensity override; done means translucent past frames are preserved in the GIF without breaking normal saveGif behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- computer-graphics
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100