不使用canvas(只用JS)绘制HTML线条

16

我想在页面上使用 HTML 绘制一条线。

从我所读的所有内容来看,HTML5 画布标记是最好的选择,但我需要将线连接到页面中不在画布标记内的某个东西,因此画布对我来说不太合适(需要使用本机 JS)。

我编写了一个函数(从其他地方找到),可以实现我所需的功能,但问题是一旦出现线条,页面的其他部分就会消失。

我发现每次在 JavaScript 中更改样式时,除形状外的其他部分都会消失。

删除 "document.write" 后什么也没有消失。

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>");
        }
    }
}

可能是在两个可拖动的div之间绘制一条线的重复问题。 - balupton
5个回答

18

快速解决方案。

下面的函数获取线的坐标然后绘制它。

它通过使用一个长而窄的 div 元素来实现。旋转角度和长度被计算出来。

应该在所有浏览器上(甚至是 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>"
}

7
调用您的方法两次将导致两个div具有相同的id。 - jantimon
2
一个问题是,如果您尝试创建从左下到右上的线条,则会生成错误。 是的,我会将id更改为class。如果您还需要一个id,可以在运行时轻松地为其提供动态id,该id由时间戳或任何其他您想要识别它的内容生成。 ID应该是唯一的。 - bjo
1
对我没用,而下面的答案(inteblio)却有效。 - daveagp
1
@Craig Taub:它没有正常工作。线的结束点远高于当前鼠标位置。你能展示一个可行的fiddle吗?另外,你能详细解释一下你是如何实现这个的吗? - darKnight
我认为这个功能无法正常工作。我已经添加了一个jsfiddle来测试它,但我认为线条坐标没有被正确计算(抱歉 - 我的数学水平不够好以修复它)。https://jsfiddle.net/Abeeee/yph13v6t/23/ - user1432181

7

我刚刚用纯JS+HTML代码开发了一个画直线的版本。
首先,正切函数定义在0到180度之间。如果x2大于x1,则反转这些点(x2变为x1,x1变为x2)。
然后我们检查这条线的长度(勾股定理),并测量其斜率。 有了斜率,我们就可以计算弧度角度。 要转换为度数,我们将结果乘以3.14并除以它。
最后,我们可以画一个高度为1px,宽度为lineLength的div。 我们根据计算出的角度旋转此div。

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>";
}

这似乎是一个更好的[可工作]解决方案。请参阅https://jsfiddle.net/Abeeee/8xh1zqam/1/。 - user1432181

2

我会看一下,我正在尝试使用纯JS(没有库)来完成它。我知道这并不总是在HTML5中完成某些事情的最佳方式。 - Craig Shipman

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);
}

1
这个在另一个stackoverflow页面上的答案很好用。我需要在图像上绘制,所以必须将图像放入具有ID的DIV中,并在后面的脚本中使用getElementById()调用。然后它就很好用了。该页面上的其他答案(Craig Taub)不起作用。我之所以这么说是因为我花了时间才意识到没有做错什么。它使用绘制旋转的细DIV的相同原理。我知道它在Chrome中可以工作。 在html页面上画线

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接