首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何用D3防止小形状的边缘阴影

如何用D3防止小形状的边缘阴影
EN

Stack Overflow用户
提问于 2014-03-27 10:18:46
回答 2查看 563关注 0票数 2

我正在开发一个小的教育工具,我想为SVG路径添加阴影。为了构造我的图形,我使用了D3.js。这通常很好用,但对于特定的形状,我会遇到问题,特别是对于具有水平和/或垂直线的小形状。

为了说明这一点,我用三个三角形制作了一个JSFiddle实例。绿色三角形上的阴影看起来很漂亮,橙色三角形上的阴影看起来还不错,但是红色三角形上的阴影看起来很难看。

阴影是使用这段代码作为示例创建的:

代码语言:javascript
复制
var defs = svg.append("defs").attr("height","160%");
var filter = defs.append("filter").attr("id", "schaduw");
filter.append("feGaussianBlur").attr("in", "SourceAlpha")
      .attr("stdDeviation", 5).attr("result", "blur");
filter.append("feOffset").attr("in", "blur")
      .attr("dx", 3)
      .attr("dy", 3)
      .attr("result", "offsetBlur");
var feMerge = filter.append("feMerge");
feMerge.append("feMergeNode").attr("in", "offsetBlur");
feMerge.append("feMergeNode").attr("in", "SourceGraphic");

从JSFiddle代码中可以看出,形状之间唯一有意义的区别是它们的大小。我怎样才能防止这些小形状出现丑陋的阴影呢?

任何帮助都非常感谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-03-27 10:37:22

您所指的阴影的质量是由您使用的高斯模糊度的标准差控制的。使用绝对值就意味着阴影是“分散”相同的数量,而不管您使用过滤器的元素的大小如何。对于较小的形状,这有你看到的效果。

有两种方法可以解决这个问题。快速和容易的方法是减少标准差,使它看起来很好,即使是最小的形状。在您的示例这里中,我通过设置.attr("stdDeviation", 1)实现了这一点。

另一种选择是,对于不同的形状尺寸,有不同的标准偏差,就像我用黑客的方式做了这里一样。这可能要困难得多,因为它需要计算形状的大小,确定合适的标准差,如果不存在,可能需要创建适当的过滤器。而且,阴影看起来不太一致。

票数 0
EN

Stack Overflow用户

发布于 2014-04-12 00:52:20

您的阴影正在被基础SVG过滤器的筛选区域裁剪。默认情况下,过滤效果显示在过滤形状周围的10%溢出区域中。你的阴影在较小的形状上太大,并且正在溢出该区域。这导致了边缘。您需要添加一个显式筛选区域并使其更大。这将将过滤区域扩展到形状周围的20%区域:

代码语言:javascript
复制
var filter = defs.append("filter").attr("id", "schaduw") .attr("width", 1.4) 
    .attr("height",1.4) .attr("x",-0.2) .attr("y",-0.2);

如果您想要一个与过滤元素成比例的阴影,则不需要计算任何内容的大小。SVG有一个内置功能,可以通过在objectBoundingBox单元中定义单元来进行相对大小调整。在这里,您应该使用objectBoundingBox单元作为过滤器基本单元,而不是userSpaceUnits (“常规”视图框单元)的默认(静默)。您需要重新声明模糊元素的stdDeviation,以及以十进制表示的原始元素框%s中偏移量的偏移量:

代码语言:javascript
复制
var filter = defs.append("filter").attr("id", "schaduw") .attr("width", 1.4) 
     .attr("height",1.4) .attr("x",-0.2) .attr("y",-0.2)     
     .attr("primitiveUnits","objectBoundingBox");
filter.append("feGaussianBlur").attr("in", "SourceAlpha")
              .attr("stdDeviation", .02).attr("result", "blur");
filter.append("feOffset").attr("in", "blur")
              .attr("dx", .01)
              .attr("dy", .01)
              .attr("result", "offsetBlur");
var feMerge = filter.append("feMerge");
feMerge.append("feMergeNode").attr("in", "offsetBlur");
feMerge.append("feMergeNode").attr("in", "SourceGraphic");

现在,你会注意到这看起来有点奇怪,因为只要你想让所有的形状看起来都像在同一个平面上,你的阴影大小就应该是一致的,不管它们有多小或多大。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22684541

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档