小程序使用uni.createAnimation只执行一次的问题

文章介绍了如何在Vue页面中创建一个动态点赞动画,通过临时动画对象的step()方法表示动画完成,并使用export方法导出动画数据,页面卸载时清除数据。

思路:
  1. 在页面创建的时候,创建一个临时动画对象
  2. 调用 step() 来表示一组动画完成
  3. 通过动画实例的export方法导出动画数据传递给组件的animation属性
  4. 还原动画
  5. 页面卸载的时候,清除动画数据
<template>
	<view class="content">
    <view class="item" v-for="(item,index) in list" :key="item.id">
      <view class="left"> {{item.memo}} </view>
      <view class="right" @click="praiseMe(index)">
        <image src="../../static/praise.png"></image>
        <view class="font11">点赞</view>
        <view :animation="animationDataArr[index]" class="praise-me animation-opacity"> +1 </view>
      </view>
    </view>
	</view>
</template>
 
<script>
export default {
	data() {
		return {
      list:[
        {id:"001",memo:"苹果"},
        {id:"002",memo:"橘子"},
        {id:"003",memo:"草莓"},
        {id:"004",memo:"香蕉"}
      ],
      animationData: {},
      animationDataArr: []
		};
	},
  onLoad() {
    // 1 在页面创建的时候,创建一个临时动画对象
    this.animation = uni.createAnimation();
    this.animationDataArr=Array(this.list.length).fill({});
  },
	onUnload() {
		// 5 页面卸载的时候,清除动画数据
		this.animationData = {};
		this.animationDataArr=Array(this.list.length).fill({});
	},
	methods: {
    // 实现点赞动画效果
   	praiseMe(index) {
   		// 2 调用 step() 来表示一组动画完成
   		this.animation.translateY(-90).opacity(1).step({
   			duration: 400
   		});
   		
   		// 3 通过动画实例的export方法导出动画数据传递给组件的animation属性
   		this.animationData = this.animation;
   		this.animationDataArr[index] = this.animationData.export();
   
   		// 4 还原动画
   		setTimeout(()=> {
   			this.animation.translateY(0).opacity(0).step({
   				duration: 0
   			});
   			this.animationData = this.animation;
   			this.animationDataArr[index] =  this.animationData.export();
   		}, 600)
   	},
  }
};
</script>
 
<style scoped>
.item{
  display: flex;
  align-items: center;
  text-align: center;
  border: 1px pink solid;
  margin-top:20rpx ;
  padding: 20rpx 0;
}
.item image{
  width: 80rpx;
  height: 80rpx;
  z-index: 10;
}
.item .left{
  flex: 1;
}
.item .right{
  width: 300rpx;
  border-left: 1px pink dashed;
  padding-top: 50rpx;
}
 
.praise-me {
	font-size: 14px;
	color: #feab2a;
}
 
.animation-opacity {
	font-weight: bold;
	opacity: 0;
}
</style>

 

<think>我们正在讨论的问题是在uni-app开发微信小程序时,使用this.animationLeft.translateX动画时出现的跳转异常问题。根据经验,这种问题通常与动画的执行时机或动画对象的正确使用有关。下面将逐步分析并提供解决方案。首先,需要明确的是,在微信小程序中,动画API的使用有一定的规范,而在uni-app中封装了类似的API,但在使用时仍需注意。可能的原因及解决方案:1.动画对象未正确初始化:在uni-app中,我们通常使用`uni.createAnimation`创建动画对象。如果动画对象没有正确初始化,可能会导致异常。2.动画操作和跳转的时序问题:动画执行是异步的,如果在动画还未完成时就进行页面跳转,可能会导致动画效果未能正确呈现或跳转异常。3.微信小程序中动画API的兼容性问题。下面是一个典型的动画使用步骤,以及如何避免跳转异常:步骤1:正确创建动画对象在页面的data中初始化一个动画对象,然后在onLoad或需要的时候创建动画实例。步骤2:使用动画API设置动画效果,并应用到组件上使用translateX等变换方法设置动画,然后调用step()表示一组动画完成,最后通过export方法导出动画数据传递给组件。步骤3:在动画完成后进行跳转使用setTimeout设置一个延时,等待动画执行完毕再进行跳转。或者使用动画的回调函数(如果有)。然而,需要注意的是,微信小程序的动画API本身不提供回调函数,所以通常使用setTimeout来延迟跳转。示例代码:在页面的data中定义:data(){return{animationLeft:{}}},onReady(){this.animationLeft=uni.createAnimation({duration:300,timingFunction:'ease',});},然后在方法中:methods:{startAnimationAndJump(){//设置动画效果this.animationLeft.translateX(-100).step();this.setData({animationLeft:this.animationLeft.export()});//在动画完成后跳转,使用setTimeout,时间略大于动画时间setTimeout(()=>{uni.navigateTo({url:'/pages/nextPage/nextPage'});},350);}}注意:如果动画执行时间较长,需要相应调整setTimeout的延时。另外,还有一种可能是页面跳转的冲突,比如跳转时动画还在进行,导致页面卡顿或跳转失败。因此,确保在动画完成后跳转是关键。其他注意事项:-确保this.animationLeft确实是通过uni.createAnimation创建的。-避免在动画进行中多次触发跳转,可以设置一个标志位防止重复跳转。如果以上方法仍不能解决问题,可以尝试使用微信小程序的动画API原生写法,在uni-app中也是支持的。总结:主要解决思路是确保动画执行完成后再进行跳转,使用setTimeout延时跳转。相关问题:1.如何在uni-app中正确使用动画API?2.微信小程序中动画的执行机制是怎样的?3.如何避免uni-app中页面跳转与动画的冲突?</think> ### UniApp微信小程序AnimationLeft TranslateX动画跳转异常解决方案 在UniApp微信小程序使用`this.animationLeft.translateX`动画时出现跳转异常,通常由**动画未完成即跳转**或**动画对象状态冲突**引起。以下是完整解决方案: #### 核心问题原因 1. **动画异步执行未完成**:`translateX`动画需要完成时间,直接跳转会中断动画 2. **页面卸载时动画未重置**:跳转后原页面动画对象未清理 3. **设备兼容性问题**:部分安卓机型对CSS动画支持差异[^1] 4. **动画状态残留**:多次触发动画时对象状态冲突 #### 完整解决方案(三步) ##### 1. 添加动画完成延时 ```javascript // 在触发跳转的方法内 this.animationLeft.translateX(-100).step({ duration: 500 }); // 添加动画完成延时 setTimeout(() => { uni.navigateTo({ url: '/target/page' }) }, 600); // 比动画时间长100ms ``` ##### 2. 在页面onUnload中重置动画 ```javascript onUnload() { // 重置动画对象防止状态残留 this.animationLeft = uni.createAnimation(); this.setData({ animationLeft: this.animationLeft.export() }); } ``` ##### 3. 添加硬件加速优化(解决安卓卡顿) ```css /* 在动画元素添加 */ .animated-element { transform: translateZ(0); will-change: transform; } ``` #### 替代方案(推荐) 使用`<wxs>`模块实现高性能动画: ```html <wxs module="animation" src="./animation.wxs"></wxs> <view :change:prop="animation.animate" :prop="translateValue" style="transition: transform 0.5s ease" ></view> ``` ```js // animation.wxs module.exports = { animate: function(newValue, oldValue) { return 'transform: translateX(' + newValue + 'px)'; } } ``` #### 调试建议 1. 开启`manifest.json`中的调试模式 ```json "mp-weixin": { "setting": { "urlCheck": false, "enableAnimationDebug": true } } ``` 2. 使用`console.log(this.animationLeft)`检查动画对象状态 3. 在模拟器中勾选**开启动画调试**选项
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值