【高心星出品】
属性动画
属性接口(以下简称属性)包含尺寸属性、布局属性、位置属性等多种类型,用于控制组件的行为。针对当前界面上的组件,其部分属性(如位置属性)的变化会引起 UI 的变化。添加动画可以让属性值从起点逐渐变化到终点,从而产生连续的动画效果。
animateTo 属性动画
通用函数,对闭包前界面和闭包中的状态变量引起的界面之间的差异做动画。
支持多次调用,支持嵌套。
animateTo(value: AnimateParam, event: () => void): void
复制代码
animateTo 接口参数中,value 指定 AnimateParam 对象(包括时长、Curve 等)event 为动画的闭包函数,闭包内变量改变产生的属性动画将遵循相同的动画参数。
案例:
点击按钮红色块旋转 90 度,绿色块向下平移 100 并且透明度改变为半透明。
代码:
import curves from '@ohos.curves'
@Entry
@Component
struct PropAnimation {
@State animate: boolean = false;
// 第一步: 声明相关状态变量
@State rotateValue: number = 0; // 组件一旋转角度
@State translateY: number = 0; // 组件二偏移量
@State opacityValue: number = 1; // 组件二透明度
// 第二步:将状态变量设置到相关可动画属性接口
build() {
Column() {
// 组件一
Column() {
this.CommonText()
}
.ColumnStyle()
.backgroundColor(0xf56c6c)
.rotate({ angle: this.rotateValue })
// 组件二
Column() {
this.CommonText()
}
.ColumnStyle()
.backgroundColor(0x67C23A)
.opacity(this.opacityValue)
.translate({ y: this.translateY })
Button('Click')
.margin({ top: 120 })
.onClick(() => {
this.animate = !this.animate;
// 第三步:通过属性动画接口开启属性动画
animateTo({ curve: curves.springMotion() }, () => {
// 第四步:闭包内通过状态变量改变UI界面
// 这里可以写任何能改变UI的逻辑比如数组添加,显隐控制,系统会检测改变后的UI界面与之前的UI界面的差异,对有差异的部分添加动画
// 组件一的rotate属性发生变化,所以会给组件一添加rotate旋转动画
this.rotateValue = this.animate ? 90 : 0;
// 组件二的scale属性发生变化,所以会给组件二添加scale缩放动画
this.opacityValue = this.animate ? 0.6 : 1;
// 组件二的offset属性发生变化,所以会给组件二添加offset偏移动画
this.translateY = this.animate ? 100 : 0;
})
})
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
@Builder
CommonText() {
Text('ArkUI')
.fontWeight(FontWeight.Bold)
.fontSize(20)
.fontColor(Color.White)
}
}
@Extend(Column)
function ColumnStyle() {
.justifyContent(FlexAlign.Center)
.width(150)
.height(150)
.borderRadius(10)
}
复制代码
animation 属性动画
相比于 animateTo 接口需要把要执行动画的属性的修改放在闭包中,animation 接口无需使用闭包,把 animation 接口加在要做属性动画的可动画属性后即可。animation 只要检测到其绑定的可动画属性发生变化,就会自动添加属性动画,animateTo 则必须在动画闭包内改变可动画属性的值从而生成动画。
animation(value:AnimateParam)
复制代码
组件的某些通用属性变化时,可以通过属性动画实现渐变过渡效果,提升用户体验。支持的属性包括 width、height、backgroundColor、opacity、scale、rotate、translate 等。布局类改变宽高的动画,内容都是直接到终点状态,例如文字、Canvas 的内容等,如果要内容跟随宽高变化,可以使用 renderFit 属性配置。
案例:
点击按钮红色块向左平移并且顺时针旋转 90°,绿色块向右平移且逆时针旋转 90°,且文字颜色变为黑色。
代码:
import curves from '@ohos.curves';
@Entry
@Component
struct AnimationDemo {
@State animate: boolean = false;
// 第一步: 声明相关状态变量
@State rotateValue: number = 0; // 组件一旋转角度
@State translateX: number = 0; // 组件二偏移量
@State translateXX:number=0;//组件一平移
@State rotateValuee: number = 0; // 组件二旋转角度
@State color: Color = Color.White; // 组件二字体颜色
// 第二步:将状态变量设置到相关可动画属性接口
build() {
Column() {
Column() {
// 组件一
Text('ArkUI')
.textStyle()
.backgroundColor(0xf56c6c)
.fontColor(Color.White)
.rotate({ angle: this.rotateValue })// 第三步:通过属性动画接口开启属性动画,控件的函数调用顺序是从下往上的,这个animation会作用到上面的rotate属性
.translate({x:this.translateXX})
.animation({ curve: curves.springMotion() })
// 组件二
Text('ArkUI')
.textStyle()
.backgroundColor(0x67C23A)
.fontColor(this.color)// 第三步:通过属性动画接口开启属性动画,控件的函数调用顺序是从下往上的,这个animation会作用到上面的fontColor属性
.animation({ curve: curves.springMotion() })
.translate({ x: this.translateX })// 第三步:通过属性动画接口开启属性动画,控件的函数调用顺序是从下往上的,这个animation会作用到上面的translate属性
.rotate({angle:this.rotateValuee})
.animation({ curve: curves.springMotion() })
}
.justifyContent(FlexAlign.Center)
// 第四步:通过状态变量改变UI界面,系统会检测改变后的UI界面与之前的UI界面的差异,对有差异的部分添加动画
Button('Click')
.margin({ top: 120 })
.onClick(() => {
this.animate = !this.animate;
// 组件一的rotate属性有变化,所以会给组件一加rotate动画
this.rotateValue = this.animate ? 90 : 0;
this.rotateValuee = this.animate ? -90 : 0;
// 组件二的translate属性有变化,所以会给组件二加translate动画
this.translateX = this.animate ? 100 : 0;
this.translateXX = this.animate ? -100 : 0;
// 组件二的fontColor属性有变化,所以会给组件二加fontColor动画
this.color = this.animate ? Color.Black : Color.White;
})
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
@Extend(Text)
function textStyle() {
.fontWeight(FontWeight.Bold)
.fontSize(20)
.textAlign(TextAlign.Center)
.borderRadius(10)
.width(150)
.height(150)
}
复制代码
评论