You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为SVG中矩形及叠放在其上方的圆形分别添加投影效果

问题场景
  • 现有一个矩形,其左侧叠放一个圆形,两个图形填充均为白色。
  • 目标效果:为矩形添加适配的投影,同时为叠放在矩形左上方的圆形添加对应投影,实现符合层级逻辑的视觉效果。
  • 当前进度:已编写两套分别匹配矩形、圆形投影参数的SVG滤镜,两个元素上的滤镜调用代码目前处于注释状态,未生效。

初始实现代码如下:

let svg = d3.select("#container")
    .append("svg");

    svg.select("defs")
    .append("svg:filter")
    .attr("id", "nodeShadow")
    .append("feDropShadow")
    .attr("dx", 0.5)
    .attr("dy", 3.2)
    .attr("stdDeviation", 3)
    .attr("flood-opacity", 0.3)
    .attr("flood-color", "lightgray");
    
     svg.select("defs")
    .append("svg:filter")
    .attr("id", "circleShadow")
    .append("feDropShadow")
    .attr("dx", 2.0)
    .attr("dy", 1.6)
    .attr("stdDeviation", 4)
    .attr("flood-color", "lightgray");
    
// node
let containerNode = svg.append("g");

containerNode.append("rect")
    .attr("x", 100)
    .attr("y", 150)
    //.attr("filter", "url(#nodeShadow)")
    .attr("fill", "#FFFFFF")
    .attr("width", 250)
    .attr("height", 30);

containerNode.append("circle")
    .attr("cx", 115)
    .attr("cy", 165)
    .attr("r", 15)
    .attr("fill", "transparent")
    //.attr("filter", "url(#circleShadow)")
    .attr("stroke", "#ffffff")
    .attr("stroke-width", "0.001")
    .attr("width", 30)
    .attr("height", 30);
解决方案

按以下三点调整即可实现正确的分层投影:

  • 修正圆形填充属性:将圆形的fill值从transparent改为#FFFFFF,和矩形填充保持一致。透明填充的元素应用投影时,仅宽度0.001的描边会生成投影,视觉上几乎不可见,无法达到预期效果。
  • 扩大滤镜渲染区域:给两个滤镜节点添加x/y/width/height属性,预留足够的投影绘制空间,避免投影边缘被滤镜默认边界裁切。
  • 按层级应用滤镜:SVG遵循「后绘制元素层级更高」的规则,保持现有先画矩形、后画圆形的顺序,直接取消两个元素上的滤镜注释即可。最终效果为矩形投影落在页面背景上,圆形投影自然落在下层的矩形表面,完全符合真实叠放的视觉逻辑。
修正后核心代码
let svg = d3.select("#container")
    .append("svg");

// 配置矩形滤镜,预留投影空间避免裁切
svg.select("defs")
.append("svg:filter")
.attr("id", "nodeShadow")
.attr("x", "-20%")
.attr("y", "-20%")
.attr("width", "140%")
.attr("height", "140%")
.append("feDropShadow")
.attr("dx", 0.5)
.attr("dy", 3.2)
.attr("stdDeviation", 3)
.attr("flood-opacity", 0.3)
.attr("flood-color", "lightgray");

// 配置圆形滤镜,预留投影空间避免裁切
svg.select("defs")
.append("svg:filter")
.attr("id", "circleShadow")
.attr("x", "-50%")
.attr("y", "-50%")
.attr("width", "200%")
.attr("height", "200%")
.append("feDropShadow")
.attr("dx", 2.0)
.attr("dy", 1.6)
.attr("stdDeviation", 4)
.attr("flood-opacity", 0.3)
.attr("flood-color", "lightgray");

// 绘制节点组
let containerNode = svg.append("g");

// 绘制矩形,应用矩形投影
containerNode.append("rect")
    .attr("x", 100)
    .attr("y", 150)
    .attr("filter", "url(#nodeShadow)")
    .attr("fill", "#FFFFFF")
    .attr("width", 250)
    .attr("height", 30);

// 绘制圆形,应用圆形投影
containerNode.append("circle")
    .attr("cx", 115)
    .attr("cy", 165)
    .attr("r", 15)
    .attr("fill", "#FFFFFF")
    .attr("filter", "url(#circleShadow)")
    .attr("stroke", "#ffffff")
    .attr("stroke-width", "0.001");

内容的提问来源于stack exchange,提问作者Ace

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.17 16:16:01