Skip to content

[p5.js 2.0 Bug Report]: Transforms in clip() stopped working in 2.x #7903

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
1 of 17 tasks
davepagurek opened this issue Jun 12, 2025 · 1 comment
Open
1 of 17 tasks

Comments

@davepagurek
Copy link
Contributor

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
  • Internationalization
  • Friendly errors
  • Other (specify if possible)

p5.js version

2.0.3

Web browser and version

Firefox

Operating system

MacOS

Steps to reproduce this

The following code clips to a circle at the center of the screen:

function setup() {
  createCanvas(400, 400);
}

function draw() {
  background(220);
  noStroke()
  
  clip(() => {
    push()
    translate(width/2, height/2)
    circle(0, 0, 60)
    pop()
  })
  fill(0)
  rect(0, 0, 400, 400)
}

In 1.11.8 it looks like this:

Image

In 2.0.3 it looks like this, which is unexpected:

Image

Live: https://editor.p5js.org/davepagurek/sketches/IVloB6s76W

@davepagurek
Copy link
Contributor Author

Between 1.x and 2.x, we changed how we generate the clip path. It used to be done by switching the fill color to transparent and drawing as usual after that, which also builds up the drawing context's clip path:

beginClip(options = {}) {
super.beginClip(options);
// cache the fill style
this._cachedFillStyle = this.drawingContext.fillStyle;
const newFill = this._pInst.color(255, 0).toString();

Now, to avoid the transparent drawing, we just build up a Path2D object with the clip path:

drawShape(shape) {
const visitor = new PrimitiveToPath2DConverter({ strokeWeight: this.states.strokeWeight });
shape.accept(visitor);
if (this._clipping) {
this.clipPath.addPath(visitor.path);
this.clipPath.closePath();

The problem, I think, is that addPath does not take in the active transformation by default. However, it can do that if you pass in a DOMMatrix with addPath(path, transformMatrix): https://developer.mozilla.org/en-US/docs/Web/API/Path2D/addPath

So maybe we need to update the addPath call with something like drawingContext.getTransform()? ("something like" because maybe we need to remove the initial transform from when beginClip is called? That might not be an issue though, have to try it and see.)

@davepagurek davepagurek added this to the 2.x Anytime milestone Jun 12, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Ready for Work
Development

No branches or pull requests

1 participant