16

I am trying to use HTML and draw a line on a page.

From everything I have read suggests HTML5 canvas tag is the best to use, but I need the line to connect to something on the page which is not in a canvas tag so canvas is not good for me (want/need to use native JS).

I have written (from something I found) a function which does what i need but problem is once line appears, everything else of page disappears.

I found that every time I change the style in JavaScript everything but the shape disappears.

Deleting "document.write" ends with nothing disappearing.

function draw(ax, ay, bx, by) {
    var n, widthLine, i, x, y;
    widthLine = 1;
    if (Math.abs(ax - bx) > Math.abs(ay - by)) {
        if (ax > bx) {
            n = ax;
            ax = bx;
            bx = n;

            n = ay;
            ay = by;
            by = n;
        }
        n = (by - ay) / (bx - ax);

        for (i = ax; i <= bx; i++) {
            x = i;
            y = Math.round(ay + m * (x - ax));
            document.write("<div style='height:" + lineWidth + "px;width:" + widthLine + "px;background-color:black;position:absolute;top:" + y + "px;left:" + x + "px;'></div>");
        }
    } else {
        if (ay > by) {
            n = ax;
            ax = bx;
            bx = n;

            n = ay;
            ay = by;
            by = n;
        }
        n = (bx - ax) / (by - ay);

        for (i = ay; i <= by; i++) {
            y = i;
            x = Math.round(ax + n * (y - ay));
            document.write("<div style='height:" + lineWidth + "px;width:" + lineWidth + "px;background-color:black;position:absolute;top:" + y + "px;left:" + x + "px;'></div>");
        }
    }
}
xxx
  • 1,153
  • 1
  • 11
  • 23
Craig Shipman
  • 187
  • 1
  • 1
  • 7
  • Possible duplicate of [Drawing a line between two draggable divs](https://stackoverflow.com/questions/6278152/drawing-a-line-between-two-draggable-divs) – balupton Nov 05 '18 at 20:43

5 Answers5

18

A quick fix.

The below function gets the coords of the line and then draws it.

It works by using a long and thin div element. The rotation angle and length are calculated.

Should work across all browsers (hopefully even IE).

function linedraw(ax,ay,bx,by)
{
    if(ay>by)
    {
        bx=ax+bx;  
        ax=bx-ax;
        bx=bx-ax;
        by=ay+by;  
        ay=by-ay;  
        by=by-ay;
    }
    var calc=Math.atan((ay-by)/(bx-ax));
    calc=calc*180/Math.PI;
    var length=Math.sqrt((ax-bx)*(ax-bx)+(ay-by)*(ay-by));
    document.body.innerHTML += "<div id='line' style='height:" + length + "px;width:1px;background-color:black;position:absolute;top:" + (ay) + "px;left:" + (ax) + "px;transform:rotate(" + calc + "deg);-ms-transform:rotate(" + calc + "deg);transform-origin:0% 0%;-moz-transform:rotate(" + calc + "deg);-moz-transform-origin:0% 0%;-webkit-transform:rotate(" + calc  + "deg);-webkit-transform-origin:0% 0%;-o-transform:rotate(" + calc + "deg);-o-transform-origin:0% 0%;'></div>"
}
Craig Taub
  • 4,169
  • 1
  • 19
  • 25
  • 7
    calling your method twice will result in two divs having the same id – jantimon Jan 28 '13 at 10:51
  • 2
    One problem with this is if you try to create a line starting bottom left to top right, it will generate incorrectly. Yes, I would change id to class. If you needed an id on it as well, you could easily give it a dynamic id at runtime generated by a timestamp or anything else you might want to identify it by. Id's should be unique. – bjo Apr 29 '13 at 16:08
  • 1
    Did not work for me, whereas the below answer (inteblio) worked – daveagp Jan 21 '18 at 18:49
  • 1
    @Craig Taub: It's not working properly. The line is end point of the line is drawn much above the current mouse position. Can you show a working fiddle for this? Also can you explain a bit how you are achieving this? – darKnight May 27 '18 at 21:24
  • I don't think I see this working accurately. I've added a jsfiddle to test this and I don't think the line coords are being correctly worked out (sorry - my maths is not good enough to fix it). https://jsfiddle.net/Abeeee/yph13v6t/23/ – user1432181 Apr 23 '21 at 15:36
7

I just developed my version on drawing a line in pure js + html code.
First of all the tan function is defined between 0 and 180 degrees. If x2 is bigger than x1 we invert these points (x2 becomes x1, and x1 becomes x2).
After that we check the length of this line (Pythagorean theorem) and we measure the slope. With the slope we can calculate the degree in radiants. To convert in degrees we multiply the result and we divide it by 3.14.
Finally we can draw a div with an height of 1px and a width of lineLength. We rotate this div based to the calculated one.

function linedraw(x1, y1, x2, y2) {
    if (x2 < x1) {
        var tmp;
        tmp = x2 ; x2 = x1 ; x1 = tmp;
        tmp = y2 ; y2 = y1 ; y1 = tmp;
    }

    var lineLength = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
    var m = (y2 - y1) / (x2 - x1);

    var degree = Math.atan(m) * 180 / Math.PI;

    document.body.innerHTML += "<div class='line' style='transform-origin: top left; transform: rotate(" + degree + "deg); width: " + lineLength + "px; height: 1px; background: black; position: absolute; top: " + y1 + "px; left: " + x1 + "px;'></div>";
}
Reality
  • 637
  • 1
  • 6
  • 25
Davide
  • 1,931
  • 2
  • 19
  • 39
2

This javascript graphic library seems very suited for what you want to achieve.

Nelson
  • 49,283
  • 8
  • 68
  • 81
  • will have a look, am trying to do it in pure js really (no library). i know this is not always best way to do something specially in html5 – Craig Shipman Jan 28 '13 at 11:00
1

This answer on another stack overflow page works well. I was drawing over an image. I needed to put the image in a DIV with an ID that was later used in the script in the getElementById() call. Then it works great. The other answer on the page (Craig Taub) does not work. I say this because it cost me time to realise it was nothing I was doing wrong. It uses the same principle of drawing a thin div which is rotated. I know it works in chrome.

Drawing lines on html page

Community
  • 1
  • 1
inteblio
  • 113
  • 1
  • 6
1

updated to:

lineDraw(ax, ay, bx, by) {
    if(ax > bx) {
        bx = ax + bx; 
        ax = bx - ax;
        bx = bx - ax;

        by = ay + by;
        ay = by - ay;
        by = by - ay;
    }

    let distance = Math.sqrt(Math.pow(bx - ax, 2) + Math.pow(by - ay, 2));
    let calc = Math.atan((by - ay) / (bx - ax));
    let degree = calc * 180 / Math.PI;

    let line = document.createElement('div');
    line.style.css({
        position: 'absolute',
        height: '1px',
        transformOrigin: 'top left',
        width: distance,
        top: ay + 'px',
        left: ax + 'px',
        transform: `rotate(${degree}deg)`,
        backgroundColor: 'back',
    });
    document.body.appendChild(line);
}