动画
动画是页面中非常常见的一种页面效果,可以使得页面更加生动有趣。
Harmonyos提供了多种动画模式,主要分为以下四种:
一、属性动画
二、显示动画
三、转场动画
四、路径动画
效果图:
实现一个类似加载等待阶段的动画
属性动画:
组件的某些通用属性变化时,可以通过属性动画实现渐变过渡效果,提升用户体验。
// xxx.ets
@Entry
@Component
struct AttrAnimationExample {
@State rotateAngle: number = 0
@State flag: boolean = true
build() {
Column() {
Image($r('app.media.rotate'))
.onClick(() => {
this.rotateAngle = 360
})
.margin(50)
.width(100)
.rotate({ angle: this.rotateAngle })
.animation({
duration: 500,
curve: Curve.Linear,//动画曲线
tempo:0.5,
// delay: 500,//延迟执行
iterations: -1, // 设置-1表示动画无限循环
playMode: PlayMode.Normal//动画播放模式
})
}.width('100%').margin({ top: 20 })
}
}
属性动画设置的一般代码如下:
Text('^-^')
.position({
x:10,
y:0
})//设置x轴y轴坐标
.rotate({
angle:0, //旋转角度
centerX:'50%', //旋转中心横坐标
centerY:'50%' //旋转中心纵坐标
})
.animation({
duration:1000,
curve:Curve.EaseInOut
})
position和rotate的作用是:设置初始的旋转系数、x轴y轴坐标。
animation是实现属性动画效果最重要的部分,duration是设置动画时长,curve是设置动画曲线,除了这两个属性还有其他属性可以让使用者更加个性化地对动画进行设置。需要注意的是,animation要放在样式属性最后,且支持的属性包括width、height、backgroundColor、opacity、scale、rotate、translate等,其他的属性有些是不支持的。
那么实现动画的原理是什么呢?
原理是监控样式属性,如position或rotate中的属性发生变化时,则会触发动画效果。HarmonyOS会自动填充中间的样式。如设置初始x为0,点击后修改x为200,那么会自动补充0~200这个过程中的动画效果,不会突兀的瞬闪出现。
显式动画:
提供全局animateTo显式动画接口来指定由于闭包代码导致的状态变化插入过渡动效。
// xxx.ets
@Entry
@Component
struct AnimateToExample {
@State rotateAngle: number = 0
private flag: boolean = true
build() {
Column() {
Image($r('app.media.rotate'))
.width(100)
.margin(50)
.rotate({ x: 0, y: 0, z: 1, angle: this.rotateAngle })
.onClick(() => {
animateTo({
duration: 500,
curve: Curve.Friction,
delay: 500,
tempo:0.5,
iterations: -1, // 设置-1表示动画无限循环
playMode: PlayMode.Normal,
onFinish: () => {
console.info('play end')
}
}, () => {
this.rotateAngle = 360
})
})
}.width('100%').margin({ top: 5 })
}
}
属性动画中实现动画效果最重要的部分是animation属性,而显式动画则是使用animateTo函数。
animateTo的使用形式如下:
animateTo(
{duration:1000},//动画参数
()=>{
//修改组件属性关联的状态变量
}
)
animateTo函数是由两部分组成的,第一部分是适合animation中相同的动画参数,动画时长,动画速度等,第二部分是一个箭头函数,函数中存放修改后的变量。显式动画能够实现就是监控了函数中修改的变量,当发现这些变量发生变化时,就会触发动画效果。
属性动画与显式动画的监控区别:属性动画监视的是animation前面的样式属性,而显式动画显示的是animateTo中箭头函数中的状态变量(样式属性)。二者监视的对象和范围不同。
转场动画:
效果图:
实现图片组件出现和隐藏的转场动画
代码实现:
// xxx.ets
@Entry
@Component
struct TransitionExample {
@State flag: boolean = true
@State show: string = 'hide'
build() {
Column() {
Button(this.show).width(80).height(30).margin(30)
.onClick(() => {
// 点击Button控制Image的显示和消失
animateTo({ duration: 1000 }, () => {
if (this.flag) {
this.show = 'show'
} else {
this.show = 'hide'
}
this.flag = !this.flag
})
})
if (this.flag) {
// Image的显示和消失配置为不同的过渡效果
Image($r('app.media.mateBookProX')).width(300).height(300)
.transition({ type: TransitionType.Insert, scale: { x: 5.0, y: 5.0 } })
.transition({ type: TransitionType.Delete, rotate: { angle: 180 } })
}
}.width('100%')
}
}
本案例是组件转场动画的一个案例,组件内转场主要通过transition属性配置转场参数,在组件插入和删除时显示过渡动效,主要用于容器组件中的子组件插入和删除时。需要注意的是:组件转场动画需要配合animateTo才能生效,动效时长、曲线、延时跟随animateTo中的配置。
transition属性中可以配置如type(设置组件新增和删除时出现动画)、translate(设置组件转场时的平移效果)、scale(设置组件转场时的缩放效果)等。可以实现自定义组件转场的动画效果的设置,可以设置新增删除相同或者不同的效果。
路径动画:
效果图:
实现让小鱼沿着我们设定的路径进行运动
代码实现:
// xxx.ets
@Entry
@Component
struct MotionPathExample {
@State toggle: boolean = true
build() {
Column() {
Image($r('app.media.fish'))
.margin(50)
.width(80)
// 执行动画:从起点移动到(300,200),再到(300,500),再到终点
.motionPath({ path: 'Mstart.x start.y L300 200 L300 500 L800 800 Lend.x end.y', from: 0.0, to: 1.0, rotatable: true })
.onClick(() => {
animateTo({ duration: 4000, curve: Curve.Linear }, () => {
this.toggle = !this.toggle // 通过this.toggle变化组件的位置
})
})
}
.width('100%')
.height('100%')
.alignItems(this.toggle ? HorizontalAlign.Start : HorizontalAlign.End)
// .justifyContent(this.toggle ? FlexAlign.Start : FlexAlign.End)
}
}
本案例是一个简单的路径动画案例,可以设置组件进行位移动画时的运动路径。
与上面三个相同,路径动画也有一个主要的属性,为motionPath属性。使用者可以在这个属性中设置起点终点,途经点等,同样的,harmonyos会自动填补中间的过程。设置路径的大致代码如下:
.motionPath({ path: 'Mstart.x start.y L300 200 L300 500 L800 800 Lend.x end.y', from: 0.0, to: 1.0, rotatable: true })
Mstart.x和start.y设置的就是动画起始点,路径点和终点以L开头,途经点可以在L后添加具体的位置信息,终点则是在L后加end.x和end.y。
终点和起点的位置的设置,我个人是有点没太搞明白。本案例中是利用一个boolean类型,然后用三元运算符来设置alignItems的样式以达到起点和终点的设置。