html - SVG光影3D感觉

标签 html svg svg-filters

我想通过在顶部和左侧 BORDER 添加一个小光并在底部和右侧 BORDER 添加一个阴影,使 svg 看起来像 3D 效果。

像这样的

#div1 {
  background: #ddd;
}
#div1, #div2, #div3 {
  width: 100px;
  height: 100px;
  position: relative;
}
#div2 {
  box-shadow: inset -2px -2px 10px 1px #000;
  position: absolute;
}
#div3 {
  box-shadow: inset 2px 2px 14px 1px #fff;
  position: absolute;
}
<div id="div1">
  <div id="div2"></div>
  <div id="div3"></div>
</div>

但我不知道如何使用 svg 过滤器做到这一点

<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="1000">


<defs>
  <filter id="filter1" x="0" y="0">
    <feSpecularLighting result="specOut"
        specularExponent="20" lighting-color="#bbbbbb">
      <fePointLight x="-100" y="-100" z="600"/>
    </feSpecularLighting>
    <feComposite in="SourceGraphic" in2="specOut"
        operator="arithmetic" k1="0" k2="1" k3="1" k4="0"/>
  </filter>
</defs>

<path filter="url(#filter1)" fill="#fff" stroke="#000" d="M20,20 L220,20 L220,220 L20,220 L20,20 "></path>



</svg>

请帮忙,谢谢

最佳答案

首先,您尝试用昏暗的白光照亮一个纯白色矩形。你不会看到任何东西。

如果让矩形变暗,您会开始看到一些效果。

<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="300">

  <defs>
    <filter id="filter1" x="0" y="0">
      <feSpecularLighting result="specOut"
          specularExponent="20" lighting-color="#bbbbbb">
        <fePointLight x="-100" y="-100" z="600"/>
      </feSpecularLighting>
      <feComposite in="SourceGraphic" in2="specOut"
          operator="arithmetic" k1="0" k2="1" k3="1" k4="0"/>
    </filter>
  </defs>

  <path filter="url(#filter1)" fill="#666" stroke="#000" d="M20,20 L220,20 L220,220 L20,220 L20,20 "></path>
</svg>

但在上面的例子中,我们只是在我们的矩形上获得了光的梯度。我们如何在矩形上制作某种斜边?

重要的是要知道,决定照明过滤器组件行为方式的并不是元素的 RGB channel 。照明组件将颜色的alpha 组件 视为bump map。 .不同的 alpha 值成为影响像素点亮方式的拓扑图。

创建不同 alpha 值的一种方法是使用高斯模糊滤镜。这就是它的样子。请注意,我们正在模糊的是形状的 alpha channel (SourceAlpha)。

<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="300">
  <defs>
    <filter id="filter2">
      <feGaussianBlur in="SourceAlpha" stdDeviation="8" result="blur1"/>
      <feBlend in="SourceGraphic" in2="blur1" mode="multiply"/>
    </filter>
  </defs>

  <path filter="url(#filter2)" fill="#666" stroke="#000" d="M20,20 L220,20 L220,220 L20,220 L20,20 "></path>
</svg>

现在,如果使用那个模糊的 alpha channel ,我们会得到接近您所追求的结果。 您可以摆弄模糊、光照过滤器值和 feComposite 值来调整效果。

请注意,我在这里也切换到使用 feDistantLight。我认为它更适合这个目的。

<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="300">
  <defs>
    <filter id="filter2">
      <feGaussianBlur in="SourceAlpha" stdDeviation="8" result="blur1"/>
      <feSpecularLighting result="specOut" in="blur1" specularConstant="1.2" specularExponent="12" lighting-color="#fff">
        <feDistantLight azimuth="225" elevation="45"/>
      </feSpecularLighting>
      <feComposite in="SourceGraphic" in2="specOut" operator="arithmetic" k1="0" k2="1" k3="1" k4="0"/>
    </filter>
  </defs>

  <path filter="url(#filter2)" fill="#666" stroke="#000" d="M20,20 L220,20 L220,220 L20,220 L20,20 "></path>
</svg>

更新

要处理形状重叠的情况(请参阅注释),您需要剪掉形状之外的任何模糊部分。您可以使用另一个 feComposite 操作来做到这一点。

<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="300">
  <defs>
    <filter id="filter2">
      <feGaussianBlur in="SourceAlpha" stdDeviation="8" result="blur1"/>
      <feSpecularLighting result="specOut" in="blur1" specularConstant="1.2" specularExponent="12" lighting-color="#fff">
        <feDistantLight azimuth="225" elevation="45"/>
      </feSpecularLighting>
      <feComposite in="SourceGraphic" in2="specOut" operator="arithmetic" k1="0" k2="1" k3="1" k4="0" result="result"/>
      <feComposite operator="atop" in2="SourceGraphic"/>
    </filter>
  </defs>

  <path filter="url(#filter2)" fill="#666" stroke="#000" d="M20,20 L220,20 L220,220 L20,220 L20,20 "></path>
  <path filter="url(#filter2)" fill="#666" stroke="#000" d="M40,40 L200,40 L200,110 L40,110 L40,40 "></path>
  <path filter="url(#filter2)" fill="#666" stroke="#000" d="M40,120 L200,120 L200,200 L40,200 L40,120 "></path>
</svg>

关于html - SVG光影3D感觉,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60344788/

相关文章:

javascript - 根据html中需要的坐标显示图像

html - 元描述引用转义

javascript - execCommand h1 样式仅选定文本

html - feColorMatrix的每个元素的含义是什么?

svg - 如何应用 SVG 滤镜来创建整个轮廓的彩色 SVG 形式?

jquery - 输入类型文本的任何监听器

javascript - svg.js 缩放和移动/中心的奇怪交互

javascript - 使用 Java 从网站保存 SVG 图像(桌面)

javascript - 将图像转换为可变数量的灰度

layout - 避免在平铺的SVG形状之间形成线条