HarmonyOS学习 - ui动画
·
我最近用 ArkUI-X 实现了一组 "会跳舞的 UI",从弹性按钮到双人舞组合动画,让组件们灵活起来
包含功能:
✅ 弹性按钮:点击后像弹簧一样回弹
✅ 图片缩放:加载时自动收缩表演
✅ 路径动画:图标沿着自定义路线 "蛇形走位"
✅ 旋转文字:360° 旋转停不下来
✅ 组动画:按钮集体跳机械舞
✅ 双人舞:图片与文字同步旋转平移
踩坑指南:动画开发避坑三要素
-
状态管理:
- ❌ 错误做法:直接修改样式属性(如
.rotate(360)) - ✅ 正确姿势:通过
@State变量控制,ArkUI-X 会自动触发动画
- ❌ 错误做法:直接修改样式属性(如
-
路径坐标:
- ❌ 错误写法:
path: 'Mstart.x start.y...'(未定义变量) - ✅ 正确示例:
path: 'M0 0 L300 200 L300 500 L500 500'
- ❌ 错误写法:
-
性能优化:
- 使用
Curve曲线(如EaseInOut)替代线性动画 - 复杂动画建议用
AnimatorGroup分组控制
- 使用
直接上代码:
@Entry
@Component
struct ArkUIXAnimationExample {
@State isButtonScaled: boolean = false
@State imgScaleValue: number = 1
@State rotationAngle: number = 0
@State pathProgress: number = 0
@State toggle: boolean = true
@State isTextRotating: boolean = false
@State isTextAnimated: boolean = false
build() {
Column({ space: 50 }) {
// 弹性按钮
Button('点我试试')
.width(150)
.height(50)
.scale({
x: this.isButtonScaled ? 1.2 : 1,
y: this.isButtonScaled ? 1.2 : 1
})
.animation({
duration: 800,
curve: Curve.EaseInOut
})
.onClick(() => {
animateTo({ duration: 200 }, () => {
this.isButtonScaled = !this.isButtonScaled
})
})
// 图片缩放
Image($rawfile('home/poster1.png'))
.width(200)
.height(200)
.scale({ x: this.imgScaleValue, y: this.imgScaleValue })
.animation({
duration: 600,
curve: Curve.Linear,
delay: 200
})
.onAppear(() => {
this.imgScaleValue = 0.8
})
// 路径动画
Button('click me').margin(50)
.motionPath({
path: 'Mstart.x start.y L300 200 L300 500 Lend.x end.y',
from: 0.0,
to: 1.0,
rotatable: true
}) // 执行动画:从起点移动到(300,200),再到(300,500),再到终点
.onClick(() => {
animateTo({ duration: 4000, curve: Curve.Linear }, () => {
this.toggle = !this.toggle // 通过this.toggle变化组件的位置
})
})
// 旋转文字
Button('旋转文字')
.fontSize(18)
.rotate({ angle: this.isTextRotating? 360 : 0 })
.animation({
duration: 3000,
curve: Curve.EaseInOut,
iterations: Infinity,
playMode: PlayMode.Normal
})
.onClick(() => {
this.isTextRotating = true
})
// 按钮组动画
Row() {
ForEach(['按钮1', '按钮2', '按钮3'], (label: string, index: number) => {
Button(label)
.width(100)
.height(50)
.translate({ x: index * 120 })
.rotate({ angle: 30 * index })
.animation({
duration: 1000 + index * 200,
curve: Curve.EaseInOut
})
})
}
// 组合动画
Stack({ alignContent: Alignment.Center }) {
Image($rawfile('home/poster3.png'))
.width(150)
.height(150)
.rotate({ angle: this.isTextAnimated? 180 : 0 })
.animation({
duration: 2000,
curve: Curve.Ease,
playMode: PlayMode.Normal
})
Text('伴舞文字')
.fontSize(20)
.translate({ x: this.isTextAnimated? -50 : 0 })
.animation({
duration: 2000,
curve: Curve.Ease,
playMode: PlayMode.Normal
})
.onClick(() => {
this.isTextAnimated = !this.isTextAnimated
})
}
}
.width('100%').alignItems(this.toggle ? HorizontalAlign.Start : HorizontalAlign.Center)
}
}
更多推荐


所有评论(0)