2017-11-18 173 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>