本章的前提是大家都知道动画的基本属性,比如animation-name,animation-duration,animation-timing-function,animation-delay,animation-iteration-count和动画方向属性。了解有关动画的更多信息。现在制作一个左右摇晃的动画效果,效果如下:在uniapp中,可以通过以下两种方式实现。1.直接使用CSSanimation1.1定义动画@keyframesshakeX{from,to{transform:translate3d(0,0,0);}10%,30%,50%,70%,90%{transform:translate3d(-10px,0,0);}20%,40%,60%,80%{transform:translate3d(10px,0,0);}}.shakeX{动画名称:shakeX;animation-duration:1s;}1.2使用效果如下:2.通过uniapp编程创建动画uniapp提供createAnimation内置函数,用于创建动画实例动画。动画定义步骤:创建一个动画实例,调用实例的方法来描述动画。通过动画实例的export方法导出动画数据,并将导出的动画数据传递给组件的动画属性(uniapp提供的组件支持动画属性)。兼容列表:AppH5微信小程序支付宝小程序百度小程序字节跳动小程序,飞书小程序QQ小程序快手小程序京东小程序√HBuilderX2.0.4+√√√√√xx注意??:导出方法每次调用后会清空掉之前的动画操作。nvue暂时不支持2.1定义动画。接下来通过编程实现上述摇一摇的功能。2.1.1创建动画实例constanimation=uni.createAnimation();//定义一个动画实例2.1.2调用一个实例方法来描述动画在上面的shakeX动画定义中,动画是通过translate3d定义的。对应的在动画实例中找到translate3d相关的实例方法。Translate相关实例方法如下:方法参数说明translatetx,[ty]当使用一个参数时,表示X轴偏移tx,单位为px;当有两个参数时,表示X轴偏移tx,Y轴偏移ty,单位为px。translateXtx在X轴上偏移tx,单位pxtranslateYty在Y轴上偏移ty,单位pxtranslateZtz在Z轴上偏移tz,单位pxtranslate3d(tx,ty,tz)在Y轴上偏移txX轴,y轴上的ty,Z轴偏移tz,单位px有了这些方法,我们就可以描述动画了~@keyframesshakeX{from,to{transform:translate3d(0,0,0);}10%,30%,50%,70%,90%{transform:translate3d(-10px,0,0);}20%,40%,60%,80%{transform:translate3d(10px,0,0);}}上面CSS中的Translate3d对应编程方法如下:animation.translate3d(0,0,0);//原始位置animation.translate3d(-10,0,0);//向左偏移animation.translate3d(10,0,0);//右偏移有了上面的方法后,动画可以这样描述:animation.animation3d(0,0,0)//0%.animation3d(-10,0,0)//10%.animation3d(10,0,0)//20%.animation3d(-10,0,0)//30%//....animation3d(0,0,0);//100%现在通过export()方法导出定义的动画:exportdefault{data(){return{animationData:{}}},onLoad(){constanimation=uni.cr吃动画();animation.animation3d(0,0,0)//0%.animation3d(-10,0,0)//10%.animation3d(10,0,0)//20%.animation3d(-10,0,0)//30%//....animation3d(0,0,0);//100%this.animationData=animation.export();}}代码运行后,没有出现预期的抖动,是什么效果?因为uniapp是在一组定义的动画中并行执行的,所以它不会产生动画效果。回过头来看上面的CSS,一个动画循环分为不同的组(steps),在10%时执行translate3d(-10px,0,0),在20%时执行translate3d(10px,0,0)。uni-app中有类似的方法吗?按步骤定义。animation.translateX(0)//0%.translateX(10)//20%.step();animation.translateX(-10).step();//30%animation.translateX(10).step();//40%animation.translateX(-10).step();//50%animation.translateX(10).step();//60%animation.translateX(-10).step();//70%animation.translateX(10).step();//80%animation.translateX(-10).step();//90%animation.translateX(0).step();//100%这个。animationData=animation.export();再次执行代码,发现它会动。从效果来看,发现效果比想象中差很多。为什么?跟动画的animation-duration属性有关。animation-duration:属性指定动画周期的持续时间。即一组动画运行到完成所花费的时间。uni.createAnimation()创建动画时可以传递参数。当不显示指定的持续时间值时,默认值为400ms。step()将继承该值。参数类型必填默认值说明durationInteger否400动画时长,单位mstimerFunctionString否"linear"定义动画效果delayInteger否0动画延迟时间,单位mstransformOriginString否"50%50%0"设置transform-origin这是“慢”的原因。理解了“慢”之后,只要调整一下动画执行时间(duration),应该就能看到预期的效果了。假设期望晃动时间为1s,将动画分成10组,每组动画时间为100ms。现在指定step的duration值为100ms,修改后的代码如下:animation.translateX(0)//0%.translateX(10)//20%.step({duration:100,});animation.translateX(-10).step({duration:100,});//30%animation.translateX(10).step({duration:100,});//40%animation.translateX(-10).step({duration:100,});//50%animation.translateX(10).step({duration:100,});//60%animation.translateX(-10).step({duration:100,});//70%animation.translateX(10).step({duration:100,});//80%动画.translateX(-10).step({duration:100,});//90%animation.translateX(0).step({duration:100,});this.animationData=animation.export();再次执行代码,运行效果如下:发现效果与预期效果基本一致。关于uni.createAnimation()的更多信息,可以自行查看文档。3.什么时候使用编程方式创建动画当不能通过css或者动态类名添加动画时,可以考虑使用编程方式创建动画。通过编程方式,您可以灵活地创建动画、控制动画运行和监视动画结束。其次,从兼容性列表来看,在不同平台上都能很好的运行。现在来看一个实际的例子:在登录的时候,通常需要在允许用户登录之前,??选择用户协议和隐私政策。现在产品希望当用户在没有勾选的情况下点击登录,希望通过摇晃用户协议和隐私政策来提醒用户。以上需求需要完成几个功能点:定义不勾选时的抖动动画类,动态添加动画类,动画结束移除动画类(用户下次点击时需要继续抖动)),通常你可以这样做:我已阅读并同意用户协议和隐私政策exportdefault{data(){return{actived:false//false};},mounted(){this.$refs.agreement.$el.addEventListener("animationend",()=>{this.active=false;//动画结束后移除类});},methods:{onLogin(){//动态添加this.actived=true;}},};@keyframesshakeX{从,到{转换:translate3d(0,0,0);}10%,30%,50%,70%,90%{transform:translate3d(-10px,0,0);}20%,40%,60%,80%{transform:translate3d(10px,0,0);}}.shakeX{动画名称:shakeX;animation-duration:1s;}在app和小程序上运行时发现this.$refs.agreement.$el为空,这是为什么,这里和uniapp的底层设计有关,如下图:微信小程序上面引用了,uniapp的设计和小程序一样。也可以在上层底层设计到uniapp设计的链接中了解。如果不能获取元素并注册animationend事件,就没有办法很好地知道动画结束,也不知道什么时候应该移除。当然,也有人认为可以通过一个定时器来完成,所以无法在细节上进行控制。这时候可以通过编程方式解决兼容性问题,现在稍微调整一下:我已阅读并同意用户协议和隐私政策text>exportdefault{data(){return{animationData:{}};},onLoad(){constanimation=uni.createAnimation({timingFunction:"linear",});this.animation=动画;},方法:{shakeX(){constanimation=this.animation;动画.translateX(0)//0%.translateX(10)//20%.步({持续时间:100,});animation.translateX(-10).step({duration:100,});//30%animation.translateX(10).step({duration:100,});//40%animation.translateX(-10).step({duration:100,});//50%animation.translateX(10).step({duration:100,});//60%animation.translateX(-10).step({duration:100,});//70%animation.translateX(10).step({duration:100,});//80%animation.translateX(-10).step({duration:100,});//90%animation.translateX(0).step({duration:100,});this.animationData=animation.export();},onLogin(){this.shak前任();}},};通过编程,为什么不用像动态类名这样的方法,在动画结束的时候类名一定要去掉,不然下次就不会生效了?这里留给大家自己思考4.总结具体使用哪种方法创建动画有几种方式,可以根据实际业务场景来确定。uniapp编程方式使用steps对动画进行分组,同一组内的动画函数会并行执行。多个动画组的执行是串行的,即下一个需要等待上一个执行完。