erik
erik

Reputation: 3880

Copy canvas to graphics object in p5.js

I've not been able to find a reference or figure this out, but I was curious if there is a way to take the current state of the drawn canvas in p5.js and save it to a graphics object.

Basically, I do a lot of pre-drawing in the setup function and would like to take a snapshot of that to be used as the background within the draw function.

I realize I could probably add an extra layer of complexity to my setup drawing by adding extra graphics objects, however it would just be much easier to get the current state into a new object/image (I have a decently complex chain of graphics objects as is that are being dropped onto the main canvas).

Upvotes: 1

Views: 2404

Answers (1)

Paul Wheeler
Paul Wheeler

Reputation: 20140

I believe what you are looking for is the copy() function. It can be used to copy regions of pixels within and between the canvas, p5.Graphics objects, and p5.Image objects. One thing to be aware of when copying from the main canvas to a p5.Image is that the main canvas has a pixel density that depends on the display (i.e. a density of 2 for high DPI displays), but p5.Image objects do not have a density. So for high DPI displays your p5.Image object needs to be oversized. For this reason it is better to use a p5.Graphics in my opinion. Here's a trivial example:

let buffer;

function setup() {
  let canvas = createCanvas(windowWidth, windowHeight);
  background(100);
  
  buffer = createGraphics(width, height);
  
  let saveButton = createButton("save");
  saveButton.position(20, 20);
  saveButton.mouseClicked(() => {
    // Copy from canvas into buffer
    buffer.copy(
      // source
      canvas,
      // source x, y, w, h
      0, 0, width, height,
      // destination x, y, w, h
      0, 0, buffer.width, buffer.height)
  });
  
  let restoreButton = createButton("restore");
  restoreButton.position(80, 20);
  restoreButton.mouseClicked(() => {
    // Copy from buffer into the canvas
    copy(buffer, 0, 0, buffer.width, buffer.height, 0, 0, width, height);
  });
}

function draw() {
  circle(mouseX, mouseY, 20);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>

Upvotes: 2

Related Questions