如何在svg中为图像标签创建边框?

时间:2015-04-11 08:31:24

标签: html svg stylesheet

我尝试在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>

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

2 个答案:

答案 0 :(得分:0)

2个选项:

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

在图像周围画一个矩形

option2 jsfiddle demo:

jsfiddle

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

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

答案 1 :(得分:0)

您只获得了底部边框,因为您的过滤器中只有一个<feOffset>可以向下移动SourceAlpha。因此只有底部边界。

如果您想坚持使用过滤器,那么您可以使用四个<feOffset>元素,这样您就可以获得所有四个边框。在下面的例子中,我实际上是在每个角落的方向上移动偏移,这样你就不会丢失角点像素。

<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>

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

更新:如何更改边框颜色

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

<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 in="newcolour"/>
            <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>