本篇内容:动画的学习使用
一、 知识储备
1. 布局更新动画
- 包含显式动画(animateTo)和属性动画(animation)
动画类型名称 |
特点 |
显式动画 |
闭包内的变化都会触发动画执行, 可以做较复杂的动画 |
属性动画 |
属性变化时触发动画执行, 设置简单 |
说白了,显示动画就是靠闭包事件触发,属性动画是挂在组件身上的属性变化触发
- 显式动画 可以通过修改组件的布局方式、宽高、位置触发动画
animateTo({ duration: 1000, curve: Curve.Ease }, () => {
// 动画闭包中根据标志位改变控制第一个Button宽高的状态变量,使第一个Button做宽高动画
if (this.flag) {
this.myWidth = 100;
this.myHeight = 50;
} else {
this.myWidth = 200;
this.myHeight = 100;
}
this.flag = !this.flag;
});
Image($r('app.media.ic_hm_logo'))
.width(160)
.height(160)
.alignRules({
top: { anchor: '__container__', align: VerticalAlign.Top },
right: { anchor: '__container__', align: this.itemAlign }
})
.margin({ top: this.mTop, right: 35 })
.id('logo')
.animation({ duration: 1000, curve: Curve.Ease }) //animation只对上面的设置生效
.onClick(() => {
this.mTop = 111
})
2. 组件内转场动画(transition)
Button() //删除插入同一个动画
.transition({ type: TransitionType.All, scale: { x: 0, y: 0 } })
Button()//删除插入不同动画
.transition({ type: TransitionType.Insert, translate: { x: 200, y: -200 }, opacity: 0 })
.transition({ type: TransitionType.Delete, rotate: { x: 0, y: 0, z: 1, angle: 360 } })
3. 弹簧曲线动画
- 分为两类,一个springCurve,一个springMotion和responsiveSpringMotion。
- springCurve
springCurve(velocity: number, mass: number, stiffness: number, damping: number)
//velocity: 初速度
//mass:弹簧系统的质量
//stiffness:弹簧系统的刚度
//damping:弹簧系统的阻尼
- springMotion和responsiveSpringMotion。此动画适合跟手动画,duration设置无效。跟手过程推荐使用responsiveSpringMotion,松手时使用springMotion
springMotion(response?: number, dampingFraction?: number, overlapDuration?: number)
responsiveSpringMotion(response?: number, dampingFraction?: number, overlapDuration?: number)
//response:可选参数 弹簧自然振动周期
//dampingFraction:可选参数阻尼系数
//overlapDuration:可选参数弹性动画衔接时长
- 注意: springCurve可以设置初速度,单一属性存在多个动画时,可以正常叠加动画效果。springMotion,由于开发者不可修改速度机制,所以在单一属性存在多个动画时,后一动画会取代前一动画。并继承前一动画的速度
.onTouch(event => {
if (event.type == TouchType.Move) {
animateTo({ curve: curves.responsiveSpringMotion() }, () => {
this.mRight = event.touches[0].screenX - 80;
})
} else if (event.type == TouchType.Up) {
animateTo({curve: curves.springMotion()}, ()=>{
this.mRight = 35;
})
}
})
4. 放大缩小动画
- sharedTransition,
- Exchange类型的共享元素转场动画,就是前后两个页面都设置有相同id的动画,那么转场时,将会自动触发缩放动画
.sharedTransition('sharedTransition', { duration: 1000, curve: Curve.Linear })
- Static类型的共享元素转场动画, 只需要在一个页面设置即可,在转换页面时自动触发透明度从0到该组件原设定的的透明度的动画。位置等其他属性不变
.sharedTransition('input', { duration: 500, curve: Curve.Linear, type: SharedTransitionEffectType.Static })
5. 页面转场动画
- 页面转场切换时,效果触发在页面上,在pageTransition函数中设置PageTransitionEntert和PageTransitionExit动画
PageTransitionEnter({type?: RouteType,duration?: number,curve?: Curve | string,delay?: number})
PageTransitionExit({type?: RouteType,duration?: number,curve?: Curve | string,delay?: number})
//type:默认是RouteType.None表示对页面栈的push和pop操作均生效,
//duration: 动画时长
//curve: 动画效果
//delay: 动画延时
转场动画设置
pageTransition() {
PageTransitionEnter({ type: RouteType.Push, duration: 1000, })
.slide(SlideEffect.Right)
PageTransitionEnter({ type: RouteType.Pop, duration: 1000, })
.slide(SlideEffect.Left)
PageTransitionExit({type: RouteType.Push, duration: 1000})
.slide(SlideEffect.Left)
PageTransitionExit({type: RouteType.Pop, duration: 1000})
.slide(SlideEffect.Right)
}
二、 效果一览

三、 源码剖析
import promptAction from '@ohos.promptAction';
import picker from '@ohos.file.picker';
import thermal from '@ohos.thermal';
import router from '@ohos.router';
import curves from '@ohos.curves';
@Component
@Entry
struct LoginPage {
@State account: string = '';
@State password: string = '';
dialog: CustomDialogController = new CustomDialogController({
builder: TipDialog({
cancel: this.onCancel,
commit: this.onCommit,
msg: this.account
}),
alignment: DialogAlignment.Center
});
onCancel() {
pr