动画/交互事件
回顾
再前面的文章中,首先从登录页开始,这一篇大概涉及到了基本UI搭建及http网络请求。第二篇中以应用首页为展开,
涉及到了更多UI方面的搭建,有底部导航栏,banner图,懒加载列表等。到第三篇,主要是上传/下载及WebView,这一部分
内容主要是作为应用我的部分经常会有的,比如头像上传,app更新,隐私协议等。此时就将应用登录,注册,首页,列表,我的等
页面主要功能部分就介绍完了。
接下来,是平常会用到的功能,即本地通知,广播,数据库持久化存储。
到这一篇,看点简单的东西,UI动画。
显示动画
定义属性,放在animationTo闭包中修改相应的属性值
animateTo({
duration: 1000,
curve: Curve.Ease // 低速开始 加快 结束前变慢
},() => {
if (this.flag) {
this.stackWidth = 200 // 修改控件宽高
this.stackHeight = 100
} else {
this.stackWidth = 400
this.stackHeight = 200
}
this.flag = !this.flag
})
属性动画
相较于显示动画,无需借助animationTo闭包修改属性 运用animation属性,再其之前设置的属性值发生变化时,会执行动画过度
Stack() {
Text('test animation')
.fontColor('#ffffff')
.fontSize(20)
}.alignContent(Alignment.Center)
.backgroundColor(this.bgColor)
.width(this.stackWidth)
.height(this.stackHeight)
.animation({duration: 3000,curve: Curve.Ease,delay: 1000,onFinish: () => {}}) // 颜色,宽高属性改变时,会执行动画
.translate({x: this.translateX}) // translateX变化不会执行动画
转场动画
组件内转场动画
由IF/ELSE控制的组件显示隐藏,ForEach列表元素个数的变化
为组件增加transition属性,通过animationTo控制开启动画
transition({type: TransitionType.All,translate: {x: -200,y: 200},opacity: 0})
type: 控制是显示(TransitionType.Insert)或隐藏(TransitionType.Delete)执行动画 针对显示动画,设置的translate,opacity为起始值,控件属性为结束值 针对隐藏动画,控件属性为起始值,设置的平移,透明度等为结束值 动画曲线由animationTo的curve参数决定
- 平移
x: 横向的平移距离 y: 纵向的平移距离 z: 竖向的平移距离
translate: {x: 200,y: -200,z: 200} - 缩放
x:横向放大倍数(或缩小比例) Y: 纵向放大倍数(或缩小比例) centerX、centerY指缩放中心点,centerX和centerY默认值是"50%"
scale: {x: 0,y: 0,centerX: 0,centerY: 0} - 透明度
取值范围: [0, 1]
opacity: 0 - 旋转
x,y,z: 横向,纵向,竖向的旋转向量
rotate: { x: 0,y: 0,z: 1,angle: 360,centerX: '50%',centerY: '50%' }
共享元素转场
不同页面,有使用相同的元素的场景,可以使用共享元素转场动画衔接 配置为相同id的组件,它们为共享元素。从起始页共享元素位置、大小过度到目标页的位置、大小
- A页面:
sharedTransition("sharedImage",{duration: 1000,curve: Curve.Linear}) // type 默认:SharedTransitionEffectType.Exchange - B页面:
sharedTransition("sharedImage",{duration: 1000,curve: Curve.Linear,type: SharedTransitionEffectType.Exchange})
SharedTransitionEffectType.Static 类型的共享元素转场。
- 只需要再一个页面配置
- 不能再两个页面中有相同的id
- 动画从透明度0过度到设定的值 起始页为设定的值到透明度0的变化
- 位置保持不变
sharedTransition("text",{curve: Curve.Linear,duration: 1000,type: SharedTransitionEffectType.Static})
页面间转场
两个页面跳转时,发生的页面专场效果。定义再pageTransition函数中。
pageTransition() {
// 定义页面进入动画 RouteType.Push type指定页面为入栈时的动画即执行router.pushUrl时。 当为出栈显示页面时,不执行该动画效果
PageTransitionEnter({ type: RouteType.Push,duration: 1000,curve: Curve.Linear })
.translate({x: -200,y: 100})
.onEnter((type: RouteType, progress: number) => {
console.log('enter::',type,progress)
})
// 定义页面退出动画 RouteType.Pop type指定页面为出栈即router.back时页面退出执行的动画。
PageTransitionExit({type: RouteType.Pop,duration: 1000,curve: Curve.Linear})
.slide(SlideEffect.Right)
.scale({x: 0,y: 0})
.opacity(0)
.onExit((type: RouteType, progress: number) => {
console.log('exit::',type,progress)
})
// None 表示对页面栈的push、pop操作均生效
PageTransitionEnter({ type: RouteType.None,duration: 1000,curve: Curve.Linear })
.translate({x: -200,y: 100})
}
注:通过设置页面转场的时长为0,可使该页面无页面转场动画
弹簧曲线动画
- springCurve 构造参数包括初速度,弹簧系统的质量、刚度、阻尼。
animateTo({duration: 2000,curve: curves.springCurve(200,1,3,1.2)},() => {
this.translateX = 0
})
- springMotion和responsiveSpringMotion
Circle({width: 50,height: 50})
.fill(Color.Blue)
.position({x: this.positionX,y: this.positionY})
.onTouch((event) => {
if (event.type == TouchType.Move) {
animateTo({curve: curves.responsiveSpringMotion(0.15,0.86,0.25)},() => {
this.positionY = event.touches[0].y
this.positionX = event.touches[0].x
})
} else if(event.type == TouchType.Up) {
animateTo({curve: curves.springMotion(0.55,0.825,0)},() => {
this.positionX = 20
this.positionY = 20
})
}
})