当前位置:

react native动画--金币落下和amp;数字滚动效果实现

访客 2024-04-23 1073 0

最近写rn项目遇到动画需求,分享下代码供有需求的前端er参考~
先上最终效果图,如下

开始分解动画!

第一步:获取动画起点位置,首先点击时获取动画开始位置,利用mesure方法获取元素距离屏幕左上角位置;

task-list.js文件

方法参数:task-此条任务信息,object;mount-可领取金币数额number

doneCallBack=(task,mount)=>{letrefname=`goldimg${task.task_id}`;letX,Y;this.refs[refname].measure((frameX,frameY,frameWidth,frameHeight,pageX,pageY)=>{X=pageX;Y=pageY;this.props._showAnimate(true,pageX,pageY,mount);});};

第二步:task-list.js父组件main.js中执行三部分动画;

1清除上一次动画定时器,并不可见动画;
2存储位置信息,将金币如60,拆分成[6,0],以创建数字滚动动画;
3执行金币动画,金币背景动画,数字动画

方法参数:status-boolean是否需要执行动画;X-number距离屏幕左侧距离;Y-number距离屏幕顶部距离;mount-number可领取金币数额;

_showAnimate=(status,X,Y,mount)=>{this.timer&&clearTimeout(this.timer);this.state.isShowAnim&&this.setState({isShowAnim:false});//上两行防止多次点击出现混乱this.setState({clickedPositionX:X,clickedPositionY:Y,mount:mount.toString().split(''),isShowAnim:true,},()=>{if(status){this.goldAnimate._startGoldAnimate();//执行金币动画this.goldBgAnimate._startGoldAnimate();//执行金币背景动画this.goldnumRunAnimate._startAnimate();//执行数字滚动动画this._getTaskList();//重新获取任务数据}});//4s后去掉领取奖励动画弹窗this.timer=setTimeout(()=>{this.setState({isShowAnim:false})},4000)};

上金币动画代码:gold-animate.js

使用rn内置Animated模块,
三种动画效果
1spring-弹簧物理模型,
2timing-easing函数(大多数情况下使用);
3decay-指定的初始速度开始,然后速度变慢至停下;
动画先向上(x)弹40,然后向右下(x,y)同时移动
translateYVal是newAnimated.Value(0)动画初始值,为0;
useNativeDriver:true使用原生驱动加载动画,可以提高动画流畅,但是对css动画部分支持;
interpolate插值函数,具体参考官方文档;
clickedPositionX点击发生时距离屏幕左侧;
finalPosY金币背景的Y位置

js部分

_startGoldAnimate=()=>{letspring=Animated.spring,timing=Animated.timing,parallel=Animated.parallel;spring(this.state.translateYVal,{toValue:1,duration:500,friction:3,tension:50,useNativeDriver:true}).start();parallel([timing(this.state.translateXVal,{toValue:1,duration:300,useNativeDriver:true,delay:600}),timing(this.state.translateSecYVal,{toValue:1,duration:300,useNativeDriver:true,delay:600})]).start();};

react部分

return(<Animated.Viewstyle={{position:'absolute',zIndex:10000,height:'100%',width:'100%',left:clickedPositionX-5,top:clickedPositionY-5,transform:[{translateY:translateYVal.interpolate({inputRange:[0,0.7,1],outputRange:[0,-40,0]})},]}}><Animated.Imagestyle={{height:22,width:22,transform:[{translateX:translateXVal.interpolate({inputRange:[0,1],outputRange:[0,Utils.windowSize.width-clickedPositionX-89]})},{translateY:translateSecYVal.interpolate({inputRange:[0,1],outputRange:[0,finalPosY-clickedPositionY15]})},],}}source={require('resource/newtask/animategold.png')}></Animated.Image></Animated.View>)

代码继续,按顺序金币背景动画
gold-bg-animate.js
动画部分:背景向上Y,移动60

_startGoldAnimate=()=>{Animated.timing(this.state.animValue,{toValue:1,duration:1000,useNativeDriver:true}).start();}

react部分

return(<Viewref={(view)=>this.goldNumBg=view}style={styles.container}><Animated.Imagestyle={{position:'absolute',bottom:-60,right:0,height:55,width:104,transform:[{translateY:animValue.interpolate({inputRange:[0,1],outputRange:[0,-60]})}],}}source={require('resource/newtask/animate_gold_bg.png')}></Animated.Image></View>)

接下来最后一个动画,数字滚动动画
文件goldnum-run-animate.js
动画部分,第一个透明度从0到1;每个数字依次开始动画,注意里面的delay属性;

_startAnimate=()=>{Animated.timing(this.state.opacityAnim,{toValue:1,duration:1000,}).start();this.state.animAry.forEach((item,index)=>{Animated.timing(item.value,{toValue:1,duration:(Number(item.num)1)*200,delay:index*400}).start();});};

animAry为创建出数组,为每个数字添加动画初始值;

letnumAry=this.state.mount;letanimAry=[];for(leti=0;i<numAry.length;i){animAry.push({num:numAry[i],name:`animValue${i}`,value:newAnimated.Value(0),})}

react部分:mount就是上文提到过的数字改造的数组,60=》[6,0]

return(<Viewstyle={styles.numContainer}><Animated.Textstyle={[styles.goldText,styles.addMark,{opacity:opacityAnim.interpolate({inputRange:[0,1],outputRange:[0,1]})}]}></Animated.Text>{mount.map((item,index)=>{return(<Animated.Viewkey={index}style={[styles.textcon,{height:(Number(item)1)*30,top:this.createAnimate(item,index)}]}>{this._createSingleNum(item)}</Animated.View>)})}</View>)

_createSingleNum(item)方法如下:

参数item-传入的数字,number;

_createSingleNum=(num)=>{letary=[];for(leti=0;i<=num;i){ary.push(i)}return(<View>{ary.map((item,index)=>{return(<Textkey={index}style={[styles.goldText]}>{item}</Text>)})}</View>)};

创建的结果如下,每个数字列有个动画,从0-5滚动;

<View><Text>0<Text><Text>1<Text><Text>2<Text><Text>3<Text><Text>4<Text><Text>5<Text><View>

createAnimate()方法,
参数:it-数字,number例如:5ind-索引值,number,如0;
为数组中每个数字,创建动画,最终通过top值改变行程动画

createAnimate=(it,ind)=>{letpropName=`animValue${ind}`;return(this.state.animAry[ind].value.interpolate({inputRange:[0,1],outputRange:[30,-30*it]}))};

最终三个动画实现文中开头动画。就酱吧~

发表评论

  • 评论列表
还没有人评论,快来抢沙发吧~