当前位置: 首页 > Web前端 > CSS

前端动画

时间:2023-03-30 14:17:50 CSS

被奥迪灯想到了。最近对汽车比较感兴趣。我平时比较注意身边的车。我发现有些奥迪车型的转向灯很有特色。从左到右有动画效果。视觉效果很好,引起了我的好奇,如何用代码在网页上模拟出来呢?先来看看我们需要实现的效果:预览方法一:css首先想到的自然是css,因为css动画很强大,而且这种方法代码简单,效果流畅,强烈推荐.代码如下:

div.css-light{width:0%;高度:6px;背景:#ff8908;动画:mymove1sease-outinfinite;}@keyframesmymove{from{width:0%;}至{宽度:100%;其中,最核心的属性就是动画。如何使用动画?如下:第一个属性指定要绑定到选择器的关键帧的名称,本例中为mymove;第二个属性指定动画完成需要多少秒或毫秒,在本例中为1s;第三个属性设置动画将如何完成一个循环,默认为ease,本例为ease-out,表示动画以低速结束;第四个属性定义了动画播放的次数,本例为无限循环;可见CSS动画真的很强大,它还支持多种动画效果,比如ease-out的效果。如果要用js模拟ease-out等各种效果,不是一行代码的事情。更多参数信息请参考:CSS3动画(animation)属性动画方法二:js方法js除了css之外,还赋予了模拟动画的能力。该方法通常使用setInterval()方法来控制动画。代码如下:
letdiv=document.getElementById('process')functionprocess(){div.style.width='0%'setInterval(()=>{div.style.width=(parseInt(div.style.width,10)+1)+'%'if(div.style.width==='100%'){div.style.width='0%'}},20)}process()但是这种方法有几个缺点。第一个不是很精确,为它传入的第二个参数(比如本例中的20),其实只是指定了将动画代码添加到浏览器UI线程队列等待执行的时间。如果其他任务已经添加到队列的前面,则动画代码将在前面的任务完成后才会执行。也就是说,以毫秒为单位的延迟并不意味着动画代码会在那个时候执行,而只是说代码会在那个时候被添加到任务队列中。如果UI线程很忙,比如忙于处理用户操作,即使是入队代码也不会立即执行。第二个缺点是编写动画循环需要知道延迟应该有多长。一方面,循环间隔必须足够短,这样不同的动画效果才能显得流畅;另一方面,循环间隔必须足够长,以确保浏览器有能力渲染产生的变化。就拿这个例子来说,如果你把20改成200,那么你会发现动画效果会一个一个出现。而从20变成1,那么动画执行起来会非常快,性能开销也会增加。第三个缺点是setInterval的开销比较大,即使页面在后台运行,这个开销也一直存在。那么,这些劣势能否得到优化呢?是时候播放requestAnimationFrame了!与setInterval相比,requestAnimationFrame最大的优势在于系统决定回调函数的执行时机。具体来说,如果屏幕刷新率为60Hz,则回调函数每16.7ms执行一次。如果刷新率为75Hz,那么这个时间间隔就变成了1000/75=13.3ms。换句话说,requestAnimationFrame的步伐跟随系统的刷新步伐。可以保证回调函数在屏幕的每个刷新间隔只执行一次,这样就不会造成丢帧,也不会造成动画卡顿。担心!使用后,你再也不用担心循环间隔应该设置多少,它帮你搞定。它的用法很简单,在requestAnimationFrame中改写如下:%'if(div.style.width==='100%'){div.style.width='0%'}window.requestAnimationFrame(updateProgress);}window.requestAnimationFrame(updateProgress);关于requestAnimationFrame的更多信息,请参考:深入了解requestAnimationFrame的真实情况window.requestAnimationFrame这篇文章模拟了一个简单的车灯动画效果,引出了一些前端动画知识,通过两种不同的方式实现(css和js)。最后,真正在车上的效果应该是通过多个LED灯来实现的。这里我提供一个方法(借助Vue)供大家参考。有兴趣的同学可以用其他方法自己模拟扩展。预览(需要翻墙),核心代码如下:
newVue({el:'#app',data(){return{items:[{id:1,active:false},{id:2,active:false},{id:3,active:false},{id:4,active:false},{id:5,active:false},{id:6,active:false},{id:7,active:false},{id:8,active:false},{id:9,active:false},{id:10,active:false}]}},创建(){this.init()},方法:{init(){this.items[0].active=true}},watch:{items:{handler(val){letindex=val.findIndex(v=>v.active===false)如果(index===-1){setTimeout(()=>{val.forEach(v=>v.active=false)},50)}else{setTimeout(()=>{val[index].active=真的},50)}},深:真}}})