我有一个 D3 v4 力模拟,里面有 100 个节点。每个节点都是一个图像,我想为每个图像添加一个投影,但是,我认为由于我渲染投影的方式,这不会缩放。对于 100 张没有投影的图像,它运行 60fps,但投影更像是 8fps。有没有一个黑客解决方案,或者有更好的方法来做到这一点。这是我现在所拥有的(在图像后面的圆圈上渲染(:
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)")
如果您愿意自己完成更多繁重的工作,那么您可以考虑通过在每个项目后面添加节点并适当地缩放、定位和着色来近似于简单形状的投影。
在下面的示例中,我创建了一个额外的圆,它略大且偏离顶层圆。它还应用了自定义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>