Skip to main content

Drawing Dashed Lines on an HTML5 Canvas

The canvas element in HTML is great, but has one strange shortcoming: it cannot draw dashed lines (natively). However, dashed lines seem like a pretty common thing to draw, which only highlights the problem.

Looking around, I've noticed several solutions to this problem. Some use trig, and others use their own libraries that must be imported. So in the end, I decided to create my own method.

This code will add the function to all canvas elements, both those already on the page, and any that are dynamically added later.

Here is the code:
CanvasRenderingContext2D.prototype.dashedLine = function(x1, y1, x2, y2, dashLen) {
    if (dashLen == undefined) dashLen = 2;
    
    this.beginPath();
    this.moveTo(x1, y1);
    
    var dX = x2 - x1;
    var dY = y2 - y1;
    var dashes = Math.floor(Math.sqrt(dX * dX + dY * dY) / dashLen);
    var dashX = dX / dashes;
    var dashY = dY / dashes;
    
    var q = 0;
    while (q++ < dashes) {
     x1 += dashX;
     y1 += dashY;
     this[q % 2 == 0 ? 'moveTo' : 'lineTo'](x1, y1);
    }
    this[q % 2 == 0 ? 'moveTo' : 'lineTo'](x2, y2);
    
    this.stroke();
    this.closePath();
};


To use this, just plop this code into your page, so that it executes before you use it (onload, head, top of body, etc). The method takes 4 or 5 parameters: the start and end coordinate pairs, and (optionally) the dash length. If the dash length is not specified, it will default to 2 pixels. When you need to use it, simply call it on the context object (e.g. context.dashedLine(100, 100, 200, 200, 3);).

Feel free to use this anytime you need it, and let me know in the comments if you like this or if you have a better solution.

P.S. For those worried about size, here is the same code, but minified using the Closure Compiler:
CanvasRenderingContext2D.prototype.dashedLine=function(d,e,g,h,a){if(a==undefined)a=2;this.beginPath();this.moveTo(d,e);var b=g-d,c=h-e;a=Math.floor(Math.sqrt(b*b+c*c)/a);b=b/a;c=c/a;for(var f=0;f++<a;){d+=b;e+=c;this[f%2==0?"moveTo":"lineTo"](d,e)}this[f%2==0?"moveTo":"lineTo"](g,h);this.stroke();this.closePath()};

Comments

  1. Hi,
    Thank you for your post, it works for simple dash patterns. In a real world scenarie you though would need a more advanced dash pattern setup.

    One webpage writing about this is: http://docstore.mik.ua/orelly/java-ent/jfc/ch04_05.htm
    In graphics models like Postscript and SVG you use the same model for defining how the pattern should look like (you can see it in the above mentioned webpage). For instance you may define a dash pattern like this:
    var dashPattern = [21, 9, 3, 9]

    Which should be rendered like this:
    "21 units of painted, 9 left blank, 3 painted, 9 left blank" and starting over again.

    At one time before HTML5 and Canvas I tried to implement an online dash pattern generater with preview. The webapp should help create custom dash pattern in postscript (Actually the Adobe Illustrator variant .ai) so that users of a vector drawing package Xara Designer Pro 7 (current version: www.xara.com) could get custom dash patterns.

    With the arrival of HTML5 Canvas I want to improve the online preview of the dash pattern people design, and found your page... However I need to be able to draw using the postscript/.ai dash pattern style. Do you think that you can do that? Make a new version which can handle that? I would love it! :-)

    My old (actually not working...) dash pattern generator can be found here: http://www.netsi.dk/xara/generatedash.html

    /Sten

    ReplyDelete
  2. Very nice! Worked perfectly for me, thanks!

    If you want to see the results it's here:

    http://www.inf.ufsc.br/~filipesilva.sc/cube/cube.html

    ReplyDelete
  3. works perfectly. thanks. do u have a similar solution for drawing parallel and perpendicular lines?

    ReplyDelete
  4. i would suggest to add color also :)
    add var color

    CanvasRenderingContext2D.prototype.dashedLine = function(x1, y1, x2, y2, dashLen, color)
    ....
    if (color == undefined) color = "#000";
    ....
    this.strokeStyle = color

    thats all now u can use it like:
    context.dashedLine(250, 250, 250, 0, 3, "#fff");

    hope its usefull

    ReplyDelete
  5. Thanks, it worked for me, with a few changes though. I found a way to draw dashed lines in firefox and IE on canvas , thanks a lot :)

    ReplyDelete

Post a Comment

Popular posts from this blog

Linux on XPS 15 9550/9560 with TB16 Dock [Update:3/29]

Finally got a laptop to replace my fat tower at work - Dell XPS 15 9560. I was allowed to choose which one I wanted and chose the XPS for its Linux support since Dell ships developer edition XPS's running Ubuntu so I figured Linux support would be better than other manufacturers. At first they got me the model with the 4K screen but my monitors are 2K and multi-dpi support in Linux is virtually non-existent and even hi-dpi support on its own is pretty terrible. So I got it exchanged for the model with the regular 1080p screen (which happened to also be the updated 9560 model), which works much better. I'm very glad to report that pretty much everything works, including the TB16 desktop dock, with just a bit of settings tweaking. This post is to help anybody considering getting this setup or looking for help getting things working. For now, I am running Kubuntu 16.04 with KDE Neon installed.

List of things I explicitly tested and work:
WiFi, BluetoothThunderbolt charging from T…

JComboBox with Disabled Items

Recently, I was working on a project in Java and needed to have a combo box, but with certain items in the list disabled (e.g. gray and non-selectable). At first, I simply set a custom renderer for the combo box which checked if the item was disabled. That, however, did not prevent the items from being selected. Thus, I set about to find a viable solution. There are plenty of solutions out there, but none seemed to work exactly the way I wanted. In the end, I ended up subclassing JComboBox to provide the functionality of disabling individual items. Here is my result, in under 100 lines:

import java.awt.Component; import java.util.ArrayList; import javax.swing.JComboBox; import javax.swing.JList; import javax.swing.plaf.basic.BasicComboBoxRenderer; public class PartialDisableComboBox extends JComboBox { private static final long serialVersionUID = -1690671707274328126L; private ArrayList<boolean> itemsState = new ArrayList<boolean>(); public PartialDisableComboBox()…

Broadcom Bluetooth Driver: Installer or Virus??

My primary computer at the moment is an HP dv6 laptop (with Broadcom 2070 Bluetooth chip). Upon getting my laptop, I immediately wiped the hard drive and slapped on a fresh copy of Windows 7. Installed the drivers from HP, and everything was rolling along nicely...

Fast-forward 4 months... Now I'm having some issues with Bluetooth communication between my phone (Android) and my laptop. So I reinstall the Bluetooth driver... The installation took a long time, but eventually errored-out, and quit. Of course, I had left the computer unattended during this, and came back to an almost-empty hard drive (!!!!). Restored for backup, some minor data loss, no problem... I thought I had snagged a virus in the download (even though it was direct from HP's site). Redownload, scan with multiple scanners, run it ....... SAME RESULT!!! Giving up on the official installer, I just took the drivers that the installer unpacked, and manually installed them... That didn't solve my original prob…