Slow Dotted Line Artwork in HTML5 Canvas

I am trying to make a pong clone using HTML5 canvas. I want to draw a dotted line down the middle of the playing field, as shown in the original Pong. I do this by extending the CanvasRenderingContext2D object, as shown in David Geary's excellent book:

 CanvasRenderingContext2D.prototype.dashedLine = function (x1, y1, x2, y2, dashLength) { dashLength = dashLength === undefined ? 5 : dashLength; var deltaX = x2 - x1; var deltaY = y2 - y1; var numDashes = Math.floor( Math.sqrt(deltaX * deltaX + deltaY * deltaY) / dashLength); for (var i=0; i < numDashes; ++i) { context[ i % 2 === 0 ? 'moveTo' : 'lineTo' ] (x1 + (deltaX / numDashes) * i, y1 + (deltaY / numDashes) * i); } 

Then I have a render() function that actually makes all the calls to render elements on the canvas. It includes my renderBackground() function, which colors the background and draws a dashed line:

 function render() { ctx.clearRect(0, 0, cWidth, cHeight); renderBackground(); // Rest removed for brevity } function renderBackground() { ctx.lineWidth = 5; ctx.strokeStyle = '#FFFFFF'; ctx.fillStyle = '#000000'; ctx.fillRect(0, 0, cWidth, cHeight); ctx.dashedLine(0, 0, 0, cHeight, 10); ctx.stroke() } 

Then in the end I have a function called animLoop() that actually calls the render() function and uses requestAnimationFrame() for smoother animations:

 function animLoop() { render(); requestAnimationFrame(animLoop); } window.requestAnimationFrame = (function() { return ( window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function( callback ){ window.setTimeout(callback, 1000 / 60); } ); })(); 

If I let my game run for more than 30 seconds, it starts to slow down to such an extent that it does not play, and the processorโ€™s use by the browser fluctuates by about 134% for Firefox and Chrome. Slowness is present only when I show a dashed line. I'm not sure what is going on, but below I also run my code through the Chrome Inspectors profiler and get the following:

enter image description here

My renderBackground() function takes up only 0.46% of the CPU time. Also I'm not sure what (program) means. Any thoughts on what might cause slowness?

You can also see the full code that I have on my Github repo .

+4
source share
1 answer

You accumulate all lineTo calls along the default path each time ctx.dashedLine is ctx.dashedLine , and the access cycle processes all the lines in the path from the moment the application is launched. As you start the animation, quickly the path will contain many lines for drawing when each measure is called.

Add ctx.beginPath() to ctx.dashedLine to solve the problem.

 function renderBackground() { ctx.lineWidth = 5; ctx.strokeStyle = '#FFFFFF'; ctx.fillStyle = '#000000'; ctx.fillRect(0, 0, cWidth, cHeight); ctx.beginPath(); // <-- add it here ctx.dashedLine(0, 0, 0, cHeight, 10); ctx.stroke(); } 

When drawing using the path, you use a virtual pen or pointer. This way you will create a virtual path with an initial path, draw lines and finally stroke these lines. In the next frame, you will begin a new virtual path, again draw new lines in the path and stroke. Thus, performance remains stable.

Demo

+2
source

Source: https://habr.com/ru/post/1485186/


All Articles