setViewport
The canvas's BACKING STORE is sized here, which is the only place that can be right.
A canvas has two sizes: the CSS box the page lays out, and the pixel buffer it draws into. Leaving the buffer at its 300x150 default and stretching it by CSS is the standard way to get a blurry canvas, and no amount of correct geometry above fixes it. scale is the device pixel ratio, so a HiDPI display gets the pixels it actually has.
Resizing clears the canvas, so the retained picture is drawn again at the new size. That is what keeps a paused picture on screen when a page moves its canvas into a picture in picture window and back.