【问题标题】:Draw a line between two elements with hover用悬停在两个元素之间画一条线
【发布时间】:2013-10-08 10:25:13
【问题描述】:

我已经看到了很多关于如何做到这一点的例子,但没有一个能做我需要做的事情。

我想要做的是,当某个图像(如果需要,它可以被包裹在一个单独的 div 中)悬停在上面时,它会从该图像的中心绘制一条线到另一个图像的中心(或者可能从第一张图片的中心到其他几张图片的中心),鼠标移开,它又回到原来的状态。

我尝试使用 HTML5 画布,但是当我尝试在画布上绘制一条线同时在画布上移动 HTML(图像)时,图像覆盖了画布并绘制了线条。当我尝试更改画布的 z-index 时,它起作用了,只是画布覆盖了 HTML 并使现有的悬停图像更改不起作用。

我找到了常规的 JS 绘制线示例,但它们都依赖于知道要绘制的确切点...有没有什么方法可以通过 JS 计算确切的点而不需要被硬编码进去?悬停时显示绘制的线条?

【问题讨论】:

  • 使图像成为画布的一部分。
  • 如果你想获得绘画的感觉,你应该继续使用画布。如果带边框的隐藏 div 可以满足您的需求,请告诉我们

标签: javascript css html canvas


【解决方案1】:

作为一种非常规的选择,您可以尝试this library。这是一个 pre-HTML5-canvas oldie-but-still-goodie。它能够将任何 DIV 转换为伪“画布”,您可以在此 DIV 中包含任何 HTML 元素并在它们之间进行各种绘图。

例如,如果您这样定义“画布”:

<div id="myCanvas" style="position: relative;"></div>

您可以像这样初始化库,设置颜色,笔触大小和画线:

var jg = new jsGraphics("myCanvas");

jg.setColor("#0000FF");
jg.setStroke(2);
jg.drawLine(x1, y1, x2, y2);

jg.paint();

它不是 HTML5 画布,但它是一个“画布”,您可以直接在其中放置 DOM 元素并在其中绘制。

这是一个小演示:http://jsfiddle.net/Rs5eY/1/ 将鼠标悬停在顶部图像上。

【讨论】:

    【解决方案2】:

    如何使用这种替代方法来突出图像之间的联系(如果您的设计允许):

    • 添加一个足够宽/高的背景画布,以容纳所有 html img。
    • 将您的 html img 添加到画布顶部(而不是画布的一部分)。
    • 悬停时,在画布上绘制连接线并在连接的图像周围放置高亮边框。
    • 离开时,清除画布连接线并移除 img 边框。

    这是代码和小提琴:http://jsfiddle.net/m1erickson/4n9GK/

    <!doctype html>
    <html>
    <head>
    <link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
    <script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
    
    <style>
        body{ background-color: ivory; }
        #canvas{border:1px solid red;}
        #img1{position:absolute; left:30px; top:30px; }
        #img2{position:absolute; left:200px; top:180px; }
        #img3{position:absolute; left:30px; top:330px; }
        #img4{position:absolute; left:200px; top:30px; }
        #img5{position:absolute; left:30px; top:180px; }
        #img6{position:absolute; left:200px; top:330px; }
    </style>
    
    <script>
    $(function(){
    
        var canvas=document.getElementById("canvas");
        var ctx=canvas.getContext("2d");
    
        ctx.fillStyle="skyblue";
        ctx.fillRect(0,0,canvas.width,canvas.height);
    
    
        $(".connectable").hover(
    
            function(){connectGroup(this);},
            function(){unconnectGroup(this);}
    
        );
    
        function connectGroup(element){
    
            var $element=$(element);
    
            var hubId=$element.attr("id");
            var p=$element.position();
            var hubX=p.left;
            var hubY=p.top;
            var hubW=$element.width();
            var hubH=$element.height();
            ctx.fillStyle="green";
            ctx.fillRect(hubX-3,hubY-3,hubW+6,hubH+6);
    
            var group=$element.attr("data-group");
    
            var g="img[data-group='"+group+"']"
    
            var $group=$(g);
    
            var notG="img:not("+g+")";
            var $hidden=$(notG);
            $hidden.fadeOut();
    
            $group.each(function(){
    
                var $groupMember=$(this);
    
                var id=$groupMember.attr("id");
    
                if(id!=hubId){
                    var p=$groupMember.position();
                    var x=p.left;
                    var y=p.top;
                    var w=$groupMember.width();
                    var h=$groupMember.height();
                    ctx.fillStyle="green";
                    ctx.strokeStyle="green";
                    ctx.beginPath();
                    ctx.moveTo(hubX+hubW/2,hubY+hubH/2);
                    ctx.lineTo(x+w/2,y+h/2);
                    ctx.stroke();
                    ctx.fillRect(x-3,y-3,w+6,h+6);
                }
    
            });
    
        }
    
        function unconnectGroup(element){
            // clear the canvas
            ctx.clearRect(0,0,canvas.width,canvas.height);
            // show the hidden images
            $("img").show();
        }
    
    
    
    }); // end $(function(){});
    </script>
    
    </head>
    
    <body>
        <canvas id="canvas" width=330 height=450></canvas>
        <img id="img1" class="connectable" data-group="1" src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house-icon.png" width=100 height=100/>
        <img id="img2" class="connectable" data-group="1" src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house-icon.png" width=100 height=100/>
        <img id="img3" class="connectable" data-group="1" src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house-icon.png" width=100 height=100/>
        <img id="img4" class="connectable" data-group="2" src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/ship.png" width=100 height=100/>
        <img id="img5" class="connectable" data-group="2" src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/ship.png" width=100 height=100/>
        <img id="img6" class="connectable" data-group="2" src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/ship.png" width=100 height=100/>
        <h3>Hover over image to show connections</h3>
    </body>
    </html>
    

    【讨论】:

    • 好吧......我想我可以弄清楚如何制作背景画布并使用 CSS 将 HTML 放置在画布顶部(我在几个小时前做了)。但是,我将如何进行悬停并将其与画布连接(然后离开清除画布)?理想的情况是,如果我可以为每个 img 分配一个数据连接和一个 data-id attr,并且如果一个 img 悬停,它会在包含与对应的 data-id attr 的图像上画一条线data-connection attr, 即 data-connection='2', data-id='1' 会画一条线说, data-con='1', data-id='1', 什么的
    • 我已将示例代码添加到我的答案中。说明:悬停时,(1)获取目标元素,(2)获取该元素的数据组,(3)获取该数据组的所有成员(4)隐藏不属于该数据成员的所有图像-group, (5) 使用画布(在图像下方)绘制从目标图像连接到其组中所有数据组元素的高亮边框和线条。离开后 (1) 清除画布 - 清除突出显示和连接器,(2) 重新显示以前隐藏的图像。免责声明:我使用了 jQuery——如果没有它,那就太疯狂了!
    【解决方案3】:

    正如@Boaz 建议的那样,理想情况下,您希望将图像作为画布的一部分,同时在一些 javascript 变量中保留您绘制它们的位置。然后您可以以编程方式在图像之间绘制线条,因为所有内容都将连接在同一画布实例上。有什么理由你不能这样做吗?

    【讨论】:

    • 好吧,我不是真的在画图像(是吗?),图像中已经包含 JavaScript:&lt;a href="page.php?x=1895&amp;y=2015"&gt;&lt;img style='background:url(images/tile_2.png)' class='xyz' data-alt-src='images/X.png' data-name=' &amp;nbsp; ' src="images/tile_2.png" /&gt;&lt;/a&gt;,当悬停时,图像 URL 已经更改为 alt -src 然后数据名称显示在 TD 中......据我所知,我不能轻易地将现有代码(因为大约有 100 个此类图像)放在画布中,或者可以我?
    猜你喜欢
    • 1970-01-01
    • 2011-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多