加入收藏 | 设为首页 | 会员中心 | 我要投稿 晋中站长网 (https://www.0354zz.com/)- 科技、容器安全、数据加密、云日志、云数据迁移!
当前位置: 首页 > 教程 > 正文

CSS如何完美实现图片渐隐消

发布时间:2023-07-14 11:30:48 所属栏目:教程 来源:互联网
导读:   这篇文章主要介绍了CSS如何实现图片渐隐消的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇CSS如何实现图片渐隐消文章都会有所收获,下面我们一起来看看
  这篇文章主要介绍了CSS如何实现图片渐隐消的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇CSS如何实现图片渐隐消文章都会有所收获,下面我们一起来看看吧。
 
  在过往,我们想要实现一个图片的渐隐消失。最常见的莫过于整体透明度的变化,像是这样:
 
 
  <div class="img"></div>
 
  div {
 
      width: 300px;
 
      height: 300px;
 
      background: url(image.jpg);
 
      transition: .4s;
 
  }
 
  .img:hover {
 
      opacity: 0;
 
  }
 
  但是,CSS 的功能如此强大的今天。我们可以利用 CSS 实现的渐隐效果已经不再是如此的简单。
 
  想想看,下面这样一个效果,是 CSS 能够实现的么?
 
  答案是肯定的!本文就将一步一步,从零开始,仅仅使用一个标签,实现上述的图片渐隐效果。
 
  这里,有两个核心的点:
 
  如何将一张图片切割的这么细,切割成这么多块?
 
  基于上述 (1)的基础上,又该如何分别控制这些小块的独立隐藏和展示呢?
 
  莫慌,让我们一步一步来解决他们。
 
  强大的 Mask
 
  首先,我们需要用到 Mask。
 
  在 CSS 中,mask 属性允许使用者通过遮罩或者裁切特定区域的图片的方式来隐藏一个元素的部分或者全部可见区域。
 
  语法
 
  最基本,使用 mask 的方式是借助图片,类似这样:
 
 
  div {
 
      width: 300px;
 
      height: 300px;
 
      background: url(image.jpg);
 
      transition: .4s;
 
  }
 
  .img:hover {
 
      opacity: 0;
 
  }
 
  当然,使用图片的方式后文会再讲。借助图片的方式其实比较繁琐,因为我们首先还得准备相应的图片素材,除了图片,mask 还可以接受一个类似 background 的参数,也就是渐变。
 
  类似如下使用方法:
 
 
  {
 
      mask: linear-gradient(#000, transparent)                      /* 使用渐变来做遮罩 */
 
  }
 
  那该具体怎么使用呢?一个非常简单的例子,上述我们创造了一个从黑色到透明渐变色,我们将它运用到实际中,代码类似这样:
 
  下面这样一张图片,叠加上一个从透明到黑色的渐变,
 
 
  {
 
      background: url(image.png) ;
 
      mask: linear-gradient(90deg, transparent, #fff);
 
  }
 
  这个 DEMO,可以先简单了解到 mask 的基本用法。
 
  这里得到了使用 mask 最重要结论:图片与 mask 生成的渐变的 transparent 的重叠部分,将会变得透明。
 
  值得注意的是,上面的渐变使用的是 linear-gradient(90deg, transparent, #fff),这里的 #fff 纯色部分其实换成任意颜色都可以,不影响效果。
 
  CodePen Demo -- 使用 MASK 的基本使用
 
  使用 mask 实现 hover 隐藏图片
 
  了解了 mask 的简单用法后,我们来看这样一个非常简单的例子,我们改造下上述的第一个 DEMO。
 
 
  <div class="img"></div>
 
  div {
 
      width: 300px;
 
      height: 300px;
 
      background: url(image.jpg);
 
  }
 
  .img:hover {
 
      mask: linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 0));
 
  }
 
  强大的 CSS @property
 
  CSS @property,大家应该不那么陌生了。
 
  @property CSS at-rule 是 CSS Houdini API 的一部分, 它允许开发者显式地定义他们的 CSS 自定义属性,允许进行属性类型检查、设定默认值以及定义该自定义属性是否可以被继承。
 
  回到我们的正题,如果我们想给上述使用 Mask 的代码,添加上动画,我们期望代码大概是这样:
 
 
  div {
 
      width: 300px;
 
      height: 300px;
 
      background: url(image.jpg);
 
      mask: linear-gradient(rgba(0, 0, 0, 1), rgba(0, 0, 0, 1));
 
  }
 
  .img:hover {
 
      mask: linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 0));
 
  }
 
  这里,mask 的是从 mask: linear-gradient(rgba(0, 0, 0, 1), rgba(0, 0, 0, 1)) 向 mask: linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 0)) 变化的。
 
  但是实际上,这样并不会产生任何的动画效果。
 
  原因在于,我们 Mask 属性本身是不支持过渡动画的!
 
  但是,利用上 CSS @property,整个效果就不一样了。借助,CSS @property,我们改造一下代码:
 
 
  @property --m-0 {
 
     syntax: "<number>";
 
     initial-value: 1;
 
     inherits: false;
 
  }
 
  div {
 
      width: 300px;
 
      height: 300px;
 
      background: url(image.jpg);
 
      mask: linear-gradient(90deg, rgba(0, 0, 0, var(--m-0)), rgba(0, 0, 0, var(--m-0)));
 
      transition: --m-0 0.5s;
 
  }
 
  div:hover {
 
      --m-0: 0;
 
  }
 
  我们利用 CSS @property 定义了一个名为 --m-0 的变量,然后,我们将整个动画过渡效果赋予了这个变量,而不是整个 mask。
 
  借助多重 mask 分割图片
 
  到了这一步,后面的步骤其实就很明朗了。
 
  由于 mask 拥有和 background 一样的特性。因此,mask 是可以有多重 mask 的。也就是说,我们可以设置多个不同的 mask 效果给同一个元素。
 
  什么意思呢?上面的效果只有一重 mask,我们稍微添加一些 mask 代码,让它变成 2 重 mask:
 
 
  @property --m-0 {
 
     syntax: "<number>";
 
     initial-value: 1;
 
     inherits: false;
 
  }
 
  @property --m-1 {
 
     syntax: "<number>";
 
     initial-value: 1;
 
     inherits: false;
 
  }
 
  div {
 
      mask:
 
          linear-gradient(90deg, rgba(0, 0, 0, var(--m-0)), rgba(0, 0, 0, var(--m-0))),
 
          linear-gradient(90deg, rgba(0, 0, 0, var(--m-1)), rgba(0, 0, 0, var(--m-1)));
 
      mask-size: 50% 100%;
 
      mask-position: left, right;
 
      mask-repeat: no-repeat;
 
      transition:
 
          --m-0 0.3s,
 
          --m-1 0.25s 0.15s;
 
  }
 
  div:hover {
 
      --m-0: 0;
 
      --m-1: 0;
 
  }
 
  这样,我们的步骤大概是:
 
  首先将 mask 一分为二,左右两边各一个
 
  然后,设置了两个基于 CSS @property 的变量,--m-0 和 --m-0
 
  然后,给它们设置了不同的过渡时间和过渡延迟时间
 
  在 hover 的一瞬间,再将这两个变量的值,都置为 0,也就是实现 linear-gradient(90deg, rgba(0, 0, 0, 1), rgba(0, 0, 0, 1)) 到 linear-gradient(90deg, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0)) 的变化,用于隐藏对应 mask 块
 
  由于设置了不同的过渡时间和延迟时间,整体上看上去,整个动画就分成了两部分
 
  看看效果:
 
  继续切割为 4 重 mask
 
  好,既然 2 重 mask 效果没问题,那么我们可以再进一步,将整个效果切割为 4 个 mask。代码还是如法炮制,这里我再贴上核心代码:
 
 
  @property --m-0 {
 
     syntax: "<number>";
 
     initial-value: 1;
 
     inherits: false;
 
  }
 
  @property --m-1 {
 
     syntax: "<number>";
 
     initial-value: 1;
 
     inherits: false;
 
  }
 
  @property --m-2 {
 
     syntax: "<number>";
 
     initial-value: 1;
 
     inherits: false;
 
  }
 
  @property --m-3 {
 
     syntax: "<number>";
 
     initial-value: 1;
 
     inherits: false;
 
  }
 
  div {
 
      mask:
 
          linear-gradient(90deg, rgba(0, 0, 0, var(--m-0)), rgba(0, 0, 0, var(--m-0))),
 
          linear-gradient(90deg, rgba(0, 0, 0, var(--m-1)), rgba(0, 0, 0, var(--m-1))),
 
          linear-gradient(90deg, rgba(0, 0, 0, var(--m-2)), rgba(0, 0, 0, var(--m-2))),
 
          linear-gradient(90deg, rgba(0, 0, 0, var(--m-3)), rgba(0, 0, 0, var(--m-3)));
 
      mask-size: 50% 50%;
 
      mask-repeat: no-repeat;
 
      mask-position: left top, right top, left bottom, bottom right;
 
      transition:
 
          --m-0 0.3s,
 
          --m-1 0.15s 0.1s,
 
          --m-2 0.25s 0.21s,
 
          --m-3 0.19s 0.15s;
 
  }
 
  div:hover {
 
      --m-0: 0;
 
      --m-1: 0;
 
      --m-2: 0;
 
      --m-3: 0;
 
  }
 
  基于 SCSS 简化代码
 
  那么,如果我们要分割为 100 块呢?或者 400 块呢?还要手写这些代码吗?
 
  当然不需要,由于上面的代码的规律非常的明显,我们可以借助预处理器很好的封装整个效果。从而快速的实现切割成任意规则块数的效果。
 
  完整的代码如下:
 
 
  $count: 400;
 
  $sqrt: 20;
 
  $per: 100% / $sqrt;
 
  $width: 300px;
 
  $perWid: 15;
 
  @for $i from 1 to ($count + 1) {
 
      @property --m-#{$i} {
 
         syntax: "<number>";
 
         initial-value: 1;
 
         inherits: false;
 
      }
 
  }
 
  @function bgSet($n) {
 
      $bg : radial-gradient(rgba(0, 0, 0, var(--m-1)), rgba(0, 0, 0, var(--m-1)));
 
      
 
      @for $i from 2 through $n {         
 
          $bg: $bg, radial-gradient(rgba(0, 0, 0, var(--m-#{$i})), rgba(0, 0, 0, var(--m-#{$i})));
 
      }
 
      
 
      @return $bg;
 
  }
 
  @function positionSet($n) {
 
      $bgPosition: ();
 
      @for $i from 0 through ($n) {   
 
          @for $j from 0 through ($n - 1) {  
 
              $bgPosition: $bgPosition, #{$i * $perWid}px #{$j * $perWid}px;
 
          }
 
      }
 
      
 
      @return $bgPosition;
 
  }
 
  @function transitionSet($n) {
 
      $transition: --m-1 0.1s 0.1s;
 
      @for $i from 1 through $n {   
 
          $transition: $transition, --m-#{$i} #{random(500)}ms #{random(500)}ms;
 
      }
 
      
 
      @return $transition;
 
  }
 
  div {
 
      width: $width;
 
      height: $width;
 
      background: url(image.jpg);
 
      mask: bgSet($count);
 
      mask-size: $per $per;
 
      mask-repeat: no-repeat;
 
      mask-position: positionSet($sqrt);
 
      transition: transitionSet($count);
 
  }
 
  div:hover {
 
      @for $i from 1 through $count {         
 
          --m-#{$i}: 0;
 
      }
 
  }
 
  这里,简单解释一下,以生成 400 块小块为例子:
 
  最上面的 SCSS 变量定义中,
 
  $count 是我们最终生成的块数
 
  $sqrt 是每行以及每列会拥有的块数
 
  $per 是每一块占整体图片元素的百分比值
 
  $width 是整个图片的宽高值
 
  $perWid 是每一块的宽高值
 
  利用了最上面的一段循环函数,批量的生成 CSS @property 变量,从 --m-0 到 --m-400
 
  @function bgSet($n) {} 是生成 400 块 mask 片段
 
  @function positionSet($n) 是生成 400 块 mask 的 mask-position,也就是生成 400 段不同定位,让 400 块 mask 刚好覆盖整个图片
 
  @function transitionSet($n) {} 是随机设置每个块的动画时间和延迟时间
 
  代码最下面,还有一段循环函数,生成 400 个 CSS @property 变量的 hover 值,当 hover 的时候,全部变成 0
 
  这样,我们就实现了 400 分块的渐隐效果。
 
  调整过渡变量,控制方向
 
  当然,上面我们的对每一个小块的 transition 的过渡时间和过渡延迟时间的设置,都是随机的:
 
 
  @function transitionSet($n) {
 
      $transition: --m-1 0.1s 0.1s;
 
      @for $i from 1 through $n {   
 
          $transition: $transition, --m-#{$i} #{random(500)}ms #{random(500)}ms;
 
      }
 
      
 
      @return $transition;
 
  }
 
  我们完全可以通过一定的控制,让过渡效果不那么随机,譬如有一定的方向感。
 
  下面,我们通过让动画的延迟时间与 $i,也就是 mask 小块的 index 挂钩:
 
 
  @function transitionSet($n) {
 
      $transition: --m-1 0.1s 0.1s;
 
      @for $i from 1 through $n {   
 
          $transition: $transition, --m-#{$i} #{100 + random(500)}ms #{($i / 50) * random(100)}ms;
 
      }
 
      
 
      @return $transition;
 
  }
 
  那么,整个动画的方向就是从左往右逐渐消失:
 
  当然,有意思的是,这个效果,不仅仅能够运用在图片上,它其实可以作用在任何元素之上!
 

(编辑:晋中站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章