1
votes

I'm trying to create a stylised timeline for an audio player. I would like to draw a nice thick line with round caps at the ends. I thought it would be relatively trivial to do this with canvas. However, I'm finding that at least in Chrome on Mac OS, the lines are not anti-aliased; and also (possibly as a consequence) the line caps are elongated, rather than perfect half-circles.

What perplexes me is that when I view the W3 Schools example the line is anti-aliased, with the expected caps. This makes me wonder if something in my code is triggering a non-anti-aliased mode in the browser...

Here is my full code:

<html>
<head>
    <style>

        body {
            background-color: #212b69;
        }

        .centering {
            height: 100%;
            width: 100%;
            display: flex;
            justify-content: center;
            align-items: center;
        }

        #timeline {
            width: 60%;
            height: 50px;
        }

    </style>
</head>
<body>
    <div class="centering">
        <canvas id="timeline" />
    </div>
    <script type="text/javascript">

        var timeline = document.getElementById('timeline');
        var ctx = timeline.getContext('2d');
        var centrline = timeline.height/2;

        // ctx.translate(0.5, 0.5); // I have tried the half-pixel trick

        // line settings
        ctx.lineCap = "round";
        ctx.lineWidth = 30;
        ctx.strokeStyle = "white";

        // draw test stroke
        ctx.beginPath();
        ctx.moveTo(20, centrline);
        ctx.lineTo(60, centrline+10); // offset to show aliasing of edges
        ctx.stroke();

    </script>
</body>
</html>

My result:

aliased line screenshot

Compared with W3Schools result:

anti-aliased line from W3Schools

I understand from these posts that vector anti-aliasing is determined by the browser. Note also that I've tried the trick of translating the canvas by a half-pixel to kick it into anti-aliasing mode. If there is no way to get canvas to get what I want it to do, is there some other method? Given that I only want to create a relatively simple shape...

1
You're distorting the canvas with the css rules.pishpish

1 Answers

1
votes

Just remove the following css rule and the shape will stop skewing.

#timeline {
            width: 60%;
            height: 50px;
        }

Here's a working example without skew: enter link description here

var timeline = document.getElementById('timeline');
        var ctx = timeline.getContext('2d');
        var centrline = timeline.height/2;

        // ctx.translate(0.5, 0.5); // I have tried the half-pixel trick

        // line settings
        ctx.lineCap = "round";
        ctx.lineWidth = 30;
        ctx.strokeStyle = "white";

        // draw test stroke
        ctx.beginPath();
        ctx.moveTo(20, centrline);
        ctx.lineTo(60, centrline+10); // offset to show aliasing of edges
        ctx.stroke();
body {
  background-color: #212b69;
}

.centering {
  height: 100%;
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}
<div class="centering">
        <canvas id="timeline" />
    </div>