Spot the bug - #138: Neon Ring Canvas

Why is my glowing neon ring rendering stretched and distorted?

<canvas id="cv" style="width: 300px; height: 300px;"></canvas>
<script>
  const ctx = document.getElementById('cv').getContext('2d');
  ctx.arc(150, 150, 100, 0, Math.PI * 2);
  ctx.strokeStyle = '#00ffcc';
  ctx.lineWidth = 8;
  ctx.stroke();
</script>

Reply with what is broken and how you would fix it.

The issue is that the canvas element’s drawing surface isn’t set to the same dimensions as its display size.

The CSS is scaling the smaller internal buffer. You need to set the width and height attributes directly on the <canvas> tag itself, like this:

<canvas id="cv" width="300" height="300"></canvas>

Spot the Bug answer: The canvas element’s drawing buffer resolution is not set, causing it to default to 300x150 pixels despite the CSS styling.

The fix:
Set the width and height attributes directly on the canvas element: cv.width = 300; cv.height = 300;

Why:
The HTML canvas element has two sizes: one set by CSS for display and one for its internal drawing buffer. If the internal drawing buffer dimensions are not explicitly set via the width and height attributes, it defaults to 300x150 pixels. When the CSS then scales this 300x150 buffer to a 300x300 display area, the content appears stretched.

First-answer leaderboard

  1. @Apexcodes - 6 (firsts) :trophy:
  2. @kirupa - 6 (firsts) :trophy:
  3. @emmawalter5 - 3 (firsts)
  4. @adnanahmed - 2 (firsts)

wait, this is a classic! I remember running into this exact thing when I was messing around with some audio visualizers years ago.

it’s such a subtle distinction between the CSS size and the actual drawing buffer. you think you’ve got it all set up and then boom, everything’s pixelated.

It’s like drawing on a tiny paper then stretching it to fit a big frame. Of course it looks blurry.

Been there

The drawRing function is trying to use ctx before it’s properly initialized for the new canvas. That’s a classic off-by-one in the render loop.