目前正在构建一个基于浏览器的SVG应用程序。在这个应用程序中,用户可以设置各种形状的样式和位置,包括矩形。

当我将笔画宽度应用到SVG矩形元素(比如1px)时,不同的浏览器会以不同的方式将笔画应用到矩形的偏移和插入。这被证明是很麻烦的,特别是当我试图计算一个矩形的外部宽度和视觉位置,并将其放置在其他元素旁边时。

例如:

Firefox添加了1px的插入(底部和左侧)和1px的偏移(顶部和右侧) Chrome添加了1px的插入(顶部和左侧),和1px的偏移(底部和右侧)

到目前为止,我唯一的解决方案是自己绘制实际的边界(可能是用路径工具),并将边界定位在描边元素的后面。但这种解决方案是一种令人不快的变通方法,如果可能的话,我宁愿不走这条路。

所以我的问题是,你能控制SVG的笔画宽度如何在元素上绘制吗?


当前回答

不能,不能指定笔画在元素内部还是外部。我在2003年向SVG工作组提出了这个功能的建议,但是没有得到任何支持(或讨论)。

正如我在提案中提到的,

你可以通过加倍描边宽度来实现与“inside”相同的视觉效果,然后使用剪辑路径将对象剪辑到自身 你可以通过将描边宽度加倍,然后将对象的无描边副本叠加在其上,从而获得与“外部”相同的视觉效果。

编辑:这个答案将来可能是错误的。应该可以使用SVG矢量效果来实现这些结果,通过结合veStrokePath与veIntersect(用于“内部”)或与veExclude(用于“外部”)。然而,矢量效果仍然是一个工作草案模块,没有实现,我还能找到。

编辑2:SVG 2规范草案包括一个笔画对齐属性(在可能的值之外的|中有中心|)。这个特性可能最终会被应用到无人机中。

编辑3:有趣而令人失望的是,SVG工作组已经从SVG 2中删除了笔画对齐。您可以在这里看到文章之后描述的一些问题。

其他回答

不能,不能指定笔画在元素内部还是外部。我在2003年向SVG工作组提出了这个功能的建议,但是没有得到任何支持(或讨论)。

正如我在提案中提到的,

你可以通过加倍描边宽度来实现与“inside”相同的视觉效果,然后使用剪辑路径将对象剪辑到自身 你可以通过将描边宽度加倍,然后将对象的无描边副本叠加在其上,从而获得与“外部”相同的视觉效果。

编辑:这个答案将来可能是错误的。应该可以使用SVG矢量效果来实现这些结果,通过结合veStrokePath与veIntersect(用于“内部”)或与veExclude(用于“外部”)。然而,矢量效果仍然是一个工作草案模块,没有实现,我还能找到。

编辑2:SVG 2规范草案包括一个笔画对齐属性(在可能的值之外的|中有中心|)。这个特性可能最终会被应用到无人机中。

编辑3:有趣而令人失望的是,SVG工作组已经从SVG 2中删除了笔画对齐。您可以在这里看到文章之后描述的一些问题。

下面是一个函数,它将计算你需要添加多少像素-使用给定的笔画-到顶部,右侧,底部和左侧,所有这些都基于浏览器:

var getStrokeOffsets = function(stroke){

        var strokeFloor =       Math.floor(stroke / 2),                                                                 // max offset
            strokeCeil =        Math.ceil(stroke / 2);                                                                  // min offset

        if($.browser.mozilla){                                                                                          // Mozilla offsets

            return {
                bottom:     strokeFloor,
                left:       strokeFloor,
                top:        strokeCeil,
                right:      strokeCeil
            };

        }else if($.browser.webkit){                                                                                     // WebKit offsets

            return {
                bottom:     strokeCeil,
                left:       strokeFloor,
                top:        strokeFloor,
                right:      strokeCeil
            };

        }else{                                                                                                          // default offsets

            return {
                bottom:     strokeCeil,
                left:       strokeCeil,
                top:        strokeCeil,
                right:      strokeCeil
            };

        }

    };

我发现最简单的方法是将clip-path添加到circle中

添加clip-path = "圆()"

<circle id="circle" clip-path="circle()" cx="100" cy="100" r="100" fill="none" stroke="currentColor" stroke-width="5" />

然后stroke-width="5"将神奇地变成内5px笔画,绝对半径为100px。

我发现了一个简单的方法,虽然有一些限制,但对我来说很有效:

在defs中定义形状 定义一个引用形状的剪辑路径 使用它和双重中风与外部是修剪

下面是一个工作示例:

<svg width="240" height="240" viewBox="0 0 1024 1024"> < def > <path id="ld" d="M256,0 L0,512 L384,512 L128,1024 L1024,384 L640,384 L896,0 L256,0 Z"/> < clipPath id =“剪辑”> <使用xlink: href = " # ld " / > < / clipPath > < / def > < g > <使用xlink:href="#ld" stroke="#0081C6" stroke-width="160" fill="#00D2B8" clip-path="url(#clip)" / > < / g > < / svg >

这招对我很管用:

.btn {
 border: 1px solid black;
 box-shadow: inset 0 0 0 1px black;
}