WEBDOOD.COM

HTML5 Canvas – Drawing Dashed Lines (dashedLineFromTo)

by webdood on Jul.18, 2011, under Canvas, HTML5, Javascript

There is no way built-in way to draw dashed lines using <canvas>.
Therefore, I came up with a prototype method that hangs off of the CanvasRenderingContext2D Object that I am calling “dashedLineFromTo”

As you may expect, it simply draws a bit of a line, then skips a bit and draws more until it is done “connecting the dots” between point A and B.

My particular application involves generating a line graph with dashed lines.
This is, in effect, a series of dashed lines and adds a slight nuance inasmuch as when one dashed line is completed and another picks up where it left off, we must keep track of if the previous line ended in a lineTo (ie drawn pixels) or a moveTo (ie just moving the drawing cursor) and, with the new line segment, begin it with a lineTo or a moveTo to “finish off” the pixels that were left unpainted in the previous segment.

This sounds more complicated than it is.

    var __dashedLineFromTo = {
      isDrawing : true,
      unFinishedPixelsFromLastDash : 0
    }
    CanvasRenderingContext2D.prototype.dashedLineFromTo = function(from,to) {
      var x=from[0], y=from[1],
          dashLength        = 2,
          dx                = (to[0] - x) + .00000001,
          dy                = to[1] - y,
          slope             = dy/dx,
          distanceRemaining = Math.sqrt(dx*dx + dy*dy),
          bUnfinishedPixels = false,
          theDashLength,
          xStep;
      this.moveTo(x,y);
      while (distanceRemaining>=0.1) {
        if (__dashedLineFromTo.unFinishedPixelsFromLastDash === 0) {
          theDashLength = dashLength;
        } else {
          theDashLength = __dashedLineFromTo.unFinishedPixelsFromLastDash;
          __dashedLineFromTo.unFinishedPixelsFromLastDash = 0;
          __dashedLineFromTo.isDrawing = !__dashedLineFromTo.isDrawing
        }
        if (dashLength > distanceRemaining) { dashLength = distanceRemaining; bUnfinishedPixels=true; }
        xStep = Math.sqrt( theDashLength*theDashLength / (1 + slope*slope) );
        x += xStep;
        y += slope*xStep;
        this[__dashedLineFromTo.isDrawing ? 'lineTo' : 'moveTo'](x,y);
        distanceRemaining -= theDashLength;
        __dashedLineFromTo.isDrawing = !__dashedLineFromTo.isDrawing;
      }
      if (bUnfinishedPixels) {
        __dashedLineFromTo.unFinishedPixelsFromLastDash = theDashLength;
      }
    }
    function init() {
      var canvas = document.getElementById("canvas");
      var ctx = canvas.getContext("2d");
      ctx.beginPath();
      ctx.lineWidth = 2;
      ctx.lineCap = 'butt';
      ctx.beginPath();
      ctx.dashedLineFromTo([0.2, 1.2], [99.9, 12.8]);
      ctx.dashedLineFromTo([99.9, 12.8], [118.5, 5.0]);
      ctx.dashedLineFromTo([118.5, 5.0], [148.5, 105.0]);
      ctx.dashedLineFromTo([148.5, 105.0], [178.5, 55.0]);
      ctx.dashedLineFromTo([178.5, 55.0], [218.5, 97.3]);
      ctx.closePath();
      ctx.stroke();
    }
<body onload="init()">
   <canvas id="canvas" width="912" height="339"></canvas>
 </body>

Here is a working example:

Shannon Norrell


3 Comments for this entry

  • jasbeer singh

    i need a completely made dashed rectangle using html5 canvas

  • Jeff Moden

    I don’t even know how to spell “Java Script” and have never written anything in JS but, because of your thoughtful naming and formatting, I was actually able to read this and figure it out.

    Shifting gears a bit and you’ll probably think me crazy but I’m a DBA and not a Developer (I was 20 years ago). I’m (just atarting) writing code to graphically represent things like the data I collect each morning on disk size v.s. free space and a whole bunch more and I’m doing all in T-SQL to create the HTML to embed in an email send using sp_SendDbMail. I know there’s tools to do this type of thing but, like I said, I’m a bit crazy and want to prove that this can actually be done via T-SQL.

    Thanks again for taking the time to post your great solution for dotted lines.

Leave a Reply

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!

Blogroll

A few highly recommended websites...

  • A List Apart
  • Dive into HTML5
  • Javascript: The Good Parts
  • QuirksMode.org