css js实现海浪、波浪效果详解

广告位招租
扫码页面底部二维码联系

【版权所有,侵权必究】【访问 www.tangshuang.net 获取更多精彩内容】未经授权,禁止复制转载。

想在博客首页加一个波浪效果,谷歌了半天没本文作者:唐霜,转载请注明出处。未经授权,禁止复制转载。有找到合适的代码,于是决定自己写一个。网【访问 www.tangshuang.net 获取更多精彩内容】【原创不易,请尊重版权】上有一个使用canvas实现的,但是我觉著作权归作者所有,禁止商业用途转载。【本文首发于唐霜的博客】得既然css已经可以支持动画效果了,有没未经授权,禁止复制转载。【访问 www.tangshuang.net 获取更多精彩内容】有使用css实现的动画效果来实现我想要的著作权归作者所有,禁止商业用途转载。本文版权归作者所有,未经授权不得转载。海浪的效果呢?于是开始琢磨。

著作权归作者所有,禁止商业用途转载。【关注微信公众号:wwwtangshuangnet】【本文受版权保护】【原创内容,转载请注明出处】

首先想到的,是如何制作波浪的外观,即波状著作权归作者所有,禁止商业用途转载。本文作者:唐霜,转载请注明出处。曲线。刚开始陷入误区,觉得一定要画出线来转载请注明出处:www.tangshuang.net著作权归作者所有,禁止商业用途转载。,后来逐渐觉得,可以换个思路。波的产生是【关注微信公众号:wwwtangshuangnet】【本文首发于唐霜的博客】什么原理?是能量的传播。能量在波中传播的【关注微信公众号:wwwtangshuangnet】【本文受版权保护】时候,不是靠物质的移动,对于水而言,其实【作者:唐霜】【本文首发于唐霜的博客】是一直在原地上下波动,并没有像视觉上看到【作者:唐霜】【原创不易,请尊重版权】的在前进。既然自然原理是这样的,那么我们【访问 www.tangshuang.net 获取更多精彩内容】本文版权归作者所有,未经授权不得转载。在实现效果的时候,也可以遵循这一原理。

【本文受版权保护】转载请注明出处:www.tangshuang.net未经授权,禁止复制转载。【本文首发于唐霜的博客】

首先,我们看到的是一片宁静的海面:本文作者:唐霜,转载请注明出处。

【原创内容,转载请注明出处】【未经授权禁止转载】【转载请注明来源】

本文版权归作者所有,未经授权不得转载。【版权所有】唐霜 www.tangshuang.net【版权所有,侵权必究】【本文受版权保护】本文版权归作者所有,未经授权不得转载。

当海底某处发生地震时,这个海域的海水被地【本文受版权保护】【版权所有】唐霜 www.tangshuang.net震波的能量顶出海面。我们姑且将这个水域看著作权归作者所有,禁止商业用途转载。【访问 www.tangshuang.net 获取更多精彩内容】作一个整体,海水将高出海平面很多:

本文版权归作者所有,未经授权不得转载。著作权归作者所有,禁止商业用途转载。【本文首发于唐霜的博客】【原创内容,转载请注明出处】本文版权归作者所有,未经授权不得转载。

未经授权,禁止复制转载。转载请注明出处:www.tangshuang.net著作权归作者所有,禁止商业用途转载。

而隔壁的海域由于受到影响,也发生了同样的本文作者:唐霜,转载请注明出处。著作权归作者所有,禁止商业用途转载。情况,但是由于时间稍晚,当中心海域浪最高【访问 www.tangshuang.net 获取更多精彩内容】【本文受版权保护】的时刻,没那么高:

【关注微信公众号:wwwtangshuangnet】【关注微信公众号:wwwtangshuangnet】【作者:唐霜】转载请注明出处:www.tangshuang.net【版权所有】唐霜 www.tangshuang.net

【关注微信公众号:wwwtangshuangnet】【关注微信公众号:wwwtangshuangnet】【原创内容,转载请注明出处】【版权所有】唐霜 www.tangshuang.net【本文受版权保护】

由此内推下去,再远一些的海域再晚一些。如未经授权,禁止复制转载。【版权所有】唐霜 www.tangshuang.net此下去,能量将会传播整个海域,如果不考虑【原创内容,转载请注明出处】【本文受版权保护】能量传播中的损耗,所有的浪高度都会是一样【本文首发于唐霜的博客】【版权所有】唐霜 www.tangshuang.net的。

【本文首发于唐霜的博客】著作权归作者所有,禁止商业用途转载。【版权所有】唐霜 www.tangshuang.net转载请注明出处:www.tangshuang.net

【访问 www.tangshuang.net 获取更多精彩内容】【访问 www.tangshuang.net 获取更多精彩内容】【原创不易,请尊重版权】【原创不易,请尊重版权】

上面是第一阶段,即当海底发生震动,将能量【未经授权禁止转载】【转载请注明来源】释放出来的时刻。当海水达到最高点时,会往【未经授权禁止转载】本文作者:唐霜,转载请注明出处。下降。

【本文受版权保护】【作者:唐霜】【原创不易,请尊重版权】【本文受版权保护】

【版权所有,侵权必究】原创内容,盗版必究。未经授权,禁止复制转载。

著作权归作者所有,禁止商业用途转载。【未经授权禁止转载】【版权所有,侵权必究】【原创内容,转载请注明出处】著作权归作者所有,禁止商业用途转载。

原创内容,盗版必究。未经授权,禁止复制转载。转载请注明出处:www.tangshuang.net

如上所示,整个浪将会传向更远的海域。波浪【版权所有】唐霜 www.tangshuang.net本文版权归作者所有,未经授权不得转载。就是这样形成的。连续不断的波浪是由于海底【原创内容,转载请注明出处】转载请注明出处:www.tangshuang.net地震连续不断的顶起海水,形成的。所以,最【本文受版权保护】【本文首发于唐霜的博客】终实际上整个波浪效果,是由单个柱体的循环著作权归作者所有,禁止商业用途转载。【访问 www.tangshuang.net 获取更多精彩内容】上下运动,以及不同柱体运动上的时间差形成【转载请注明来源】著作权归作者所有,禁止商业用途转载。的一个效果。

本文版权归作者所有,未经授权不得转载。【原创内容,转载请注明出处】【访问 www.tangshuang.net 获取更多精彩内容】本文版权归作者所有,未经授权不得转载。

根据这个原理,把柱体的宽度缩小,小到消除【版权所有,侵权必究】【作者:唐霜】柱体之间的高度差,那样就看上去是一条连续本文作者:唐霜,转载请注明出处。著作权归作者所有,禁止商业用途转载。运动的线形成的波浪效果。

原创内容,盗版必究。著作权归作者所有,禁止商业用途转载。本文作者:唐霜,转载请注明出处。本文作者:唐霜,转载请注明出处。

根据这个思路,用css和js来实现他们。

【版权所有,侵权必究】未经授权,禁止复制转载。【原创不易,请尊重版权】【原创不易,请尊重版权】

首先,我们需要一个海洋:【未经授权禁止转载】

原创内容,盗版必究。【版权所有】唐霜 www.tangshuang.net【未经授权禁止转载】【作者:唐霜】著作权归作者所有,禁止商业用途转载。
<div class="ocean" id="ocean1"></div>

其次,我们需要海洋中的柱体:【本文受版权保护】

原创内容,盗版必究。【原创不易,请尊重版权】未经授权,禁止复制转载。本文版权归作者所有,未经授权不得转载。
<script>
function addWaves(id, width) {
  var ocean = document.getElementById(id)
  var count = Math.floor(ocean.clientWidth/width)
  var docFrag = document.createDocumentFragment()
  for(let i = 0; i < count; i ++) {
    let wave = document.createElement("div")
    wave.className = "wave"
    wave.style.width = width + "px"
    wave.style.left = width * i + "px"
    docFrag.appendChild(wave)
  }
  ocean.appendChild(docFrag)
}
addWaves("ocean1", 5) // 规定每个柱体宽度为5像素
</script>
<style>
.ocean {
  position: relative;
}
.ocean .wave {
  position: absolute;
  bottom: 0;
  height: 100%;
}
/* 上面是基础的css,下面可以根据你当前的需要调整样式 */
#ocean1 {
  width: 600px;
  height: 150px;
  margin-top: 100px;
}
#ocean1 .wave {
  background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, rgb(0,50,150)), color-stop(1, rgb(0,150,255)));
}
</style>

这样,一个平静的海域就构建好了。【关注微信公众号:wwwtangshuangnet】

著作权归作者所有,禁止商业用途转载。【原创内容,转载请注明出处】转载请注明出处:www.tangshuang.net著作权归作者所有,禁止商业用途转载。

接下来就是构建动态的效果。利用css3的本文作者:唐霜,转载请注明出处。【关注微信公众号:wwwtangshuangnet】keyframes来实现一个循环的动画帧【本文首发于唐霜的博客】【未经授权禁止转载】,使海水动起来。新增如下样式:

著作权归作者所有,禁止商业用途转载。本文作者:唐霜,转载请注明出处。本文版权归作者所有,未经授权不得转载。【访问 www.tangshuang.net 获取更多精彩内容】【关注微信公众号:wwwtangshuangnet】
@-webkit-keyframes wave {
  0% {  height: 100%;  }
  50% {  height: 120%;  }
  100%{   height: 100%;  }
}
.ocean .wave {
  animation: wave 2s infinite ease-in-out;
}

添加这段css之后,你发现,整个海平面都【原创内容,转载请注明出处】【未经授权禁止转载】在一起上下运动……所以,我们要继续处理延【转载请注明来源】原创内容,盗版必究。时的问题。延时的话在css里面有一个an未经授权,禁止复制转载。【未经授权禁止转载】imation-delay属性。但是我们【本文受版权保护】未经授权,禁止复制转载。必须要让每一个wave的delay大于前本文版权归作者所有,未经授权不得转载。原创内容,盗版必究。一个,所以只能在js里面动态添加这个属性【版权所有,侵权必究】【版权所有,侵权必究】,在上面的js里面,给每个wave设置s【访问 www.tangshuang.net 获取更多精彩内容】【未经授权禁止转载】tyle的地方再增加一条:

【版权所有】唐霜 www.tangshuang.net【关注微信公众号:wwwtangshuangnet】【访问 www.tangshuang.net 获取更多精彩内容】
wave.style.width = width + "px"wave.style.left = width * i + "px"
wave.style.animationDelay = (i/100) + "s"

增加了一个animationDelay,本文版权归作者所有,未经授权不得转载。本文作者:唐霜,转载请注明出处。这样就可以让每一个wave的动画延时执行【访问 www.tangshuang.net 获取更多精彩内容】本文作者:唐霜,转载请注明出处。,i/100是说把时间间隔缩小到以1/1本文版权归作者所有,未经授权不得转载。【未经授权禁止转载】00s为单位。

【本文首发于唐霜的博客】【访问 www.tangshuang.net 获取更多精彩内容】【本文首发于唐霜的博客】未经授权,禁止复制转载。

这样,怎个波浪就动起来了,实现了我们想要未经授权,禁止复制转载。转载请注明出处:www.tangshuang.net的效果。不过这个效果里面有一点不是很好,【未经授权禁止转载】【访问 www.tangshuang.net 获取更多精彩内容】就是如果5px作为一个柱体的宽度的话,会【转载请注明来源】【本文受版权保护】有明显的锯齿效果,想要消除锯齿,最好是让【本文受版权保护】【版权所有】唐霜 www.tangshuang.net柱体的宽度等于1px,并且让柱体之间的延未经授权,禁止复制转载。【原创不易,请尊重版权】时变小,也就是说两个柱体之间的连续性更好【访问 www.tangshuang.net 获取更多精彩内容】【访问 www.tangshuang.net 获取更多精彩内容】,这样锯齿就相对没有那么明显。但由于延时原创内容,盗版必究。【版权所有,侵权必究】变小,波浪的速度就会变快,波长也就会变小【作者:唐霜】【原创不易,请尊重版权】。总之最终代码如下:

【作者:唐霜】本文版权归作者所有,未经授权不得转载。【未经授权禁止转载】本文版权归作者所有,未经授权不得转载。
<!doctype html>
<head>
<meta charset="utf-8">
<title>ocean</title>
<style>
@-webkit-keyframes wave {
  0% {  height: 100%;  }
  50% {  height: 120%;  }
  100%{   height: 100%;  }
}
.ocean {
  position: relative;
}
.ocean .wave {
  position: absolute;
  bottom: 0;
  height: 100%;
  animation: wave 2s infinite ease-in-out;
}
.ocean {
  width: 600px;
  height: 150px;
  margin-top: 100px;
}
.ocean .wave {
  background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, rgb(0,50,150)), color-stop(1, rgb(0,150,255)));
}
</style>
</head>

<body>
<div class="ocean" id="ocean1"></div>
<br>
<div class="ocean" id="ocean2"></div>
<br>
<div class="ocean" id="ocean3"></div>
<script>
/**
 * id: 要获取的div元素的id属性
 * width: 每一个wave柱体的宽度,单位px
 * duration: 每一个wave柱体上下运动一个循环的时长,单位s
 * delay: 当前运动的这个柱体相对于上一个柱体开始运动的延时,单位s
 */
function addWaves(id, width, duration, delay) {
  var ocean = document.getElementById(id)
  var count = Math.floor(ocean.clientWidth/width)
  var docFrag = document.createDocumentFragment()
  for(let i = 0; i < count; i ++) {
    let wave = document.createElement("div")
    wave.className = "wave"
    wave.style.width = width + "px"
    wave.style.left = (width * i) + "px"
    wave.style.animationDelay = (i * delay) + "s"
    wave.style.animationDuration = duration + "s"
    docFrag.appendChild(wave)
  }
  ocean.appendChild(docFrag)
}
addWaves("ocean1", 5, 2, 1/100)
addWaves("ocean2", 1, 2, 1/100)
addWaves("ocean3", 1, 1.5, 1/1000)
</script>
</body>
</html>

注意一下addWaves函数,当widt原创内容,盗版必究。【访问 www.tangshuang.net 获取更多精彩内容】h和delay取值不同时,得到的效果也不原创内容,盗版必究。【版权所有,侵权必究】同。width是柱体的宽度,不能太大,d【关注微信公众号:wwwtangshuangnet】【原创内容,转载请注明出处】elay是第二个柱体相对于第一个柱体开始本文作者:唐霜,转载请注明出处。未经授权,禁止复制转载。运动的延时时间,单位为妙,因此这里都是按【原创不易,请尊重版权】【关注微信公众号:wwwtangshuangnet】1/100以下作为单位的。波峰为ocea未经授权,禁止复制转载。原创内容,盗版必究。n高度的120%(写死在css里面的),原创内容,盗版必究。著作权归作者所有,禁止商业用途转载。一个波长为:waveWith = width * duration / delay,如果你的ocean宽度大于波长,就可以【原创内容,转载请注明出处】【版权所有】唐霜 www.tangshuang.net在可视区域内看到oceanWidth/waveWith个浪头。这与你的设计非常相关。【本文首发于唐霜的博客】

【作者:唐霜】【关注微信公众号:wwwtangshuangnet】原创内容,盗版必究。【本文首发于唐霜的博客】

好了,关于波浪的实现就到这里,希望对你有【本文受版权保护】原创内容,盗版必究。用。

【关注微信公众号:wwwtangshuangnet】本文作者:唐霜,转载请注明出处。【转载请注明来源】

2017-02-18 13366

为价值买单,打赏一杯咖啡

本文价值133.66RMB
已有2条评论
  1. test 2018-10-05 15:36

    思路很棒,不过最终效果锯齿太严重了

    • 否子戈 2018-10-06 17:55

      是的,css锯齿也是个难题