2014-03-27 37 views
2

我正在开发一个小型教育工具,为此我想将阴影添加到SVG路径。为了构建我的图形,我使用了D3.js.这通常是可爱的,但具体的形状我遇到了问题,特别是对于具有水平和/或垂直线的小形状。如何防止使用D3的小形状的前卫阴影

为了说明这一点,我做了一个JSFiddle example三个三角形。绿色三角形上的阴影看起来很漂亮,橙色三角形上的阴影仍然正常,但红色三角形上的阴影看起来非常难看。

阴影使用this code作为示例中创建:

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码中可以看出,形状之间的唯一有意义的区别是它们的大小。我怎样才能防止小的形状有丑陋的阴影?

任何帮助非常感谢! =)

回答

0

您引用的阴影质量由您使用的高斯模糊的标准偏差控制。在这里使用绝对值意味着无论您使用过滤器的元素的大小如何,阴影都是“分散”的。对于较小的形状,这有你看到的效果。

有两种方法可以解决这个问题。快速简便的方法是降低标准偏差,使其即使对于最小的形状也很好看。我已经通过设置.attr("stdDeviation", 1)在您的示例here中完成了此操作。

另一种选择是针对不同的形状尺寸有不同的标准偏差,因为我用哈克的方式完成了here。这会更困难,因为它需要您计算形状的大小,确定合适的标准偏差,并可能创建适当的过滤器(如果不存在)。此外,阴影看起来不太一致。

1

您的阴影正在被基础SVG滤镜的滤镜区域裁剪。默认过滤器效果显示在过滤形状周围的10%溢出区域中。您在较小形状上的阴影太大,并且溢出该区域。这是造成边缘。你需要添加一个明确的过滤区域并使其更大。这将扩大过滤区周围形状的20%区域:

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以小数表示:

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"); 

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

相关问题