IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    CSS 和 SVG 实现彩色图片阴影

    XboxYan发表于 2024-01-30 11:30:09
    love 0

    在平时开发中,有时候会碰到这样的彩色阴影,效果如下

    image-20240127150305827

    是不是非常有质感?下面分布介绍 CSS 和 SVG 两种实现方式,一起看看吧

    一、实现原理

    从设计上看,其实原理很简单,一张原图和一张模糊的图,叠加在一起就行了,示意如下

    image-20240127151048448

    那么具体如何实现呢?接着往下看

    二、CSS 滤镜

    首先,单纯的 CSS并不能直接做出这种效果,毕竟无法生成一份相同的图片,因此,我们需要手动创建一个相同的图层。

    假设HTML如下

    <div class="wrap">
       <img class="cover" src="https://bookcover.yuewen.com/qdbimg/349573/1036370336/180.webp">
    </div>

    为了节省 dom,我们可以通过伪元素的方式来生成这个图片,关键代码如下

    .wrap{
      position: relative;
      /**/
    }
    .wrap::before{
      content:'';
      position: absolute;
      background: url("https://bookcover.yuewen.com/qdbimg/349573/1036370336/180.webp");
      transform: translate(10px,10px);
    }

    稍微给点偏移,这样得到了两层图片

    image-20240127152242945

    然后给这个伪元素设置模糊滤镜就行了

    .wrap::before{
      /**/
      filter: blur(12px);
    }

    这样就实现了文章开头效果

    image-20240127152434408

    是不是很简单呢?

    不过实际中可以采用 CSS的方式,将需要重复的图片抽离出来

    <div class="wrap" style="--bg: url('https://bookcover.yuewen.com/qdbimg/349573/1036370336/180.webp')">
      <img class="cover" src="https://bookcover.yuewen.com/qdbimg/349573/1036370336/180.webp">
    </div>

    然后CSS就可以保持统一了

    .wrap::before{
      /**/
      background: var(--bg);
    }

    三、SVG滤镜

    有没有发现 上面这种方式需要手动去创建一个一模一样的图层有些多余呢?

    确实是这样,CSS 目前还无法直接复制一个图层

    Firefox 中有个element()方法可以根据dom生成一份完全相同的图层,但是仅仅 Firefox 支持:https://developer.mozilla.org/en-US/docs/Web/CSS/element

    那么,还有其他方式吗?

    当然也是有了,那就是 SVG滤镜!

    和前面的思路其实是一致的,先模糊图层,然后偏移一下,用SVG实现就是

    <svg width="0" height="0">
      <filter id="natural-shadow-filter">
        <feGaussianBlur stdDeviation="12" />
        <feOffset dx="10" dy="10" />
        <feMerge>
          <feMergeNode />
          <feMergeNode in="SourceGraphic" />
        </feMerge>
      </filter>
    </svg>

    似乎有些看不懂?没关系,我们一步步分析。

    首先filter就滤镜的意思,表示整个就是定义了一个滤镜,后面可以给 CSS 直接使用。

    接着,feGaussianBlur就是高斯模糊,stdDeviation表示模糊的范围。

    然后,feOffset表示偏移,dx和dy分别是水平和垂直方向的位移。

    最后是一个feMerge标签,这个表示合并,也就是将多个滤镜组合起来,里面的feMergeNode表示每一步滤镜的结果。这里有两个feMergeNode,第一个就是前面滤镜的最终结果,也就是模糊+偏移后的效果,第二个feMergeNode有一个in参数,表示输入,这里设置的是SourceGraphic,表示原始图像,也就是处理之前的原图。这里的叠加顺序是后来居上,也就是原图放在模糊图之上。

    示意效果如下

    image-20240127155041021

    最后,我们在CSS中直接通过 id 引入的方式实用这个滤镜就行了

    .wrap{
      filter: url("#natural-shadow-filter");
    }

    效果如下,和 CSS基本一致

    image-20240127152434408

    我们还可以多试几种其他图片,下面是 CSS 和 SVG 两种实现的效果对比

    image-20240127155714338

    你可以查看以下链接

    • CSS & SVG color shadow(codepen.io)')

    四、总结一下

    以上就是本文的全部内容了,主要介绍了 CSS 和 SVG 两种不同的实现方式,下面总结一下

    1. 彩色阴影其实原理很简单,一张原图和一张模糊的图,叠加在一起就行了
    2. CSS无法直接创建一个完全相同的图层,需要手动去创建
    3. 手动去创建一个一模一样的图层有些多余,而SVG可以自动生成多份
    4. SVG可以将多个效果通过feMerge进行叠加,顺序是后来居上,SourceGraphic表示原始图像
    5. CSS可以通过url(#id)的方式引入SVG滤镜

    当然,SVG的潜力远不仅如此,在图像处理方面,SVG有着无可比拟的优势,CSS 滤镜可以称之为“残血版”滤镜,很多效果还是需要SVG出马,以后还会介绍更多实用场景。最后,如果觉得还不错,对你有帮助的话,欢迎点赞、收藏、转发 ❤❤❤



沪ICP备19023445号-2号
友情链接