Bug 165644 - Canvas flickers when scrolling
Summary: Canvas flickers when scrolling
Status: NEW
Alias: None
Product: WebKit
Classification: Unclassified
Component: Canvas (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Nobody
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-12-08 19:04 PST by Joseph Pecoraro
Modified: 2016-12-08 19:32 PST (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Joseph Pecoraro 2016-12-08 19:04:44 PST
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
Comment 1 Simon Fraser (smfr) 2016-12-08 19:06:37 PST
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.
Comment 2 Joseph Pecoraro 2016-12-08 19:18:16 PST
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.
Comment 3 Joseph Pecoraro 2016-12-08 19:22:50 PST
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);
> }
Comment 4 Simon Fraser (smfr) 2016-12-08 19:32:09 PST
I filed https://github.com/whatwg/html/issues/2159