目录1. 直接使用 CSS 动画1.1 定义动画1.2 使用2. 通过 uniapp 提供编程式创建动画2.1 定义动画2.1.1 创建动画实例2.1.2 调用实例方法来描述动画3.
本章的前提就是大家都知道动画的基本属性,例如animation-name
、animation-duration
、animation-timing-function
、animation-delay
、animation-iteration-count
和animation-direction
属性。
了解更多 animation 相关的内容。
现在制作一个左右抖动的动画效果,效果如下:
在 uniapp 中,可以通过如下两种方式来完成。
@keyframes shakeX {
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 {
animation-name: shakeX;
animation-duration: 1s;
}
<view class="box shakeX"></view>
<style>
.box {
width: 100rpx;
height: 100rpx;
background-color: green;
}
</style>
效果如下:
uniapp 提供 createAnimation
内置函数,用于创建一个动画实例 animation。
动画定义步骤:
export
方法导出动画数据animation
属性(uniapp 提供组件都支持 animation 属性)兼容性列表:
App | H5 | 微信小程序 | 支付宝小程序 | 百度小程序 | 字节跳动小程序、飞书小程序 | QQ小程序 | 快手小程序 | 京东小程序 | |
---|---|---|---|---|---|---|---|---|---|
√ | HBuilderX 2.0.4+ | √ | √ | √ | √ | √ | x | x |
注意⚠️:
export
方法每次调用后会清掉之前的动画操作。nVue
暂不支持
接下来通过编程实现上面抖动功能。
const animation = uni.createAnimation(); // 定义动画实例
在上面的 shakeX
动画定义中,通过 translate3d
来定义动画。 对应的在 animation
实例中去查找与 translate3d
相关的实例方法。
translate
相关的实例方法,如下:
方法 | 参数 | 说明 |
---|---|---|
translate | tx,[ty] | 一个参数时,表示在X轴偏移tx,单位px;两个参数时,表示在X轴偏移tx,在Y轴偏移ty,单位px。 |
translateX | tx | 在X轴偏移tx,单位px |
translateY | ty | 在Y轴偏移ty,单位px |
translateZ | tz | 在Z轴偏移tz,单位px |
translate3d | (tx,ty,tz) | 在X轴偏移tx,在Y轴偏移ty,在Z轴偏移tz,单位px |
有了这些方法之后,我们可以描述动画啦~
@keyframes shakeX {
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()
方法导出定义动画:
<template>
<view class="box" :animation="animationData"></view>
</template>
export default {
data() {
return {
animationData: {}
}
},
onLoad(){
const animation = uni.createAnimation();
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 中把一个动画周期划分成不同的组(步骤),10%
时执行 translate3d(-10px, 0, 0)
,20%
时执行translate3d(10px, 0, 0)
。
在 uni-app 中有没有类似的方式呢? 通过 step
来定义。
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%
this.animationData = animation.export();
再来执行代码,发现会动了。
从效果来看发现跟预期效果差很多,为什么? 跟 animation 的 animation-duration
属性有关。
animation-duration
: 属性指定一个动画周期的时长。
也就是一组动画运行完所需时间。 在 uni.createAnimation()
创建动画时可以传递参数,在不显示的指定 duration
值时,默认值为 400ms
。 而 step()
会继承该值。
参数 | 类型 | 必填 | 默认值 | 说明 | |
---|---|---|---|---|---|
duration | Integer | 否 | 400 | 动画持续时间,单位ms | |
timingFunction | String | 否 | "linear" | 定义动画的效果 | |
delay | Integer | 否 | 0 | 动画延迟时间,单位 ms | |
transformOrigin | String | 否 | "50% 50% 0" | 设置transform-origin |
这就是 “慢” 的原因。
在明白“慢”之后,只要把动画执行时间 (duration) 调整,应该能看到预期效果。假设期望完成抖动时间 1s
,把动画拆分成 10
组,则每一组的动画时间为 100 ms
.
现在指定 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%
animation.translateX(-10).step({
duration: 100,
}); // 90%
animation.translateX(0).step({
duration: 100,
});
this.animationData = animation.export();
再来执行代码,运行效果如下:
发现效果基本与预期效果一样了。
更多 uni.createAnimation()
相关的内容,可以自行查看文档
当不能通过 css
方式或通过动态类名一些方式去添加动画时,此时就可以考虑使用编程式来创建动画。编程式可以很灵活创建动画、控制动画运行和监听动画的结束。 其次从兼容列表来看,能很好在不同平台运行。
现在看个实际例子: 在登录时,通常需要 ☑️ 选用户协议和隐私政策 之后才允许用户登录。现在产品希望当用户在未勾选时点击登录,希望通过抖动 用户协议和隐私政策来提醒用户。
上面需求需要完成几个功能点:
通常可以这样做:
<view ref="agreement" class="agreement" :class="{ 'shakeX': actived }">
<radio
@click="onChecked"
style="transform: scale(0.6)"
:color="color"
:checked="agreement"
></radio>
我已阅读并同意<text class="service"
>用户协议</text
>和<text class="privacy">隐私政策</text>
</view>
<button @click="onLogin">登录</button>
export default {
data() {
return {
actived: false // false
};
},
mounted(){
this.$refs.agreement.$el.addEventListener("animationend", ()=> {
this.actived = false; // 动画结束移除类
});
},
methods: {
onLogin(){
// 动态添加
this.actived = true;
}
},
};
@keyframes shakeX {
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 {
animation-name: shakeX;
animation-duration: 1s;
}
发现在 app
、小程序
上运行时,发现 this.$refs.agreement.$el
为空,这是为什么,这里就是跟 uniapp 底层设计有关,如下图所示:
上面引用微信小程序,uniapp 在设计跟小程序是一样的。 也可以在上底层设计链接中了解到 uniapp
设计。
如果不能获取元素并注册animationend
事件,没办法很好知道动画结束,不知道何时应该移除。当然有的人想可以通过定时器完成,这样不能精细话控制。
此时通过编程式就可以很好解决兼容的问题,现在稍微调整下:
<view class="agreement" :animation="animationData">
<radio
@click="onChecked"
style="transform: scale(0.6)"
:color="color"
:checked="agreement"
></radio>
我已阅读并同意<text class="service"
>用户协议</text
>和<text class="privacy">隐私政策</text>
</view>
<button @click="onLogin">登录</button>
export default {
data() {
return {
animationData: {}
};
},
onLoad(){
const animation = uni.createAnimation({
timingFunction: "linear",
});
this.animation = animation;
},
methods: {
shakeX() {
const animation = this.animation;
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%
animation.translateX(-10).step({
duration: 100,
}); // 90%
animation.translateX(0).step({
duration: 100,
});
this.animationData = animation.export();
},
onLogin(){
this.shakeX();
}
},
};
通过编程方式,为什么不需要像动态类名的方式,动画结束必须移除类名否则下次不会生效? 这里留给大家去思考了。
step
来进行动画分组,同一个分组内动画函数会并行执行。到此这篇关于uniapp定义动画的几种方式的文章就介绍到这了,更多相关uniapp定义动画方式内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
--结束END--
本文标题: uniapp定义动画的几种方式总结
本文链接: https://lsjlt.com/news/195111.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-01-12
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0