uni-app 动画效果
章节介绍
在移动应用开发中,流畅的动画效果是提升用户体验的重要因素。uni-app 提供了丰富的动画 API 和实现方式,使开发者能够轻松创建各种动画效果。本章节将详细介绍 uni-app 中的动画实现方法,包括基础动画 API、过渡效果以及复杂的动画序列,帮助你掌握如何为应用添加生动流畅的动画效果。
核心知识点讲解
1. 动画 API 概述
uni-app 提供了两种主要的动画实现方式:
- CSS 动画:使用 CSS3 的
animation和transition属性 - JS 动画 API:使用 uni-app 封装的
uni.createAnimation方法
CSS 动画
CSS 动画适用于简单的、预定义的动画效果,如元素的淡入淡出、平移、旋转等。
/* 定义动画 */
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
/* 使用动画 */
.animated-element {
animation: fadeIn 0.5s ease-in-out;
}JS 动画 API
JS 动画 API 提供了更灵活的动画控制能力,适用于复杂的、需要动态控制的动画效果。
// 创建动画实例
const animation = uni.createAnimation({
duration: 500, // 动画持续时间
timingFunction: 'ease', // 动画曲线
delay: 0, // 动画延迟时间
transformOrigin: '50% 50% 0' // 动画原点
});
// 定义动画步骤
animation.translateX(100).rotate(180).step();
// 导出动画数据
this.animationData = animation.export();
// 在模板中使用
// <view animation="{{animationData}}"></view>2. 过渡效果
过渡效果是指元素在状态变化时的平滑过渡,如元素的显示/隐藏、位置变化等。
基本过渡效果
/* 基本过渡效果 */
.transition-element {
transition: all 0.3s ease;
}
.transition-element:hover {
transform: scale(1.1);
color: #ff4d4f;
}条件渲染中的过渡
在使用 v-if、v-show 等指令进行条件渲染时,可以结合过渡类实现平滑的过渡效果。
<template>
<view>
<button @click="show = !show">切换显示</button>
<view class="transition-box" v-show="show"></view>
</view>
</template>
<style>
.transition-box {
width: 200rpx;
height: 200rpx;
background-color: #409eff;
transition: all 0.3s ease;
}
.transition-box[v-show="false"] {
opacity: 0;
transform: scale(0.8);
}
</style>
<script>
export default {
data() {
return {
show: true
};
}
};
</script>3. 动画序列
动画序列是指多个动画按照一定的顺序执行,形成连贯的动画效果。
链式动画
使用 JS 动画 API 可以创建链式动画,通过多次调用 step() 方法实现。
// 创建动画实例
const animation = uni.createAnimation({
duration: 500,
timingFunction: 'ease'
});
// 第一个动画:平移
animation.translateX(100).step();
// 第二个动画:旋转
animation.rotate(180).step();
// 第三个动画:缩放
animation.scale(0.8).step();
// 导出动画数据
this.animationData = animation.export();延迟动画
通过设置不同的 delay 参数,可以实现动画的延迟执行。
// 创建动画实例
const animation1 = uni.createAnimation({
duration: 500,
timingFunction: 'ease',
delay: 0
});
const animation2 = uni.createAnimation({
duration: 500,
timingFunction: 'ease',
delay: 200
});
// 执行第一个动画
animation1.translateX(100).step();
this.animationData1 = animation1.export();
// 执行第二个动画
animation2.translateX(100).step();
this.animationData2 = animation2.export();实用案例分析
案例:实现页面切换动画
在 uni-app 中,可以通过配置 pages.json 文件实现页面切换动画,也可以通过自定义动画实现更灵活的页面转场效果。
1. 配置页面切换动画
在 pages.json 文件中,可以为全局或单个页面配置转场动画:
{
"pages": [
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "首页",
"app-plus": {
"animationType": "slide-in-right",
"animationDuration": 300
}
}
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8",
"app-plus": {
"animationType": "fade-in",
"animationDuration": 300
}
}
}2. 自定义页面切换动画
对于更复杂的页面切换动画,可以使用自定义组件和动画 API 实现:
<!-- 页面切换动画组件 -->
<template>
<view class="page-transition" :class="{ 'enter': enter, 'leave': leave }">
<slot></slot>
</view>
</template>
<style scoped>
.page-transition {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
transition: all 0.3s ease;
}
.page-transition.enter {
transform: translateX(100%);
opacity: 0;
}
.page-transition.enter-active {
transform: translateX(0);
opacity: 1;
}
.page-transition.leave {
transform: translateX(0);
opacity: 1;
}
.page-transition.leave-active {
transform: translateX(-100%);
opacity: 0;
}
</style>
<script>
export default {
data() {
return {
enter: true,
leave: false
};
},
mounted() {
// 触发进入动画
this.$nextTick(() => {
this.enter = true;
});
},
methods: {
// 触发离开动画
leave() {
this.leave = true;
setTimeout(() => {
this.$emit('leave-done');
}, 300);
}
}
};
</script>3. 页面切换动画使用示例
<!-- 页面 A -->
<template>
<view class="container">
<text>页面 A</text>
<button @click="navigateToPageB">跳转到页面 B</button>
</view>
</template>
<script>
export default {
methods: {
navigateToPageB() {
uni.navigateTo({
url: '/pages/pageB/pageB'
});
}
}
};
</script>
<!-- 页面 B -->
<template>
<page-transition ref="transition">
<view class="container">
<text>页面 B</text>
<button @click="navigateBack">返回页面 A</button>
</view>
</page-transition>
</template>
<script>
import PageTransition from '@/components/page-transition.vue';
export default {
components: {
PageTransition
},
methods: {
navigateBack() {
this.$refs.transition.leave();
setTimeout(() => {
uni.navigateBack();
}, 100);
}
}
};
</script>常见问题与解决方案
1. 动画不流畅
问题:动画执行时出现卡顿或不流畅的情况。
解决方案:
- 优先使用 CSS 动画,因为 CSS 动画由 GPU 加速
- 避免在动画过程中修改布局属性(如 width、height、top、left 等)
- 使用
transform和opacity属性进行动画,这些属性不会触发重排 - 对于复杂动画,考虑使用
requestAnimationFrame优化
2. 动画在不同平台表现不一致
问题:同一动画在不同平台(如 iOS 和 Android)表现不一致。
解决方案:
- 测试不同平台的动画效果,针对差异进行适配
- 使用条件编译为不同平台提供不同的动画实现
- 优先使用 uni-app 官方推荐的动画 API 和实现方式
- 对于复杂动画,考虑使用第三方动画库如 lottie-web
3. 动画结束后元素位置重置
问题:使用 uni.createAnimation 创建的动画结束后,元素位置会重置到初始状态。
解决方案:
- 动画结束后,手动更新元素的样式属性
- 使用
uni.createAnimation的fillMode参数(仅支持部分平台) - 对于需要持久化的动画效果,考虑使用 CSS 类切换而不是 JS 动画
代码优化建议
1. 动画性能优化
// 优化前:直接修改样式属性
this.style.top = '100px';
this.style.left = '100px';
// 优化后:使用 transform 属性
this.style.transform = 'translate(100px, 100px)';2. 动画代码复用
// 优化前:重复创建动画实例
const animation1 = uni.createAnimation({ duration: 300 });
animation1.translateX(100).step();
this.animationData1 = animation1.export();
const animation2 = uni.createAnimation({ duration: 300 });
animation2.translateY(100).step();
this.animationData2 = animation2.export();
// 优化后:封装动画工具函数
methods: {
createAnimation(styles, duration = 300) {
const animation = uni.createAnimation({ duration });
Object.keys(styles).forEach(key => {
animation[key](styles[key]);
});
animation.step();
return animation.export();
}
}
// 使用
this.animationData1 = this.createAnimation({ translateX: 100 });
this.animationData2 = this.createAnimation({ translateY: 100 });3. 动画序列管理
// 优化前:嵌套 setTimeout
setTimeout(() => {
// 第一个动画
this.animate1 = true;
setTimeout(() => {
// 第二个动画
this.animate2 = true;
setTimeout(() => {
// 第三个动画
this.animate3 = true;
}, 300);
}, 300);
}, 300);
// 优化后:使用 Promise 链
methods: {
delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
},
async runAnimationSequence() {
// 第一个动画
this.animate1 = true;
await this.delay(300);
// 第二个动画
this.animate2 = true;
await this.delay(300);
// 第三个动画
this.animate3 = true;
}
}章节总结
本章节详细介绍了 uni-app 中的动画效果实现方法,包括:
- 动画 API 概述:介绍了 CSS 动画和 JS 动画 API 的使用方法
- 过渡效果:讲解了如何实现元素状态变化时的平滑过渡
- 动画序列:介绍了如何创建链式动画和延迟动画
- 实用案例:通过页面切换动画的实现,展示了动画效果在实际应用中的使用
- 常见问题与解决方案:针对动画实现中常见的问题提供了解决方案
- 代码优化建议:提供了动画性能优化、代码复用和动画序列管理的优化建议
通过本章节的学习,你应该能够掌握 uni-app 中各种动画效果的实现方法,为你的应用添加流畅、生动的动画效果,提升用户体验。在实际开发中,应根据具体场景选择合适的动画实现方式,并注意优化动画性能,确保动画效果流畅自然。