javascript - SVG 投影分层

标签 javascript css d3.js svg

我想为我使用 d3 和 SVG 制作的绘图添加阴影,但我遇到了阴影与相邻元素重叠的问题。请参阅下图了解它当前的外观。请注意,中间的六边形似乎具有不同的高度,因为在其中一些六边形的顶部渲染了阴影。我想要做的是以这样一种方式设置阴影,使它们只在背景上呈现,而不是在其他相邻的六边形之上。

这是当前如何定义阴影的代码:

      var filter = defs.append("filter")
        .attr("id", "drop-shadow")
        .attr("height", "130%");

    // SourceAlpha refers to opacity of graphic that this filter will be applied to
    // convolve that with a Gaussian with standard deviation 3 and store result
    // in blur
    filter.append("feGaussianBlur")
        .attr("in", "SourceAlpha")
        .attr("stdDeviation", 1)
        .attr("result", "blur");

    // translate output of Gaussian blur to the right and downwards with 2px
    // store result in offsetBlur
    filter.append("feOffset")
        .attr("in", "blur")
        .attr("dx", 1)
        .attr("dy", 1)
        .attr("result", "offsetBlur");

    // overlay original SourceGraphic over translated blurred opacity by using
    // feMerge filter. Order of specifying inputs is important!
    var feMerge = filter.append("feMerge");

    feMerge.append("feMergeNode")
        .attr("in", "offsetBlur")
    feMerge.append("feMergeNode")
        .attr("in", "SourceGraphic");

然后将这些样式应用于六边形:

d3.select(this).style("filter", "url(#drop-shadow)")

Shadows overlapping hexagaons

最佳答案

您不需要在两层中创建一大堆重复项。您需要做的就是将所有六边形包裹在一个组中 (<g>) 并对其应用过滤器。

<svg>
  <defs>
    <filter id="drop-shadow" width="150%" height="150%">
      <feGaussianBlur in="SourceAlpha" stdDeviation="3" result="blur"/>
      <feOffset in="blur" dx="2" dy="2" result="offsetBlur"/>
      <feMerge>
        <feMergeNode in="offsetBlur"/>
        <feMergeNode in="SourceGraphic"/>
      </feMerge>
    </filter>
  </defs>

  <rect x="75" y="75" width="50" height="50" fill="cyan"
        filter="url(#drop-shadow)"/>
  <rect x="75" y="25" width="50" height="50" fill="gold"
        filter="url(#drop-shadow)"/>
  <rect x="25" y="75" width="50" height="50" fill="lime"
        filter="url(#drop-shadow)"/>
  <rect x="25" y="25" width="50" height="50" fill="red"
        filter="url(#drop-shadow)"/>

  <g filter="url(#drop-shadow)" transform="translate(150,0)">
    <rect x="75" y="75" width="50" height="50" fill="cyan"/>
    <rect x="75" y="25" width="50" height="50" fill="gold"/>
    <rect x="25" y="75" width="50" height="50" fill="lime"/>
    <rect x="25" y="25" width="50" height="50" fill="red"/>
  </g>
</svg>

关于javascript - SVG 投影分层,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45558251/

相关文章:

javascript - 在 Ember 模型的计算属性中使用 Promise

javascript - 正则表达式 |闰年等等

html - 使用 CSS 的圆 Angular 表格

html - 将一个 div 在向右浮动的 div 和向左浮动的 div 之间居中

javascript - 与页面中的多个图表交互

javascript - Vega 中带有调整大小 handle 的时间范围选择器

javascript - 使用 Lodash 将数组转换为嵌套对象,这可能吗?

html - 下划线主题子菜单现在显示在移动设备上

javascript - 由于 d3 事件错误,无法转换 typescript

javascript - 我如何发现触发事件的 DOM 元素并相应地表现