WEBDOOD.COM

Archive for July, 2011

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 more...

Javascript Bitwise Operators or Math.Floor? Which is better?

by webdood on Jul.15, 2011, under Software Development

I realized today that there are three ways to get at the floor of a value in Javascript.
There is:

  • the well-known Math.floor method
  • the lesser well-known Left-Shift <<operator (that I personally always use)
  • the even less well-known Double NOT ~~ operator
  • They all work similarly. Which is faster?

    I developed a test harness to compare the three different methods.

    The results? Math.floor is definitely the slowest.
    Safari processes the Left-shift << about 15% faster than the Double NOT ~~ operator
    Chrome effectively processes ~~ and << at the same speed
    Firefox processes Double NOT ~~ operator 6% faster than the Left-shift << operator
    IE8 processes Left-shift << operator 5% faster than the Double NOT ~~ operator

    Conclusion: use Left-shift << for a generalized, faster approach to getting at the floor of a value.

    Shannon Norrell

    Leave a Comment more...


    Javascript Array Sort By String Length

    by webdood on Jul.08, 2011, under Arrays, Javascript

    Had a need to sort an array of strings by length of each string in descending order.
    Simple solution, really. Perhaps may come in handy at a later date.

      ////////////////////////////////////////////////////////////////////////////
      //
      // Array.sortByStringLength() - sorts an array of strings based on length
      // ==========================
      //
      ////////////////////////////////////////////////////////////////////////////
      Array.prototype.sortByStringLength = function() {
        return this.sort( byStringLength )
      }
      function byStringLength(a,b) {//Sort function used by Array.sortByStringLength
        var retVal = 0;
        if (a.length > b.length) { retVal = -1; }
        return retVal;
      }
    

    Shannon Norrell

    2 Comments more...

    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