纯css实现水波流动效果

4,529 阅读5分钟

我正在参加「创意开发 投稿大赛」详情请看:掘金创意开发大赛来了!

前言

大家好,我是小阵 🔥,一路奔波不停的码字业务员
如果喜欢我的文章,可以关注 ➕ 点赞,与我一同成长吧~😋
加我微信:zzz886885,邀你进群,一起学习交流,摸鱼学习两不误🌟

开开心心学技术大法~~

开心

来了来了,他真的来了~

正文

先看效果

iShot_2022-08-02_21.37.38

实现思路

  • 先实现一个装水的容器,可以通过box-shadow给容器增添点厚度的感觉

  • 水的实现,其实就是一个纯色的背景

  • 接下来就是波纹的实现

  • 思考下现有的css属性可以有这样的效果吗?

  • 答案是否定的,那我们怎样通过dom+css来实现这样的效果呢?

  • 我们可以看到波纹的行动轨迹是有规律的,再仔细观察后会发现其实每四个小周期是一个循环,每四个小周期之后的动画都是固定的

    • 那其实可以通过赛贝尔曲线+animation来实现
    • 当然,这就比较复杂了,赛贝尔曲线+animation的方案其实是可以实现任意n个小周期为一个循环的
  • 那还能通过怎样的方式来实现这样的运动轨迹呢?

    • 先观察圆形容器中的浅粉色部分,会发现其实他就是一个带有border-radius的正方形在旋转,或者是一个长于宽相差不大的矩形

      • 也就是通过border-raduis+animation即可
    • 再观察浅粉色和深蓝色中间的浅蓝色部分的移动轨迹,已经有了一次推测的大家应该也可以很快发现,其实这也是一个带有border-radius的正方形或长宽相差不大的矩形,只不过这个的border-radius更大而已

    • 因为更大,所以看上去转动时波动就没那么明显

    • 然后水dom在最下面,浅蓝色dom在中间,浅粉色dom在最上面,这样颜色互相覆盖之下,就能形成类似的视觉效果

  • 上面提到转动的是正方形或长于宽相差不大的矩形,这是为什么呢?

    • 因为假设一下,长宽相差比较明显,这时一个矩形的转动还是挺有规律的,但是如果是两个矩形转动呢?
    • 我们要的是有波纹效果,也就是其中一个矩形在转动时永远比另一个矩形转动时稍大,这样才会相差一部分看着像波纹
  • 还有一个没那么重要但是也需要注意的点

    • 我们可以看到,认真观察的话,其实他们旋转都不是正对圆心的,也就是要更偏一点的,这个是为了让两个带圆角的正方形旋转时不要总是间隔一致,要有错落有致的感觉

      • 所以也需要设置translate
      • 又因为做旋转动画时需要用到transform:rotate(0deg)transform:rotate(360deg)的旋转
      • 所以是transform: translate(-50%, -60%) rotate(0deg)transform: translate(-50%, -60%) rotate(360deg)
      • 当然,两个水波dom的translate属性可以适当偏差一点,但是不宜偏差过大,因为过大之后还是会出现上面说过的长宽相距太大时会出现的问题

看到这里,如果之前实现过类似效果的同学可能已经明白了。

如果还是稍微有点晕乎的同学可以直接去看我下面贴的完整代码来反过来分析

下面来说具体实现

具体实现

基础html

<div class="quan">
  <div class="shui"></div>
</div>

我们只关注背景和容器,因为.shui可以设置两个伪元素,所以就用伪元素来代替两个水波

背景颜色

body {
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: rgb(240, 228, 228);
}

背景最好要是浅色的,这样看起来跟水与水波的对比才会更清晰

容器颜色

.quan {
  position: relative;
  width: 180px;
  height: 180px;
  border-radius: 50%;
  border: 3px solid rgb(246, 247, 248);
  box-shadow: 0 0 0 3px rgb(41, 134, 196);
}

因为后续要基于该容器定位,所以是relative

水样式

.shui {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgb(23, 106, 201);
  border-radius: 50%;
  overflow: hidden;
}

水既是深蓝色背景,也要起到容器的作用,添加overflow:hidden来保证实现水波的两个dom不会超出,当然,这个样式写在容器上也可以

两个水波样式

.shui::after {
  content: '';
  position: absolute;
  top: 0;
  left: 50%;
  width: 150%;
  height: 150%;
  border-radius: 40%;
  background-color: rgb(240, 228, 228);
  animation: shi 5s linear infinite;
}
​
@keyframes shi {
  0% {
    transform: translate(-50%, -65%) rotate(0deg);
  }
​
  100% {
    transform: translate(-50%, -65%) rotate(360deg);
  }
}
​
.shui::before {
  content: '';
  position: absolute;
  top: 0;
  left: 50%;
  width: 150%;
  height: 150%;
  border-radius: 42%;
  background-color: rgb(240, 228, 228, 0.2);
  animation: xu 7s linear infinite;
}
​
@keyframes xu {
  0% {
    transform: translate(-50%, -60%) rotate(0deg);
  }
​
  100% {
    transform: translate(-50%, -60%) rotate(360deg);
  }
}

可以看到两个水波domtranslateborder-radius都有少许的不同,这个可以根据实现视觉效果微调

完整代码

总结

  • 重点是两个水波dom的动画相互配合
  • 当然还可以有更多水波dom,这完全取决于你自己

结语

如果文章真的有帮到你,希望可以多多点赞、收藏、关注支持一波呀!!小阵会很开心哒~

学习自老哥北极光之夜,感兴趣的可以去了解下。

文章如有错误或不严谨之处,还望指出,感谢感谢!!!

加油!

往期好文推荐「我不推荐下,大家可能就错过了史上最牛逼vscode插件集合啦!!!(嘎嘎~)😄」