一、 属性动画animation
1. 基本使用
组件的某些通用属性变化时,可以通过属性动画实现渐变过渡效果,提升用户体验。支持的属性包括width、height、backgroundColor、opacity(透明度)、scale(缩放)、rotate(旋转)、translate(平移)等。
使用动画的核心步骤如下:
- 声明相关状态变量
- 将状态变量设置到相关可动画属性接口
- 通过属性动画接口开启属性动画(在属性动画上面的属性会应用动画)
- 通过状态变量改变UI界面
@Entry
@Component
struct Index {
@State w:number = 50 //宽
@State h:number = 50 //高
@State Opacity:number = 1 //透明度
@State bkc:ResourceColor = Color.Blue //背景色
@State ag:number = 0 //旋转角度
@State y:number = 1 //缩放
@State x:number = 1 //缩放
@State sy:number = 0 //平移
build() {
Column() {
Column() {}
.width(this.w)
.height(this.h)
.backgroundColor(this.bkc)//背景色
.opacity(this.Opacity)//透明度
.scale({x:this.x,y:this.y})//缩放
.rotate({angle:this.ag})//旋转角度
.translate({x:0,y:this.sy})//平移
.animation({})
.onClick(()=>{
// 三元表达式: 判断语句 ?(true) :(false)
this.w = this.w == 50 ?150 :50
this.h = this.h == 50 ?150 :50
this.Opacity = this.Opacity == 1 ?0.5 :1
this.ag = this.ag == 0 ?360 :0
this.sy = this.sy == 0 ?200 :0
this.y = this.y == 1 ?2 :1
this.x = this.x == 1 ?2 :1
this.bkc = this.bkc == Color.Blue ?Color.Red :Color.Blue
})
}
.width('100%')
.height('100%')
.backgroundColor(Color.Pink)
}
}
2.常用属性
| 名称 | 参数类型 | 必填 | 描述 |
|---|---|---|---|
| duration | number | 否 | 动画时长,单位为毫秒。默认值:1000 |
| curve | string、 Curve、ICurve | 否 | 设置动画曲线。默认值:Curve.EaseInOut |
| delay | number | 否 | 动画延迟播放时间。单位为毫秒,默认不延时播放。默认值:0取值范围:(-∞, +∞) |
| iterations | number | 否 | 动画播放次数。默认值:1 说明: 设置为-1时表示无限次播放。设置为0时表示无动画效果。 |
| playMode | PlayMode | 否 | 动画播放模式,默认播放完成后重头开始播放。默认值:PlayMode.Normal |
| onFinish | () => void | 否 | 结束回调,动画播放完成时触发。从API version 9开始,该接口支持在ArkTS卡片中使用。 |
(1)动画枚举 Curve的取值含义
| 名称 | 描述 |
|---|---|
| Linear | 表示动画从头到尾的速度都是相同的。 |
| Ease | 表示动画以低速开始,然后加快,在结束前变慢,CubicBezier(0.25, 0.1, 0.25, 1.0)。 |
| EaseIn | 表示动画以低速开始,CubicBezier(0.42, 0.0, 1.0, 1.0)。 |
| EaseOut | 表示动画以低速结束,CubicBezier(0.0, 0.0, 0.58, 1.0)。 |
| EaseInOut | 表示动画以低速开始和结束,CubicBezier(0.42, 0.0, 0.58, 1.0)。 |
| FastOutSlowIn | 标准曲线,CubicBezier(0.4, 0.0, 0.2, 1.0)。 |
| LinearOutSlowIn | 减速曲线,CubicBezier(0.0, 0.0, 0.2, 1.0)。 |
| FastOutLinearIn | 加速曲线,CubicBezier(0.4, 0.0, 1.0, 1.0)。 |
| ExtremeDeceleration | 急缓曲线,CubicBezier(0.0, 0.0, 0.0, 1.0)。 |
| Sharp | 锐利曲线,CubicBezier(0.33, 0.0, 0.67, 1.0)。 |
| Rhythm | 节奏曲线,CubicBezier(0.7, 0.0, 0.2, 1.0)。 |
| Smooth | 平滑曲线,CubicBezier(0.4, 0.0, 0.4, 1.0)。 |
| Friction | 阻尼曲线,CubicBezier(0.2, 0.0, 0.2, 1.0)。 |
| 自定义: | import curves from '@ohos.curves'curves.cubicBezierCurve(0.29,-0.33,.83,0.67) |
(2)playMode 取值
| 名称 | 描述 |
|---|---|
| Normal | 动画正向播放。(默认值) |
| Reverse | 动画反向播放。 |
| Alternate | 动画在奇数次(1、3、5...)正向播放,在偶数次(2、4、6...)反向播放。需配合属性iterations设置为-1无限播放使用。 |
| AlternateReverse | 动画在奇数次(1、3、5...)反向播放,在偶数次(2、4、6...)正向播放。需配合属性iterations设置为-1无限播放使用。 |
@Entry
@Component
struct Index {
@State w:number = 50
build() {
Column() {
Column(){}
.height(50)
.width(this.w)
.backgroundColor(Color.Blue)
.animation({
// duration:1000, //播放时长
curve:Curve.Linear, //动画曲线
delay:3000, //延迟3秒播放
iterations:-1, // 播放次数 -1为无限播放
playMode:PlayMode.Alternate //动画在奇数次(1、3、5...)正向播放,在偶数次(2、4、6...)反向播放。
})
.onClick(()=>{
this.w = 200
})
}
.width('100%')
.height('100%')
.backgroundColor(Color.Pink)
}
}
@Entry
@Component
struct Index {
@State w:number = 50
build() {
Column() {
Column(){}
.height(50)
.width(this.w)
.backgroundColor(Color.Blue)
.animation({
curve:Curve.Linear, //动画曲线
delay:2000, //**延迟2秒播放**
iterations:2,
onFinish:()=>{
AlertDialog.show({message:'动画完成了'})
}
})
.onClick(()=>{
this.w = 200
})
}
.width('100%')
.height('100%')
.backgroundColor(Color.Pink)
}
}
3.组件加载自动触发
上面学的动画效果都是我们点击后才开始的,下面我们可以通过挂载事件(通用事件)让动画效果自动触发。
| 名称 | 支持冒泡 | 功能描述 |
|---|---|---|
| onAppear(event: () => void) | 否 | 组件挂载显示时触发此回调。从API version 9开始,该接口支持在ArkTS卡片中使用。 |
| onDisAppear(event: () => void) | 否 | 组件卸载消失时触发此回调。从API version 9开始,该接口支持在ArkTS卡片中使用。 |
@Entry
@Component
struct Index {
@State sc:number = 1 // 缩放
@State isShow:boolean = false // 控制文本是否出现
build() {
Column({space:50}) {
Button('显示和隐藏')
.onClick(()=>{
this.isShow = !this.isShow
})
if(this.isShow){
Text('全场低至一分购')
.fontSize(30)
.fontWeight(800)
.fontColor(Color.Red)
.backgroundColor(Color.Orange)
.padding(10)
.margin({top:50})
.borderRadius(20)
.scale({
x:this.sc,
y:this.sc
})
.animation({
iterations:-1,
playMode:PlayMode.Alternate
})
.onAppear(()=>{
this.sc = 1.3
AlertDialog.show({message:'文本出来了'})
})
.onDisAppear(()=>{
AlertDialog.show({message:'文本销毁了'})
})
}
}
.width('100%')
.height('100%')
.backgroundColor(Color.Pink)
}
}
二、显式动画animateTo
1.了解
属性动画 animation是作为属性使用,而animateTo显示动画是一个系统的内置函数,可以直接调用,一般事件触发时一起使用,比如点击事件,滚动事件等等。基本用法:
// 参数 1 动画选项 和 animation 相同
// 参数 2 箭头函数,状态变量的修改写在里面
animateTo({参数1}, () => {
状态变量的改变
})
2.案例-返回顶部
使用了Tabs组件和自定义tabBar,
@Entry
@Component
struct Index {
//顶部按钮平移
@State translateY:number = 80
//Tabs的首页导航自定义样式
@Builder
firstTabBarBuilder() {
Column() {
Image($r('app.media.mjyp_tabbar_icon_0_1_selected'))
.width(25)
Text('首页')
.fontColor(Color.Orange)
}
}
//Tabs的其他导航自定义样式
@Builder
otherTabBarBuilder(icon: string, text: string) {
Column() {
Image($r(icon))
.width(25)
Text(text)
}
}
scroller = new Scroller()
build() {
Column() {
Tabs() {
TabContent() {
Stack({ alignContent: Alignment.BottomEnd }) {
// 3. 绑定控制器对象
Scroll(this.scroller) {
Column() {
}
.height(2000)
.width('100%')
.backgroundColor('#0094ff')
.linearGradient({angle:180,colors:[['#0094ff',0],['#9400ff',0.5],['#00ff94',1]]})
}
// 4. 滚动触发事件中
.onWillScroll(() => {
// 4.1 如果y偏移量大于200,则
if(this.scroller.currentOffset().yOffset > 200){
animateTo({duration:500},()=>{
this.translateY = -50
})
}else {
animateTo({duration:500},()=>{
this.translateY = 80
})
}
})
// 顶部按钮
Column() {
Image($r('app.media.ic_public_arrow_up_0'))
.fillColor('rgba(0,0,0,0.5)')
.width(45)
Text('顶部')
}
.backgroundColor(Color.White)
.height(80)
.width(80)
.borderRadius(40)
// 1. 通用属性平移-> y方向向上平移
.translate({
x:-20,
y: this.translateY
})
.onClick(()=>{
this.scroller.scrollEdge(Edge.Top)
})
}
}.tabBar(this.firstTabBarBuilder())
TabContent() {
}.tabBar(this.otherTabBarBuilder('app.media.mjyp_tabbar_icon_1', '推荐'))
TabContent() {
}.tabBar(this.otherTabBarBuilder('app.media.mjyp_tabbar_icon_1', '我的'))
TabContent() {
}.tabBar(this.otherTabBarBuilder('app.media.mjyp_tabbar_icon_1', '我的'))
}
.barPosition(BarPosition.End)
}
.height('100%')
.width('100%')
}
}
三、ImageAnimator 帧动画组件
1.了解
ImageAnimator不是容器组件,也不需要传递参数,只需要设置属性即可。用法:
ImageAnimator()
.属性()
2.常用属性
| 参数名称 | 参数类型 | 参数描述 |
|---|---|---|
| images | Array<[ImageFrameInfo] | 设置图片帧信息集合。 说明: 不支持动态更新。 |
| state | AnimationStatus | 默认为初始状态,用于控制播放状态。 |
| duration | number | 单位为毫秒,默认时长为1000ms;duration为0时,不播放图片;值的改变只会在下一次循环开始时生效;当images中任意一帧图片设置了单独的duration后,该属性设置无效。 默认值:1000 从API version 10开始,该接口支持在ArkTS卡片中使用。 |
| iterations | number | 默认播放一次,设置为-1时表示无限次播放。 默认值:1 |
!!! 注意点:
- ImageAnimator组件必须设置宽和高,否则看不见
- 如果图片数量大,并且单个图片的占用空间大,会影响性能,使用时尽量对图片进行压缩处理
使用如下:
@Entry
@Component
struct Index {
@State state:AnimationStatus = AnimationStatus.Initial
build() {
Column() {
ImageAnimator()
.images([
{ src: $r('app.media.loading_dog_0') },
{ src: $r('app.media.loading_dog_1') },
{ src: $r('app.media.loading_dog_2') },
{ src: $r('app.media.loading_dog_3') },])
.state(this.state) // 动画状态
.duration(500) // 持续时间
.iterations(-1) // 播放次数
.width(300)
.height(200)
Row() {
Button('启动')
.onClick(()=>{
this.state = AnimationStatus.Running //播放
})
Button('暂停')
.onClick(()=>{
this.state = AnimationStatus.Paused //暂停:停在触发的瞬间
})
Button('停止')
.onClick(()=>{
this.state = AnimationStatus.Stopped //停止:直接到最后一张图
})
}
}
.width('100%')
.height('100%')
}
}