2017-11-18 176 views
2

我有一个D3 v4力仿真,其中有100个节点。每个节点都是一个图像,我想为每个图像添加一个阴影,但是,我认为由于我呈现阴影的方式,这不会缩放。 100个没有阴影的图像运行60fps,但是阴影更像8fps。有没有一个hacky的解决方案,或者更好的方法来做到这一点。以下是我现在所拥有的(渲染上的图像后面的圆圈):将阴影添加到很多D3力模拟节点?

var dropShadowFilter = this.d3Graph.append('svg:filter') 
    .attr('id', 'drop-shadow') 
    .attr('filterUnits', "userSpaceOnUse") 
    .attr('width', '250%') 
    .attr('height', '250%'); 
dropShadowFilter.append('svg:feGaussianBlur') 
    .attr('in', 'SourceGraphic') 
    .attr('stdDeviation', 2) 
    .attr('result', 'blur-out'); 
dropShadowFilter.append('svg:feColorMatrix') 
    .attr('in', 'blur-out') 
    .attr('type', 'hueRotate') 
    .attr('values', 180) 
    .attr('result', 'color-out'); 
dropShadowFilter.append('svg:feOffset') 
    .attr('in', 'color-out') 
    .attr('dx', 3) 
    .attr('dy', 3) 
    .attr('result', 'the-shadow'); 
dropShadowFilter.append('svg:feBlend') 
    .attr('in', 'SourceGraphic') 
    .attr('in2', 'the-shadow') 
    .attr('mode', 'normal'); 


this.node = this.d3Graph.selectAll(null) 
    .data(Nodes) 
    .enter() 
    .append("g") 
    .attr("class", "nodes"); 

this.node.append("circle") 
    .attr("r", 30) 
    .attr("fill", "red") 
    .style("filter", "url(#drop-shadow)") 
+0

如果每个节点都有追加到它们的图像,你可以创建为每个图像的照片编辑应用程序中的阴影效果,而不是使用SVG过滤 –

+0

这穿过我的脑海,但不幸的是,我不这么认为。当它们彼此靠近时,阴影最终会与其他节点重叠,这看起来不正确。 – PurplePanda

回答

1

如果你愿意做更多繁重的自己,那么你可以考虑通过增加节点逼近的简单形状阴影在每个项目后面进行缩放,定位和着色。

在下面的示例中,我创建了一个稍大于顶层圆圈的额外圆圈。它也有一个自定义的fake-shadow径向渐变应用。

var d3Graph = d3.select('svg') 
 

 
var dropShadowFilter = d3Graph.append('svg:filter') 
 
    .attr('id', 'drop-shadow') 
 
    .attr('filterUnits', "userSpaceOnUse") 
 
    .attr('width', '250%') 
 
    .attr('height', '250%'); 
 
dropShadowFilter.append('svg:feGaussianBlur') 
 
    .attr('in', 'SourceGraphic') 
 
    .attr('stdDeviation', 2) 
 
    .attr('result', 'blur-out'); 
 
dropShadowFilter.append('svg:feColorMatrix') 
 
    .attr('in', 'blur-out') 
 
    .attr('type', 'hueRotate') 
 
    .attr('values', 180) 
 
    .attr('result', 'color-out'); 
 
dropShadowFilter.append('svg:feOffset') 
 
    .attr('in', 'color-out') 
 
    .attr('dx', 3) 
 
    .attr('dy', 3) 
 
    .attr('result', 'the-shadow'); 
 
dropShadowFilter.append('svg:feBlend') 
 
    .attr('in', 'SourceGraphic') 
 
    .attr('in2', 'the-shadow') 
 
    .attr('mode', 'normal'); 
 

 
var simpleGradient = d3Graph.append('defs') 
 
    .append('radialGradient') 
 
    .attr('id', 'fake-shadow'); 
 
simpleGradient.append('stop') 
 
    .attr('offset', "80%") 
 
    .attr('stop-color', '#01AFAF'); 
 
simpleGradient.append('stop') 
 
    .attr('offset', "100%") 
 
    .attr('stop-color', "#01AFAF00");
body { 
 
    background: papayawhip 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> 
 
<svg height="120" width="600" text-anchor="middle"> 
 
<text x="200" y="105">Original</text> 
 
<text x="400" y="105">Fake Shadow</text> 
 
<circle cx="200" cy="50" r="30" filter="url(#drop-shadow)" fill="red"/> 
 
<circle cx="403" cy="53" r="32.5" fill="url(#fake-shadow)"/> 
 
<circle cx="400" cy="50" r="30" fill="red"/> 
 
</svg>