代码之家  ›  专栏  ›  技术社区  ›  manymanymore

使用filters和d3.js部分更改svg中的阴影不透明度

  •  4
  • manymanymore  · 技术社区  · 6 年前

    如何使用filters和d3.js部分更改svg中的阴影不透明度?

    以下是我希望我的影子看起来的样子: enter image description here

    我是说阴影被写着 Entity Name

    以下是我迄今所能取得的成就:

    var svg = d3.select("#drawRegion")
                    .append("svg")
                    .attr("width", "100%")
                    .attr("height", "100%");
                    
                    
    var defs = svg.append("defs");
    
    var filter = defs.append("filter")
                     		.attr("id","coolShadow");
    
    filter.append("feMorphology")
      .attr("in", "SourceGraphic")
      .attr("result", "upperLayer")
      .attr("operator", "dilate")
      .attr("radius", "2 2");
    
    filter.append("feMorphology")
      .attr("in", "SourceAlpha")
      .attr("result", "enlargedAlpha")
      .attr("operator", "dilate")
      .attr("radius", "3 5");
    
    filter.append("feGaussianBlur")
      .attr("in", "enlargedAlpha")
      .attr("result", "bluredAlpha")
      .attr("stdDeviation", "5");
      
    filter.append("feOffset")
      .attr("in", "bluredAlpha")
      .attr("result", "lowerLayer")
      .attr("dy", "3");
    
    
    var feMerge = filter.append("feMerge");
    feMerge.append("feMergeNode")
      .attr("in","lowerLayer");
    feMerge.append("feMergeNode")
      .attr("in","upperLayer");
    
    svg.append("rect")
        .attr("rx", 2)
        .attr("ry", 2)
    	.attr("x", "20%")
      .attr("y", "20%")
      .attr("width", "60%")
      .attr("height", "60%")
      .attr("fill", "white")
      .style("filter", "url(#coolShadow)");
      
      
      
      
      
      
      
      
    #drawRegion {
        width: 100%;
        height: 100%;
        display: inline-block;
        position: fixed;
        top: 0;
        bottom: 0;
        left: 0;
        right: 0;
        margin: auto;
        position: relative;
    }
    <div id="drawRegion">
    
    </div>
    <script src="https://d3js.org/d3.v5.min.js"></script>

    正如你所看到的,阴影已经准备好了。唯一我不知道如何实现的是增加的不透明度(现在它太大了,我想降低它,但同时保留在左,上,右边界的透明度)。

    我尝试降低整体的不透明度,但没有帮助:左边框、上边框和右边框的透明度也降低了,而我希望使下边框部分更透明,并保留其他边框不变。

    如果有任何更正,使我能够处理这一问题,或提出完全不同的解决办法,我将不胜感激。

    2 回复  |  直到 6 年前
        1
  •  1
  •   Michael Mullany    6 年前

    最好的方法来实现你想要做的是拨回y半径在第二个女性形态和y在feoffset。有一些方法可以有选择地减少不透明度,但它们会导致阴影的不连续性——这可能是你不想要的。

    (你还需要扩展你的过滤区域-我在这里为你做的)。

    我想知道,为什么你要用女性形态来扩展源矩形?如果您想要一个更大的圆角矩形,您可以直接在SVG中绘制它-它将更具性能。女性形态学是一个缓慢的操作。

    var svg = d3.select("#drawRegion")
                    .append("svg")
                    .attr("width", "100%")
                    .attr("height", "100%");
                    
                    
    var defs = svg.append("defs");
    
    var filter = defs.append("filter")
                     		.attr("id","coolShadow")
                     		.attr("y","-20%")
                     		.attr("height","140%");
    
    filter.append("feMorphology")
      .attr("in", "SourceGraphic")
      .attr("result", "upperLayer")
      .attr("operator", "dilate")
      .attr("radius", "2 2");
    
    filter.append("feMorphology")
      .attr("in", "SourceAlpha")
      .attr("result", "enlargedAlpha")
      .attr("operator", "dilate")
      .attr("radius", "3 3");
    
    filter.append("feGaussianBlur")
      .attr("in", "enlargedAlpha")
      .attr("result", "bluredAlpha")
      .attr("stdDeviation", "5");
      
    filter.append("feOffset")
      .attr("in", "bluredAlpha")
      .attr("result", "lowerLayer")
      .attr("dy", "2");
    
    var feMerge = filter.append("feMerge");
    feMerge.append("feMergeNode")
      .attr("in","lowerLayer");
    feMerge.append("feMergeNode")
      .attr("in","upperLayer");
    
    svg.append("rect")
        .attr("rx", 2)
        .attr("ry", 2)
    	.attr("x", "20%")
      .attr("y", "20%")
      .attr("width", "60%")
      .attr("height", "60%")
      .attr("fill", "white")
      .style("filter", "url(#coolShadow)");
      
      
      
      
      
      
      
      
    #drawRegion {
        width: 100%;
        height: 100%;
        display: inline-block;
        position: fixed;
        top: 0;
        bottom: 0;
        left: 0;
        right: 0;
        margin: auto;
        position: relative;
    }
    <div id="drawRegion">
    
    </div>
    <script src="https://d3js.org/d3.v5.min.js"></script>
        2
  •  1
  •   Xavier Guihot    6 年前

    你们两个都可以玩 opacity dy 属性。

    不透明度将使阴影全局变亮或变暗(值介于0和1之间)。

    这个 属性(同样适用于 dx )垂直移动阴影(“移动光源”)。

    如果 0 ,则阴影位于形状的中心(光源正好位于形状的上方)。如果(和你的情况一样) 是正的,那么阴影将被转换到底部,因此在阴影的形状下会更加明显。

    下面是一个例子 不透明度 0.3 :

    .style("opacity", 0.3)
    

    (你可以用它来调整你的风格):

    .attr("dy", "0")
    

    var svg = d3.select("#drawRegion")
                    .append("svg")
                    .attr("width", "100%")
                    .attr("height", "100%");
                    
                    
    var defs = svg.append("defs");
    
    var filter = defs.append("filter")
                     		.attr("id","coolShadow")
                        .attr("x", "-100%").attr("y", "-100%") //
                        .attr("width", "300%").attr("height", "300%"); //
    
    filter.append("feMorphology")
      .attr("in", "SourceGraphic")
      .attr("result", "upperLayer")
      .attr("operator", "dilate")
      .attr("radius", "2 2");
    
    filter.append("feMorphology")
      .attr("in", "SourceAlpha")
      .attr("result", "enlargedAlpha")
      .attr("operator", "dilate")
      .attr("radius", "3 5");
    
    filter.append("feGaussianBlur")
      .attr("in", "enlargedAlpha")
      .attr("result", "bluredAlpha")
      .attr("stdDeviation", "4");
      
    filter.append("feOffset")
      .attr("in", "bluredAlpha")
      .attr("result", "lowerLayer")
      .attr("dy", "0"); //
    
    
    var feMerge = filter.append("feMerge");
    feMerge.append("feMergeNode")
      .attr("in","lowerLayer");
    feMerge.append("feMergeNode")
      .attr("in","upperLayer");
    
    svg.append("rect")
        .attr("rx", 2)
        .attr("ry", 2)
    	.attr("x", "20%")
      .attr("y", "20%")
      .attr("width", "60%")
      .attr("height", "60%")
      .attr("fill", "white")
      .style("filter", "url(#coolShadow)")
      .style("opacity", 0.3); //
    #drawRegion {
        width: 100%;
        height: 100%;
        display: inline-block;
        position: fixed;
        top: 0;
        bottom: 0;
        left: 0;
        right: 0;
        margin: auto;
        position: relative;
    }
    <div id="drawRegion">
    
    </div>
    <script src="https://d3js.org/d3.v5.min.js"></script>

    请注意,我还修改了应用阴影的宽度/高度/位置,以避免其被截断:

    var filter = defs.append("filter")
                   .attr("id", "coolShadow")
                   .attr("x", "-100%").attr("y", "-100%")
                   .attr("width", "300%").attr("height", "300%");