Bug 165644
Summary: | Canvas flickers when scrolling | ||
---|---|---|---|
Product: | WebKit | Reporter: | Joseph Pecoraro <joepeck> |
Component: | Canvas | Assignee: | Nobody <webkit-unassigned> |
Status: | NEW | ||
Severity: | Normal | CC: | dino, joepeck, simon.fraser |
Priority: | P2 | ||
Version: | WebKit Nightly Build | ||
Hardware: | Unspecified | ||
OS: | Unspecified |
Joseph Pecoraro
Summary:
Canvas logo flickers when scrolling on http://tesseract.projectnaptha.com.
• Flicker in Safari
• Flicker in Firefox.
• No Flicker in Chrome.
Steps to Reproduce:
1. Load http://tesseract.projectnaptha.com
2. Scroll the page up and down slightly or rubber band
=> Logo at top flickers
Attachments | ||
---|---|---|
Add attachment proposed patch, testcase, etc. |
Simon Fraser (smfr)
Looks like that logo is using mouse position as an input. Probably related to how often we report mouse position changes during scrolling, and whether we flicker between two values.
Joseph Pecoraro
The page has a rAF draw loop for the logo:
> function main (time) {
> fixdim()
> ctx.clearRect(0,0,canvas.width,canvas.height)
>
> var t = time/10000
> ctx.strokeStyle = ctx.fillStyle = color
> var sm = 1
> var m = tesseractwithrotation(t, t*2, t*3, mouse.x/100, mouse.y/100, 0)
> drawtesseract(ctx, m, {
> x: canvas.width/2,
> y: canvas.height/2,
> size: gh*canvas.height,
> line_width: 2,
> })
>
> lasttime = time
> requestAnimationFrame(main)
> }
It seems as if the fixdim() is causing this issue in Safari when it sets the canvas.width and canvas.height to values that end up not changing. When that happens WebKit clears the canvas.
Fortunately the code has a global variable "freeze" that you can set to true and it skips this code. When set the canvas no longer flickers.
So perhaps we should be smarter when setting the width/height of a canvas to a value that ultimately doesn't cause a change.
Joseph Pecoraro
Yeah, this could be smarter if the width/height is not changing we may not need to reset (which clears):
> void HTMLCanvasElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
> {
> if (name == widthAttr || name == heightAttr)
> reset();
> HTMLElement::parseAttribute(name, value);
> }
Simon Fraser (smfr)
I filed https://github.com/whatwg/html/issues/2159