clip-path是CSS属性之一,只不过很多同学都担心浏览器对他的兼容性,因此不怎么使用该属性。其实clip-path已经得到很好的支持,可以说现在主流浏览器对他的支持已经很好了。

背景

今天逛 CodePen,看到了这样一个非常有意思的效果:

图片

CodePen Demo -- Material Design Menu By Bennett Feely[1]

这个效果还是有一些值得探讨学习的点,下面我们一起来看看。

如何实现这样一个类似的效果?

首先,想一想,如果让你去实现上面的效果,你会怎么做呢?

这里我简单罗列一些可能的办法:

  1. 阴影 box-shadow

  2. 渐变 radial-gradient

  3. 缩放 transform: scale()

快速的一个一个过一下。

使用 box-shadow 实现

如果使用 box-shadow,代码大致如下:

<div class="g-container"> 
    <div class="g-item"></div> 
</div>

    .g-container { 
        position: relative; 
        width: 400px; 
        height: 300px; 
        overflow: hidden; 
    } 
    
    .g-item { 
        position: absolute; 
        width: 48px; 
        height: 48px; 
        border-radius: 50%; 
        background: #fff; 
        top: 20px; 
        left: 20px; 
        box-shadow: 0 0 0 0 #fff; 
        transition: box-shadow .3s linear; 
         
        &:hover { 
            box-shadow: 0 0 0 420px #fff; 
        } 
    }

      核心就在于:

      1. 外层一个设置了 overflow: hideen 的遮罩

      2. 内层元素 hover 的时候,实现一个 box-shadow: 0 0 0 0 #fff 到 box-shadow: 0 0 0 420px #fff 的变化

      效果如下:

      图片

      整体的动画是模拟出来了,但是它最致命的问题有两个:

      1. 当我们的鼠标离开圆形的时候,整个动画就开始反向进行了,白色区域开始消失,如果我们要进行按钮操作,是无法完成的

      2. 隐藏在动画展开后的矩形内的元素,不容易放置

      所以,box-shadow 看着虽好,但是只能放弃。上述 Demo 的代码 -- CodePen Demo -- box-shadow zoom in animation[2]

      使用渐变 radial-gradient 实现

      下面我们使用径向渐变 radial-gradient 加上 CSS @property,也可以还原上述效果:

      <div class="g-container"></div>

        @property --size { 
          syntax: '<length>'; 
          inherits: false; 
          initial-value: 24px; 
        } 
        
        .g-container { 
            position: relative; 
            width: 400px; 
            height: 300px; 
            overflow: hidden; 
            background: radial-gradient(circle at 44px 44px, #fff 0, #fff var(--size), transparent var(--size), transparent 0); 
            transition: --size .3s linear; 
             
            &:hover { 
                --size: 450px; 
            } 
        }

          我们通过控制径向渐变的动画效果,在 hover 的时候,让原本只是一个小圆背景,变成一个大圆背景,效果如下:

          图片

          emmm,效果确实是还原了,问题也很致命:

          1. 由于是背景的变化,所以鼠标不需要 hover 到小圆上,只需要进入 div 的范围,动画就会开始,这显然是不对的

          2. 和第一种 box-shadow 的方法类似,隐藏在白色之下的导航元素的 DOM 不好放置

          上述 Demo 的代码 -- CodePen Demo -- radial-gradient zoom in animation[3]

          emmm,还有一种方法,通过缩放 transform: scale(),也会存一定问题,这里不继续展开。

          所以到这里,想实现上述的效果,核心在于:

          1. 鼠标要 hover 到圆上,才能开始动画,并且,鼠标可以在展开后的范围内自由移动,且不会收回动画效果

          2. 动画展开后,里面的 DOM 的放置,不能太麻烦,能不借助 Javascript 去控制里面内容的显示隐藏最好

          利用 clip-path 实现动态区域裁剪

          所以,这里,我们其实是需要一个动态的区域裁剪。

          在我的这篇文章中 -- 如何不使用 overflow: hidden 实现 overflow: hidden?[4],介绍了 CSS 中几种裁剪元素的方式,而其中,最适合利用在这个效果的,就是 -- clip-path。

          利用 clip-path,可以非常好的实现,动态裁剪的功能,并且,代码也非常简单:

          <div class="g-container"></div>

            .g-container { 
                position: relative; 
                width: 400px; 
                height: 300px; 
                overflow: hidden; 
                transition: clip-path .3s linear; 
                clip-path: circle(20px at 44px 44px); 
                background: #fff; 
                 
                &:hover { 
                    clip-path: circle(460px at 44px 44px); 
                } 
            }

              我们只需要利用 clip-path,在最开始的时候,将一个矩形 div,利用 clip-path: circle(20px at 44px 44px) 裁剪成一个圆,当 hover 的时候,扩大裁剪圆的半径到整个矩形范围即可。

              效果如下:

              这样,我们就能完美的实现题图的效果,并且,内置的 DOM 元素,直接写进这个 div 内部即可。

              <div class="g-container"> 
                  <ul> 
                      <li>11111</li> 
                      <li>22222</li> 
                      <li>33333</li> 
                      <li>44444</li> 
                  </ul> 
              </div>

                效果如下:

                图片

                CodePen Demo -- clip-path zoom in animation[5]

                很有意思的一个技巧,利用 clip-path 实现动态区域裁剪,希望大家能够掌握。

                最后

                好了,本文到此结束,希望本文对你有所帮助 :)


                点赞(0)

                评论列表 共有 0 条评论

                暂无评论
                立即
                投稿
                发表
                评论
                返回
                顶部