iTakeo

树叶飘落效果解析…


之前写过一次类似树叶落下的效果,当时想到的方法是,动态的往body里面添加元素,添加一些随机的属性,然后写一个动画,让他按照随机的速度落下,达到一种落差的效果,最后判断top值是否超过clientHeight,超过就remove掉。

嗯,看样子不错,也能跑起来,但是在安卓手机上测试,会有卡顿,后来优化了下,改成css3动画,再次测试,不错,安卓也不卡了,挺流畅,但是代码量又增加了,并且这样反复的对dom进行属性的重绘,添加和删除,效率很低。

今天换了另一种写法,所有动画效果全部利用css3来完成,也不用反复的进行dom添加和删除操作了,并且代码量是之前的三分之一。先看下面的演示效果吧。

那么先从html结构开始说,下面就是树叶dom的结构,暂时把每个div称作leaves :

  1. <div class=“leaves”><img src=“img1.png” alt=“”></div>  

下面是css部分,让每一个leaves都absolute定位,top为-100px,让他置于窗口外面隐藏起来:

  1. .leaves{width80px;heightauto;  positionabsoluteleft0pxtop: –80px;}  
  2. .leaves img{width: 100%;}  

接下来就开始写css3动画了,要想leaves从上落下,需要使用keyframes关键帧动画,让他0%的时候从0开始,100%的时候,落到650px处,然后在css中添加animation:move 6s linear infinite,让他6秒重复播放(具体animation的使用,查阅w3c介绍)

  1. //记住兼容性,需要添加moz和webkit前缀  
  2. @keyframes move  
  3. {  
  4.     0%   {transform: translate3d(0px0px,0); }  
  5.     100% {transform: translate3d(0px650px,0); }  
  6. }  

落下的效果就算写好了,由于定位的关系,他们可能全部挤在一起,这个等下通过js来改变left值,接下来让他到最下面的慢慢消失,这个其实就是opacity透明,当然也是需要keyframes关键帧动画的,到100%的时候opacity为0,时间跟上面move落下的时间需要一致,animation:fade 6s linear infinite:

  1. //记住兼容性,需要添加moz和webkit前缀  
  2. @keyframes fade  
  3. {  
  4.     0%   { opacity: 1; }  
  5.     50%  { opacity: 1; }  
  6.     100% { opacity: 0; }  
  7. }  

到目前为止,基本css都已经写好了,但是貌似还少了点什么,看看上面的demo,原来是少了左右摇摆,摇摆可以使用rotate旋转,我们给leaves里面的img添加keyframes关键帧动画【因为leaves已经有transform动画,如果这里在添加rotate会覆盖前面的】,在css中添加animation:rotate 3s ease-in-out infinite alternate。

  1. @keyframes rotate  
  2. {  
  3.     0%   { transform:rotate(-50deg); }  
  4.     100% { transform:rotate(50deg); }  
  5. }  
  1. //这是翻转元素,让树叶看起来多种多样  
  2. @keyframes rotate1  
  3. {  
  4.     0%   { transform:scale(-11) rotate(-50deg); }  
  5.     100% { transform:scale(-11) rotate(50deg); }  
  6. }  

需要注意的是:默认rotate的旋转基点再元素的中心,这样摆起来很怪异,使用transform-origin:50% -100%;来改变他的旋转基点,看起来就很自然,慢慢悠悠落下的感觉,在css中修改:

  1. .leaves img{transform-origin:50% -100%;-moz-transform-origin:50% -100%;-webkit-transform-origin:50% -100%;width: 100%;}  

如果只是这样css写,所有的leaves会一起落下,并没有上面demo那样参差不齐的感觉,那是因为所有leaves的动画时间都是一样的,现在我们需要通过js来改变每个leaves落下的时间,以及延时时间就可以了:

提示:如果你的leaves是直接写在html中的,可以忽略下面的代码,如果你想动态添加到body中,可以看下面的代码

  1. //树叶的总个数  
  2. var count = 20;   
  3. //循环创建树叶的dom元素  
  4. var fragment = document.createDocumentFragment();  
  5. for(var i = 0 ; i < count; i ++) {  
  6.     var div = document.createElement(“div”);  
  7.     div.className = ‘leaves’;  
  8.         div.innerHTML = ‘<img src=“img’+(Math.round(Random(1,3)))+’.png” alt=“”>’;  
  9.         fragment.appendChild (div);  
  10. };  
  11. //添加到body里  
  12. document.body.appendChild(fragment);  

下面是一个Random获取随机数的函数,用于改变每个leaves的left值,以及动画时间:

  1. function Random(s,e){return Math.random()*(e-s)+s;};  

接着通过js获取所有leaves:

  1. var leaves = document.querySelectorAll(‘.leaves’);  

然后使用forEach循环每个leaves,来修改动画时间,延时时间,还有摇摆的时间,让他们看起来有落差,从视觉上看像树叶一片片落下的感觉:

  1. [].forEach.call(leaves,function(o,i){  
  2.     var time1 = Random(5,10);   //树叶总共落下的时间  
  3.     var time2 = Random(1,3);    //每个树叶的延时时间  
  4.     var time3 = Random(3,6);    //每个树叶的摇摆的时间  
  5.     //随机设置left,根据浏览器宽度设置最大值  
  6.     o.style.left = Random(-30,document.documentElement.clientWidth) +’px’;  
  7.     //设置animation属性,为了兼容添加了前缀,总共时间和延时时间随机获取  
  8.     o.style.animation = o.style.WebkitAnimation = o.style.MozAnimation = ‘fade ‘+time1+’s ‘+ time2+’s linear infinite,move ‘+time1+’s ‘+ time2+’s linear infinite’;  
  9.     //设置里面图片的animation属性,设置摇摆时间,随机翻转树叶  
  10.     o.children[0].style.animation = o.children[0].style.MozAnimation = o.children[0].style.WebkitAnimation = Math.round(Random(0,1)) ? ‘rotate ‘+time3+’s ease-in-out infinite alternate’ : ‘rotate1 ‘+time3+’s ease-in-out infinite alternate’;  
  11. })  

到此,树叶飘落的动画效果以及全部写完,可以稍微修改,来实现金币效果,下雪效果…..

下载:树叶飘落演示

2015/07/09 1 / /
标签:  暂无标签

评论回复

  1. 回复 fb

    不错 😛

验证码: 9 + 2 =

回到顶部