Skip to content
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

noSmooth() breaks positioned WEBGL canvas #7548

Open
2 of 17 tasks
ffd8 opened this issue Feb 15, 2025 · 5 comments · May be fixed by #7553 or #7557
Open
2 of 17 tasks

noSmooth() breaks positioned WEBGL canvas #7548

ffd8 opened this issue Feb 15, 2025 · 5 comments · May be fixed by #7553 or #7557

Comments

@ffd8
Copy link
Contributor

ffd8 commented Feb 15, 2025

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

1.11.3

Web browser and version

Chrome 133.0.6943.54

Operating system

MacOS

Steps to reproduce this

Steps:

  1. createCanvas(), position it, add noSmooth() in the draw()
  2. 2D renderer, no problem
  3. WEBGL, breaks, creates new empty canvas?

Perhaps one isn't supposed to use noSmooth() in the draw? I don't remember hitting this issue, but maybe never tried it before... Is that how it's supposed to behave? The refs only show examples of it in the setup(), but it doesn't state anywhere that's the only spot for it to go. In 2D renderer, it doesn't cause an issue, so is it normal in WEBGL or a bug?

Snippet:

function setup() {
	let cvn = createCanvas(300, 300)
	cvn = createCanvas(300, 300, WEBGL) // breaks with noSmooth() below
	cvn.position(150, 50)
	
	background(0, 0, 255)
	circle(0, 0, 100)
}

function draw(){
	noSmooth() // breaks sketch in WEBGL mode
}
@davepagurek
Copy link
Contributor

noSmooth() involves recreating the canvas (see also these other problems: #6369 (comment))

A docs update sounds like the best option here for mentioning that the canvas will be recreated.

About positioning: I don't think we try to copy the style attribute from the last canvas when we recreate it, so that would probably be necessary to not lose the position if setAttributes or noSmooth is called after positioning. Since noSmooth calls setAttributes under the good, I think that would be the spot where we'd have to add a fix.

@HarshitaKatariya
Copy link

Yup, setAttributes has a property that recreates the canvas, so updating the documentation of noSmooth() is a good option.

Alternatively, we can update the codebase to prevent unnecessary canvas recreation by checking if antialias is already false before calling setAttributes(). This would improve performance, maintain canvas positioning, and ensure consistency between 2D and WebGL modes.

Would it be okay to proceed with a pull request for this fix?

@ImRAJAS-SAMSE
Copy link
Contributor

ImRAJAS-SAMSE commented Feb 16, 2025

I would like to work on this issue by modifying setAttributes() in p5.RendererGL.js to prevent unnecessary canvas recreation when noSmooth() is called in draw().

My Plan to Fix this issue:

  1. Skip unnecessary recreation – Check if antialias is already false before calling _initContext(), avoiding redundant canvas resets.
  2. Preserve positioning – Store position, top, and left before recreation and restore them after.
  3. Update docs – Clarify that noSmooth() can cause canvas recreation if used in draw().

Let me know if any changes are needed and should I proceed with a PR!
Thank you :)

@HarshitaKatariya
Copy link

@ImRAJAS-SAMSE, I think the change might not have fully resolved the issue as expected. The canvas position still seems to be off after calling noSmooth(). Could you double-check whether the position is being correctly restored after the canvas is recreated?

@ImRAJAS-SAMSE
Copy link
Contributor

Hi @HarshitaKatariya, thank you for reviewing the PR! 🙌

I double-checked the fix, and during testing, the canvas retained its position correctly after calling noSmooth().

What I Tested:

  • Used createCanvas(300, 300, WEBGL); and positioned it at (150, 50).
  • Called noSmooth() in draw().
  • Verified that the canvas did not reset to (0, 0) after recreation.
  • The sphere rendered properly with jagged edges, confirming that noSmooth() was applied.

Could you share a test case where the issue still occurs? I’d be happy to debug further if needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment