News for hackers. Stuff that matters.
Re:It's always been you, Canvas2D by contravariant on Friday March 04, 2022 @08:48AM (#30554652)
Now hang on for a bit, I can vaguely understand what is going wrong with the ClearRect (though why it draws a line to the bottom right when the code just moves the pencil and draws a horizontal line is beyond me) but what on earth is with:

    canvas.width = canvas.width;
That's worse than a code smell, that reeks. Adding a new function to clear the state is nice, but what on earth is going on?
Re:It's always been you, Canvas2D by proto-n on Friday March 04, 2022 @09:00AM (#30554801)
I was curious also, so went looking. Here are some relevant stackoverflow questions: [1], [2]. Basically, setting the width of the canvas to any value different than the current width clears the canvas, because it forces the browser to re-allocate the relevant bitmap. Current implementations don't check if the width value is different, just re-allocate the bitmap anyways. Hence the trick.

[1] https://stackoverflow.com/questions/17522134/how-does-canvas...

[2] https://stackoverflow.com/questions/2142535/how-to-clear-the...

Re:It's always been you, Canvas2D by resonious on Friday March 04, 2022 @09:06AM (#30554880)
Makes sense but smells like a massive oversight in the API design. Really? No "clear the bitmap" function?
Re:It's always been you, Canvas2D by SQueeeeeL on Friday March 04, 2022 @09:16AM (#30555039)
Web dev is full of this kind of oversight (not defending it, it just has a lot of precedence)
Re:It's always been you, Canvas2D by jakelazaroff on Friday March 04, 2022 @09:51AM (#30555582)
There is now! Why it took so long is anyone’s guess.
Re:It's always been you, Canvas2D by greggman3 on Friday March 04, 2022 @12:40PM (#30557824)
there is clearRect
Re:It's always been you, Canvas2D by resonious on Friday March 04, 2022 @07:23PM (#30562475)
Right! But given the mysterious pink line that appears after drawing again (per the article), it seems that clearRect does something else.
Re:It's always been you, Canvas2D by jdashg on Friday March 04, 2022 @02:27PM (#30559241)
Look first to the spec! The spec says don't check if different for canvas2d: https://html.spec.whatwg.org/multipage/canvas.html#concept-c...

> Whenever the width and height content attributes are set, removed, changed, or redundantly set to the value they already have, then the user agent must perform the action from the row of the following table that corresponds to the canvas element's context mode.

> | 2d | Follow the steps to set bitmap dimensions to the numeric values of the width and height content attributes. |

> When the user agent is to set bitmap dimensions to width and height, it must run these steps: > 1. Reset the rendering context to its default state. > 2. Resize the output bitmap to the new width and height.

There's opportunity to reuse the previous surface and just clear the contents, but I'm not sure if this is done. (But the reset of state and clear are both mandatory for `.width=.width`)

Re:It's always been you, Canvas2D by shadowgovt on Friday March 04, 2022 @09:38AM (#30555381)
> Current implementations

Yikes on a bike. Shit like this is how we end up with `typeof null === 'object'` forever baked into the spec.

Re:It's always been you, Canvas2D by ninkendo on Friday March 04, 2022 @11:10AM (#30556664)
Things like this are to be expected if you truly value "never break anyone, ever, even if everyone unanimously agrees something is bad" as an immutable goal of your software. Programming languages are especially important for this sort of philosophy... If you make a mistake and people rely on it, your mistake is now part of the way the language works, always and forever.

My hot take: Software that doesn't take this approach isn't truly serious in the same way as software that does. Personally I'm glad for this level of discipline because at some point, there has to be a "bottom"... software that we have to rely on in order to make our own code work. Not everything gets to enforce deprecation/removal cycles, sometimes it just has to Always, Always Work.

Re:It's always been you, Canvas2D by shadowgovt on Friday March 04, 2022 @12:44PM (#30557878)
Totally agree. I think it's way too late to change out the behavior of `typeof`, but Canvas2D is young enough that it might be great if one or more browsers removed that optimization and didn't cause width = width to blank the canvas contents, so that people didn't come to rely on a bad API to solve a problem that has nothing to do with canvas width.

... of course, that would require extending the API with an actual blanking function...

Re:It's always been you, Canvas2D by easrng on Friday March 04, 2022 @10:59AM (#30556513)
and things like

  > typeof document.all
  < "undefined"
  > document.all.constructor
  < HTMLAllCollection
Re:It's always been you, Canvas2D by Matheus28 on Friday March 04, 2022 @02:06PM (#30558975)
That's a neat one! Never knew about it
Re:It's always been you, Canvas2D by MatmaRex on Friday March 04, 2022 @09:35AM (#30555335)
There are some getters and setters in the web APIs with cheeky side effects. Presumably this one causes the canvas to be re-created, or something. Here's another good one, try it in your browser console:

    location.href = location.href;
Re:It's always been you, Canvas2D by tentacleuno on Friday March 04, 2022 @12:07PM (#30557387)
Your trick doesn't work for me in Firefox 96 :)

One more: If you set an image's src attribute to the same thing, it'll still reload the image.

  const image = new Image("/img.png");
  document.body.append(image);
  image.src = image.src;
Re:It's always been you, Canvas2D by greggman3 on Friday March 04, 2022 @12:42PM (#30557849)
It might not actually reload the image but it has to fire all the events as though it did otherwise code would hang.
Re:It's always been you, Canvas2D by tentacleuno on Friday March 04, 2022 @06:34PM (#30562064)
It does reload the image in Firefox at least. I just tried it.
Re:It's always been you, Canvas2D by MatmaRex on Saturday March 05, 2022 @07:57AM (#30567141)
Oh, it works, it's just cheekier than you think - it won't refresh the page if the URL includes a hash/fragment (such as after you clicked one of the "next" links while browsing comments here).
Re:It's always been you, Canvas2D by greggman3 on Friday March 04, 2022 @12:46PM (#30557894)
It's not really. The code smell is people using it to clear rather than using clearRect but the fact that setting canvas.width or canvas.height resets the canvas and even does so if the size is the same is good engineering IMO.

It's consistent and so your code can know if it sets the size things will reset. It doesn't have to special case when you happen to set it to the same size.

Re:It's always been you, Canvas2D by mysteryDate on Friday March 04, 2022 @09:20AM (#30555095)
Yup. It's awful. We are aware and ashamed
Re:It's always been you, Canvas2D by bschwindHN on Friday March 04, 2022 @09:00AM (#30554788)
I would guess that when a dimension is "changed" (in this case it's not changed, but it is assigned), the canvas is recreated, along with all its internal state.
Re:It's always been you, Canvas2D by l30n4da5 on Friday March 04, 2022 @09:41AM (#30555443)
> That's worse than a code smell, that reeks.

Welcome to webdev.

Re:It's always been you, Canvas2D by recursive on Friday March 04, 2022 @02:07PM (#30558987)
I'd hate to hear what you think of the way I usually do it. On second thought, no check this out.

    canvas.width ^= 0;
It's shorter and easier to type, and just as "clear".
Re:It's always been you, Canvas2D by mysteryDate on Friday March 04, 2022 @09:30AM (#30555250)
Yup, we're aware and we're all ashamed
Re:It's always been you, Canvas2D by ArtWomb on Friday March 04, 2022 @09:45AM (#30555487)
I always avoided the canvas.width clear hack as well. It's just too weird.

I simply fillRect with the background color in a method defined "clear".

2D games will forever be playable. A single round of SNES Super Ghouls & Ghosts is enough to humble even the top esports players of the day ;)

Re:It's always been you, Canvas2D by beardyw on Friday March 04, 2022 @09:01AM (#30554812)
Setting the width or height clears the canvas, so I guess it's just an ugly hack.