#2023盲盒+码# 熟悉一下服务卡片新的动画能力 原创
【本文正在参加 2023「盲盒」+码有奖征文活动】,活动链接 https://ost.51cto.com/posts/25284
前言
随着不同版本HarmonyOS发布,服务卡片的能力也经历了几次变革,从最开始的只支持JS语言,到后来增加了对ArKTS语言的基础支持,现在又丰富了ArkTS动画的效果。对服务卡片增加动画效果,是个比较小众的概念,用好它会锦上添花,没有它无伤大雅,有它用不好反而画蛇添足,既然有了这个功能,就努力去了解一下它,想不出具体可以用到哪里,就做一个无聊的切换卡片吧。
ArkTS卡片开放了使用动画效果的能力,支持显式动画、属性动画、组件内转场动画,我们就通过一个小示例简单熟悉一下它们的具体用法,这个示例主要功能是,用户点击卡片,会来回切换为白天场景和夜晚场景,白天场景太阳会自动旋转,夜晚场景星星会自动闪烁。
效果预览
显式动画
animateTo,是显式动画接口,用来指定由于闭包代码导致的状态变化插入过渡动效。
示例中的星星动画,就是采用的显式动画,
Image($r('app.media.star'))
.width('5%')
.height('5%')
.margin({ top: 40, left: 20 })
.opacity(this.opacityValue + 0.3)
.onAppear(() => {
animateTo({
curve: Curve.EaseInOut,
playMode: PlayMode.AlternateReverse,
onFinish: () => {
this.opacityValue = 0.7;
}
}, () => {
this.opacityValue = 0.2;
})
})
opacityValue 初始值是 1,
@State opacityValue: number = 1;
闭包代码对this.opacityValue赋值为0.2,很显然导致了opacityValue状态变化,所以系统会自动插入过度动画,有了闪一下的效果。
属性动画
animation,这个属性是组件属性动画实现,组件的某些通用属性变化时,可以通过属性动画实现渐变过渡效果,支持的属性包括width、height、backgroundColor、opacity、scale、rotate、translate等。
示例中的太阳动画,就是采用的属性动画,
Image($r('app.media.sun'))
.width('40%')
.height('40%')
.margin(10)
.rotate({ angle: this.rotateAngle })
.animation({
curve: Curve.EaseInOut,
playMode: PlayMode.AlternateReverse,
onFinish: () => {
this.rotateAngle = 0;
}
})
.onAppear(() => {
this.rotateAngle = 180;
})
rotateAngle 的初始值为0,
@State rotateAngle: number = 0;
当控件显示时,值变为180,这样系统也会自动加入渐变过渡效果,太阳就转起来了。
转场动画
转场动画主要通过transition属性配置转场参数,在组件插入和删除时显示过渡动效,主要用于容器组件中的子组件插入和删除时,显示动画效果。
示例中的白天黑夜切换,是采用的转场动画,
@Builder DayCard() {
Stack() {
Image($r('app.media.daybg'))
.width('100%')
.height('100%')
Image($r('app.media.sun'))
.width('40%')
.height('40%')
.margin(10)
}
.alignContent(Alignment.TopStart)
.transition({ type: TransitionType.Insert, opacity: 0 })
.transition({ type: TransitionType.Delete, opacity: 1 })
}
@Builder NightCard() {
Stack() {
Image($r('app.media.nightbg'))
.width('100%')
.height('100%')
Image($r('app.media.star'))
.width('5%')
.height('5%')
.margin({ top: 40, left: 20 })
}
.alignContent(Alignment.TopStart)
.transition({ type: TransitionType.Insert, opacity: 0 })
.transition({ type: TransitionType.Delete, opacity: 1 })
}
我们通过transition属性设置DayCard和NightCard在插入和删除时显示不同的透明度,实现过度效果,要激活动画,还需要在根容器的点击事件中修改isDay变量。
.onClick(() => {
animateTo({ duration: 8000 }, () => {
this.isDay = !this.isDay;
})
})
这样白天夜晚就可以平稳过渡了。
总结
服务卡片提供的这三种形式动画和页面中支持的动画都差不多,但也有一些限制,服务卡片中的动画时长、播放速度、延迟时间和播放次数都不支持设置,动画时长默认是1秒,无延迟并且只能播放一次,相信仅有的这些属性也足够开发者使用了。
服务卡片确实不太用得到太复杂的动画