【问题标题】:How to create border for image tag in svg?如何在 svg 中为图像标签创建边框?
【发布时间】:2019-06-08 04:59:30
【问题描述】:

我尝试像这样在 svg 中为图像创建边框:

<svg id="svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1054 670" xml:space="preserve">
<defs>
    <filter id="f3" x="0" y="0" width="200%" height="200%">
      <feOffset result="offOut" in="SourceAlpha" dx="0" dy="1"></feOffset>
      <feGaussianBlur result="blurOut" in="offOut" stdDeviation="0.5"></feGaussianBlur>
      <feBlend in="SourceGraphic" in2="blurOut" mode="normal"></feBlend>
    </filter>
  </defs>

<image overflow="visible" x="5" width="200" height="300" filter="url(#f3)" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://upload.wikimedia.org/wikipedia/commons/9/9e/Flag_of_Japan.svg" >
    </image>    
</svg>

但它只是一个边框底部。如何在右上角和左上角添加边框。谢谢你

【问题讨论】:

    标签: html svg stylesheet


    【解决方案1】:

    您只会得到底部边框,因为您的过滤器中只有一个 &lt;feOffset&gt; 会向下移动 SourceAlpha。因此只有底部边框。

    如果你想坚持使用过滤器,那么你可以只使用四个&lt;feOffset&gt; 元素,这样你就可以得到所有四个边框。在下面的示例中,我实际上是在每个角的方向上移动偏移量,这样您就不会丢失角像素。

    <svg id="svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1054 670" xml:space="preserve">
    <defs>
        <filter id="f3">
          <feOffset result="nw" in="SourceAlpha" dx="-3" dy="-3"></feOffset>
          <feOffset result="ne" in="SourceAlpha" dx="3" dy="-3"></feOffset>
          <feOffset result="se" in="SourceAlpha" dx="3" dy="3"></feOffset>
          <feOffset result="sw" in="SourceAlpha" dx="-3" dy="3"></feOffset>
          <feMerge>
              <feMergeNode in="nw"/>
              <feMergeNode in="ne"/>
              <feMergeNode in="se"/>
              <feMergeNode in="sw"/>
              <feMergeNode in="SourceGraphic"/>
            </feMerge>
        </filter>
      </defs>
    
    <image overflow="visible" x="5" width="200" height="300" filter="url(#f3)" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://upload.wikimedia.org/wikipedia/commons/9/9e/Flag_of_Japan.svg" >
        </image>    
    </svg>

    四个角位移的 SourceAlpha 提供黑色边框。然后我们将原始图像合并到顶部。

    更新:如何更改边框颜色

    要使边框颜色不是黑色,我们必须向过滤器添加更多操作。最简单的方法是用新的边框颜色填充过滤器区域,然后用黑色边框矩形将其遮盖。完成后,我们可以像以前一样合并顶部的标志图像。

    <svg id="svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1054 670" xml:space="preserve">
    <defs>
        <filter id="f3">
            <!-- Make four copies of the image alpha, each moved to a different corner -->
            <feOffset result="nw" in="SourceAlpha" dx="-3" dy="-3"></feOffset>
            <feOffset result="ne" in="SourceAlpha" dx="3" dy="-3"></feOffset>
            <feOffset result="se" in="SourceAlpha" dx="3" dy="3"></feOffset>
            <feOffset result="sw" in="SourceAlpha" dx="-3" dy="3"></feOffset>
            <!-- Merge those four copies together -->
            <feMerge result="blackborder">
                <feMergeNode in="nw"/>
                <feMergeNode in="ne"/>
                <feMergeNode in="se"/>
                <feMergeNode in="sw"/>
            </feMerge>
            <!-- Create a filter primitive that is just a solid block of what will be
                 the new border colour (in this case orange) -->
            <feFlood flood-color="orange"/>
            <!-- Use the "in" operator to merge the blackborder with the orange fill.
                 Any parts of the orange fill that are "in"-side the back shape will remain.
                 The rest will me masked out. -->
            <feComposite in2="blackborder" operator="in" />
            <!-- Finally, merge the new orange border with the original image -->
            <feMerge>
                <feMergeNode/>
                <feMergeNode in="SourceGraphic"/>
            </feMerge>
        </filter>
    </defs>
    
    <image overflow="visible" x="5" y="5" width="200" height="300" filter="url(#f3)" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://upload.wikimedia.org/wikipedia/commons/9/9e/Flag_of_Japan.svg" >
        </image>    
    </svg>

    【讨论】:

    • 谢谢,这是我正在寻找的答案,那么我该如何更改边框颜色。我是 SVG 新手
    • 我添加了有关如何更改颜色的额外细节。
    • @PaulLeBeau 谢谢它很有用,只是一个帮助边框颜色更改似乎在 safari 中不起作用
    • 它在 Safari 中为我工作。您是否遇到了这个问题?:stackoverflow.com/questions/39756849/…
    • @PaulLeBeau 啊,我在 macOSX 的 safari 上很有趣,我在这里看到了问题。尝试了上面的Run code snippet,甚至创建了一个小提琴jsfiddle.net/invincibleJai/kmn8of3w
    【解决方案2】:

    2 个选项:

    1- 调整 SVG 元素的大小以匹配图像并使用 CSS 边框

    2- 在图像周围画一个矩形

    option2 jsfiddle demo:
    

    jsfiddle

    更新: 使用 javascript 以编程方式将矩形添加为图像的边框,并具有调整大小和边框颜色更改功能:

    function addBorders(image){
        var x = image.getAttribute("x");
        x = x ? x : 0;
        var y = image.getAttribute("y");
        y = y ? y : 0;    
        var w = image.getAttribute("width");
        var h = image.getAttribute("height");
    
        var g = document.createElementNS("http://www.w3.org/2000/svg", "g");    
    
        var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");    
        rect.setAttribute("style","fill:white; fill-opacity:0;stroke:black; stroke-width:2px;");
    
        rect.id = image.id + "rect";
        console.log(rect.id);
        rect.setAttribute("x",x);
        rect.setAttribute("y",y);
        rect.setAttribute("width",w);
        rect.setAttribute("height",h);
    
    
        var parent = image.parentNode;
        parent.insertBefore(g,image);
        g.appendChild(image);
        g.insertBefore(rect,image.nextSibling);
    
    }
    
    function redrawBorder(rect,w,h){
        rect.setAttribute("width",w);
        rect.setAttribute("height",h);    
    }
    
    window.updatePosition = function(image,x,y){
    
        document.getElementById(image.id + "rect")
        image.setAttribute("x",x);
        image.setAttribute("y",y);
        moveBorder(image.nextSibling,x,y);
    
    }
    
    function moveBorder(rect,x,y){
        rect.setAttribute("x",x);
        rect.setAttribute("y",y);    
    }
    
    window.updateSize = function(image,w,h){
    
        document.getElementById(image.id + "rect")
        image.setAttribute("width",w);
        image.setAttribute("height",h);
        redrawBorder(image.nextSibling,w,h);
    
    }
    
    window.updateColor = function(image,color){
    
         document.getElementById(image.id + "rect").style.stroke=color;
    }
    
    
    var image = document.getElementById("image1");
    addBorders(image);
    

    演示: jsfiddle

    【讨论】:

    • 谢谢你,但我正在寻找另一种方式,因为我需要显示许多其他尺寸的图像
    • 我更新了我的答案,JS 函数将在您的图像周围绘制一个矩形,无论其位置或大小如何。请检查代码下方的jsfiddle,更改图像x/y/hight/width值以查看效果。您还可以更改 rect 样式以更改颜色,虚线,虚线...等。希望有帮助
    • 我已经考虑过这种方式,但在 svg 图像中存在一个问题,如果 的宽度或高度小于图像的原始大小,则图像将自动调整大小,而刚刚创建的 rect 元素将不正确。
    • 你的意思是如果图像太小,图像会出现在边框的顶部?我更新了代码和 jsfiddle 来解决这个问题。请看一下
    • 是的,谢谢,这也是一个好方法,我试过像你一样创建矩形,但它显示不正确
    猜你喜欢
    • 2021-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-14
    • 2011-05-22
    • 2013-01-22
    • 1970-01-01
    相关资源
    最近更新 更多