processing / processing/p5.js

saveGif issue when used with translucent background

Open
#5,924 5 comments 0 reactions 0 assignees View on GitHub

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:
  1. Create a sketch that uses a translucent background and then use saveGif
  2. The call to saveGif reuslts in the canvas being cleared due to pixelDensity call here: https://github.com/processing/p5.js/blob/1246fc26daf558522a60b693b4e0059027aae8b4/src/image/loading_displaying.js#L286
  3. The resulting GIF starts without the faded past frames, resulting in a jump:
    test
    Compared to how the GIF should look:
    testFix
Snippet:

Example sketch that saves two gifs, one with the bug (test.gif) and one using the workaround of overriding pixelDensity (testFix.gif)

p5.js Web Editor link

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

  1. It might be worth changing saveGif to not override the pixelDensity of the current sketch, which would require more complicated maths for the buffers but prevents the change
  2. It might be worth having an option on saveGif to render n frames 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.