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

如何在SVG遮罩内部添加投影效果?

解决SVG遮罩内侧添加投影的问题

核心结论:无法直接在遮罩(mask)内部实现内侧投影,因为遮罩仅控制元素的可见范围,不参与视觉效果的渲染。但可以通过滤镜组合或分层绘制的方式实现需求,无需手动转换为路径。

方法一:使用SVG滤镜实现内侧投影

通过<filter>组合<feDropShadow>和<feComposite>,先生成朝向内侧的投影,再与原遮罩后的边框叠加:

<svg xmlns="http://www.w3.org/2000/svg" width="640" height="640">
    <defs>
        <!-- 原遮罩 -->
        <mask id="bezelMask">
            <rect width="100%" height="100%" fill="white" />
            <circle cx="50%" cy="50%" r="43.75%" fill="black" />
            <rect width="100%" height="6.25%" y="65%" fill="white" />
            <rect width="100%" height="35%" y="71.25%" fill="black" />
        </mask>

        <!-- 内侧投影滤镜 -->
        <filter id="innerShadow">
            <!-- 生成投影,调整dx/dy控制方向,stdDeviation控制模糊度 -->
            <feDropShadow dx="0" dy="2" stdDeviation="4" flood-color="rgba(0,0,0,0.5)" />
            <!-- 只保留投影中位于原形状内侧的部分 -->
            <feComposite operator="in" in2="SourceGraphic" />
            <!-- 将投影与原图形叠加 -->
            <feMerge>
                <feMergeNode />
                <feMergeNode in="SourceGraphic" />
            </feMerge>
        </filter>
    </defs>
    <g id="circular-face">
        <!-- 应用滤镜和遮罩,注意顺序:先滤镜后遮罩 -->
        <circle id="bezel" r="50%" cx="50%" cy="50%" fill="red" filter="url(#innerShadow)" mask="url(#bezelMask)" />
    </g>
</svg>

原理说明:

  1. <feDropShadow>生成向外的投影,但通过<feComposite operator="in">,只保留投影与原图形重叠的部分(即内侧区域)。
  2. <feMerge>将投影和原边框叠加,实现内侧阴影效果。

方法二:分层绘制边框与投影

直接绘制边框的实际形状(无需遮罩),然后给形状添加内侧投影,这种方式更直观:

<svg xmlns="http://www.w3.org/2000/svg" width="640" height="640">
    <defs>
        <!-- 定义边框的形状为clipPath,方便复用 -->
        <clipPath id="bezelShape">
            <rect width="100%" height="100%" />
            <circle cx="50%" cy="50%" r="43.75%" />
            <rect width="100%" height="35%" y="71.25%" />
        </clipPath>
        <!-- 内侧投影滤镜 -->
        <filter id="innerShadowAlt">
            <feDropShadow dx="0" dy="3" stdDeviation="5" flood-color="rgba(0,0,0,0.6)" />
            <feComposite operator="in" in2="SourceGraphic" />
            <feMerge>
                <feMergeNode />
                <feMergeNode in="SourceGraphic" />
            </feMerge>
        </filter>
    </defs>
    <g id="circular-face">
        <!-- 绘制边框:用大圆形裁剪后得到目标形状 -->
        <g clip-path="url(#bezelShape)">
            <circle r="50%" cx="50%" cy="50%" fill="red" filter="url(#innerShadowAlt)" />
        </g>
        <!-- 绘制底部横条(对应原遮罩中y=65%的矩形) -->
        <rect width="100%" height="6.25%" y="65%" fill="red" filter="url(#innerShadowAlt)" />
    </g>
</svg>

原理说明:

  1. 用<clipPath>定义边框的可见区域,替代原遮罩的逻辑。
  2. 分别绘制圆形边框和底部横条,都应用内侧投影滤镜,实现完整的悬浮效果。

关键注意事项

  • 滤镜的顺序很重要:先应用滤镜,再应用遮罩/裁剪,否则滤镜会被遮罩截断,无法生效。
  • 调整<feDropShadow>的dx/dy和stdDeviation参数,可以控制阴影的方向和模糊程度,适配不同的设计需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 18:44:59