【问题标题】:Change a shadow opacity partially in svg using filters and d3.js使用过滤器和 d3.js 在 svg 中部分更改阴影不透明度
【发布时间】:2018-06-04 22:55:48
【问题描述】:

如何使用过滤器和 d3.js 在 svg 中部分更改阴影不透明度?

这是我希望我的影子看起来的样子:

我指的是写有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>

如您所见,阴影几乎已准备就绪。唯一我不知道如何实现 - 是增加的不透明度(现在它太增加了,我想降低它,但同时保留左侧、顶部和右侧边框的透明度)。

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

我将不胜感激任何可以让我解决问题或完全不同的解决方案的更正。

【问题讨论】:

    标签: javascript d3.js svg svg-filters


    【解决方案1】:

    实现您想要做的最好的方法是回拨第二个 feMorphology 上的 y 半径和 feOffset 上的 y。有一些方法可以选择性地降低不透明度,但它们会导致阴影不连续——这可能是你不想要的。

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

    不过,我想知道,您为什么要使用 feMorphology 来扩展源矩形?如果您想要一个带有略微圆角的较大矩形,您可以直接在 SVG 中绘制它——它的性能会更高。 feMorphology 是一项缓慢的操作。

    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】:

      您可以同时使用opacitydy 属性。

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

      dy 属性(dx 也是如此)垂直移动阴影(“移动光源”)。

      如果dy0,则阴影位于形状的中心(光源在形状的正上方)。如果(如您的情况)dy 是正数,则阴影将被平移到底部,因此在阴影形状下方会更加明显。

      这是opacity0.3 的示例:

      .style("opacity", 0.3)
      

      dy0(您可以根据自己的风格调整它):

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

      【讨论】:

        猜你喜欢
        • 2018-02-13
        • 2017-08-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-01-23
        • 2023-03-03
        • 1970-01-01
        • 2019-05-14
        相关资源
        最近更新 更多