32

How can we draw a line in html page. I tried using canvas but found that its not working. Maybe browser doesn't support it. Can there be other easier way.

sam
  • 339
  • 1
  • 3
  • 5

10 Answers10

64

EDIT: Maybe it is little bit late but here is my new implementation. Hope it's more readable.

function createLineElement(x, y, length, angle) {
    var line = document.createElement("div");
    var styles = 'border: 1px solid black; '
               + 'width: ' + length + 'px; '
               + 'height: 0px; '
               + '-moz-transform: rotate(' + angle + 'rad); '
               + '-webkit-transform: rotate(' + angle + 'rad); '
               + '-o-transform: rotate(' + angle + 'rad); '  
               + '-ms-transform: rotate(' + angle + 'rad); '  
               + 'position: absolute; '
               + 'top: ' + y + 'px; '
               + 'left: ' + x + 'px; ';
    line.setAttribute('style', styles);  
    return line;
}

function createLine(x1, y1, x2, y2) {
    var a = x1 - x2,
        b = y1 - y2,
        c = Math.sqrt(a * a + b * b);

    var sx = (x1 + x2) / 2,
        sy = (y1 + y2) / 2;

    var x = sx - c / 2,
        y = sy;

    var alpha = Math.PI - Math.atan2(-b, a);

    return createLineElement(x, y, c, alpha);
}

document.body.appendChild(createLine(100, 100, 200, 200));

Explanation (as they say "a picture is worth a thousand words"):

Draw line explanation sketch

madox2
  • 45,325
  • 15
  • 94
  • 95
  • 1
    all other answers are for vertical/horizontal lines only. this one is for lines with any degree. – oberhamsi Jul 20 '12 at 14:23
  • ^^Inaccurate. I do like this answer because it does it programmatically, however it's not the only answer to reference degrees. You can do degrees through CSS rotation of html divs that are essentially short and wide rectangles. – Metagrapher Jan 31 '13 at 19:33
  • 1
    @madox2, could you please add comments to your code to facilitate its readability and ease the burden on the user to reverse engineer your code? (particularly the "if(y1 < y2){" statement) – Metagrapher Jan 31 '13 at 19:36
  • This is a good code, when adding transform:rotate('+deg+'deg), works also on IE11. – jacouh Jun 17 '14 at 12:10
  • Congratulations @John. I still have to parse out this code, think about what each line is doing, and see how it's relevant and why what was done was done in order to grok it, every time I read it. It's not exactly universally immediately comprehensible, but thanks for your "mee too" vote providing your anecdotal evidence. – Metagrapher Oct 27 '14 at 18:29
  • I didn't think I was being an asshole until my comment to you @John. Sorry. It wasn't my intent up until your comment, which I simply felt I was responding in kind. It sounds like a misunderstanding. Which is coincidental or ironic? I get lost on the intricacies of that definition. I guess I get lost easily, which is why I like comments. – Metagrapher Oct 28 '14 at 18:17
  • @Metagrapher "Reverse engineering" is what you do when you try to understand binary code. Applying that phrase to source code is being an asshole to the one who wrote it. – John Oct 28 '14 at 20:36
  • 6
    reverse engineering has a much broader use than simply understanding binary code. One can quite reverse engineer a television set if you like. This comment thread is getting a bit pedantic, no? There's never going to be agreement or a winner, just two guys trying to have bigger balls on the internet. Let's just drop the animosity and back and forth, eh, @John? – Metagrapher Oct 28 '14 at 21:58
  • Thanks for this solution. However, I found that after creating the line using `document.createElement`, if the created element is later appended to some container, say using jQuery's `append()`, the positioning gets messed. Solution was to store the style in an attribute on the element, and later retrieve and apply it after performing the `append()`. – JWL Jun 22 '20 at 14:13
10

you could define:

<div id="line1" class="line vertical"></div>
<div id="line2" class="line horizontal"></div>

.line {
  position: absolute;
  background-color: #000000;
}

.vertical { 
   width: 1px;
   height: 500px;
}

.horizontal {
   width: 500px;
   height: 1px;
}

#line1 {
   top: 20px;
   left: 50%;
}

#line2 {
   top: 260px;
   left: 25%;
}

/* for added rotation effects */
.forty-five {
   transform: rotate(45deg);
}

if you want to get into diagonal lines you could begin to try some rotation with transform: rotate(45deg); The IE Compatible method of rotating objects is discussed thoroughly here, which is terribly complicated. I do not know the IE compatible way to rotate divs, sorry., but that would work in Safari, Firefox, Chrome, and Opera.

[EDITS]

2014/11/08 - sjc - updated transform rules. Added MozDev links and IE rotation SO links.

Community
  • 1
  • 1
Metagrapher
  • 8,242
  • 1
  • 23
  • 31
  • also, you may not want to absolutely position the div. It depends on how you are using the line. If you are just doing a horizontal rule then there is actually a tag for that, too...
    – Metagrapher Nov 24 '10 at 19:13
6

i found myself needing a solution on this so i developped one using "hr" div and some gradient in border-image. Here is a Jsfiddle link to test it and the code below.

<html lang="fr">
<head>
<script>
    window.addEventListener("load",function(){
        function pow2(n){
            return n*n;
        }   

        var p1 = {
            id:"p1",
            x:150,
            y:50
        };
        var p2 = {
            id:"p2",
            x:300,
            y:250
        };
        var select = null;

        function getAngle(){

            var dist = Math.sqrt(pow2(p1.x-p2.x)+pow2(p1.y-p2.y));
            var l = document.getElementById("line");
            var cos = (p2.x-p1.x)/Math.sqrt(pow2(p2.x-p1.x)+pow2(p2.y-p1.y));
            var behind = p1.x < p2.x;
            var higher = p1.y > p2.y;
            l.style.width = (dist*2)+"px";
            l.style.left = (p1.x-dist)+"px";
            l.style.top = (p1.y)+"px";

            l.style.transform = "rotateZ("+(higher?-1:1)*Math.acos(cos)*(180/Math.PI)+"deg)";
        }

        var down = false

        document.addEventListener("mousemove",function(e){
            if(select){
                select.x = e.pageX;
                select.y = e.pageY;
                console.log(p1);
                var p = document.getElementById(select.id);
                p.style.left = (select.x-5)+"px";
                p.style.top = (select.y-5)+"px";
                getAngle();
            }
        });
        document.addEventListener("mouseup",function(e){
            if(!select)
                select = p1;
            else if(select == p1)
                select = p2;
            else 
                select = null;
        });
        document.addEventListener("mousedown",function(e){
            down = true;
        });
    });
</script>
</head>
<body>
<hr id="line" style="
position: absolute;
top: 50px;
left: -100px;
width: 500px;
margin: 0;
-webkit-transform: rotateZ(53.1deg);
border-width: 1px;      border-style: solid;                          
border-image: linear-gradient(to right, #ffffff 0%,#ffffff 49%,#000000 50%,#000000 100%) 1;
"/>
<div id="p1" style="
border-radius: 5px;
width: 10px;
background: #000;
position: absolute;
height: 10px;
top: 45px;
left: 145px;
"></div>
<div id="p2" style="
border-radius: 5px;
width: 10px;
background: #000;
position: absolute;
height: 10px;
top: 245px;
left: 295px;
"></div>
</body>
</html>

hope it helps someone :)

Insomniak Dev
  • 139
  • 2
  • 4
  • rotated
    with DOMelem.style.transform =rotateZ(angle) that's the good solution, are boring : no copy/paste, no really dynamic DOM into it, see http://robert.ocallahan.org/2011/11/drawing-dom-content-to-canvas.html why canvas must be avoided as possible
    – reuns Oct 17 '15 at 21:57
2

The <canvas> object is the easiest way (aside from plopping an image or using flash). Also, please post your code and tell us under what browser you're trying to use <canvas>. We can't tell you what you're doing wrong otherwise.

As far as support is concerned, from Wikipedia:

The element is currently supported by the latest versions of Mozilla Firefox, Google Chrome, Safari, and Opera. It is not natively implemented by Internet Explorer (IE) as of version 8[7], though support is in development for Internet Explorer 9; however, many of the Canvas element's features can be supported in IE, for example by using Google or Mozilla plugins, JavaScript libraries and either Adobe Flash or IE's proprietary VML.

SVG is another option, but (surprise!) IE doesn't it support it (IE9 is supposed to support some parts of it).

I'm also not sure what kind of line you want to draw. I mean, you could just make a div and only enable one of its borders - that would be a straight line.

Vivin Paliath
  • 91,149
  • 38
  • 215
  • 293
2

Not all browsers support the <canvas/> element. Try a cross-browser solution, like FlashCanvas or excanvas.

The alternative is using SVG.

Klemen Slavič
  • 19,431
  • 3
  • 32
  • 43
0

Hi there i made a jQuery plugin for that propose. It is crossbrowser and don't use SVG or CANVAS. Check it: https://github.com/tbem/jquery.line

tbem
  • 596
  • 4
  • 14
0

I find that the < hr > tag works very well if all you want is a horizontal line accross the page.

0

options for cross browser vector graphics include Raphaël and svgweb

tim
  • 131
  • 3
0

maybe this package can help. You specify starting and ending point for line that you want to draw. https://www.npmjs.com/package/draw-line-connect

Burak Gündüz
  • 216
  • 2
  • 9
-3

I found this code on w3schools.com at https://www.w3schools.com/tags/canvas_lineto.asp

var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.beginPath();
ctx.moveTo(0,0);
ctx.lineTo(300,150);
ctx.stroke();

this allows you to easily draw lines on a canvas. Hope this helps!

Pete K.
  • 92
  • 3
  • 11
  • 1
    You can't just copy code from W3Schools. Their code is not under a Creative Commons license. See also my answer on Meta: https://meta.stackexchange.com/a/141240/188419 – Emil Vikström Apr 06 '17 at 08:56
  • Thus without considering you need a canvas object to use the code above. – Andrea Moro Jul 03 '19 at 20:20