HarmonyOS鸿蒙Next中如何实现呼吸灯动画效果?
HarmonyOS鸿蒙Next中如何实现呼吸灯动画效果? 如何实现呼吸灯动画效果?
3 回复
效果

实现思路
- 完成页面布局
- Circle组件增加scale属性
- 点击事件后,通过animateTo更改scale属性响应式数据值
完整代码
@Builder
export function MainPageBuilder() { // 细节2:按照这个格式配置
Listen()
}
@Component
struct Listen {
@StorageProp('bottomRectHeight') bottomRectHeight: number = 0;
@StorageProp('topRectHeight') topRectHeight: number = 0;
@State isRecognize: boolean = false
@State circleScaleIn: number = 1
@State circleScaleOut: number = 1
@Consume navPathStack: NavPathStack
build() {
NavDestination() {
Column() {
Row() {
Image($r('app.media.ai_listen_left')).width(30).margin({ left: 10 })
Text('听歌识曲').fontSize(16).fontWeight(600)
Image($r('app.media.ai_listen_gd')).width(30).margin({ right: 10 })
}
.width('100%')
.justifyContent(FlexAlign.SpaceBetween)
.onClick(() => this.navPathStack.pushPathByName('AiListen', null))
Row() {
Text('开启桌面悬浮球,边刷视频边识曲').fontColor(Color.Gray).margin({ left: 20 })
Toggle({ type: ToggleType.Switch, isOn: false })
.selectedColor('#007DFF')
.switchPointColor('#FFFFFF')
.onChange((isOn: boolean) => {
console.info('Component status:' + isOn)
}).margin({ right: 20 })
}
.backgroundColor('#d9e8fc')
.justifyContent(FlexAlign.SpaceBetween)
.width('100%')
.height(40)
.margin({ top: 10, bottom: 20 })
Column({ space: 40 }) {
Stack() {
Circle({ width: 200, height: 200 })
.stroke('#dce9fb')
.strokeWidth(30)
.fill('none')
.scale({ x: this.circleScaleOut, y: this.circleScaleOut })
Circle({ width: 200, height: 200 })
.fill(this.isRecognize ? '#0783ff' : '#c1dbfc')
.scale({ x: this.circleScaleIn, y: this.circleScaleIn })
Image(this.isRecognize ? $r('app.media.ai_listen_logo_white') : $r('app.media.logo'))
.width(150)
.padding(15)
.borderRadius('50%')
.onClick(async () => {
// 特效
this.isRecognize = !this.isRecognize
if (this.isRecognize) {
animateTo({ duration: 500, iterations: -1, playMode: PlayMode.Alternate }, () => {
this.circleScaleIn = 0.85
})
animateTo({ duration: 1000, iterations: -1, curve: Curve.EaseInOut }, () => {
this.circleScaleOut = 0.85
})
} else {
animateTo({ duration: 0 }, () => {
this.circleScaleIn = 1
this.circleScaleOut = 1
})
}
})
}
Text('点击开始识曲')
.fontWeight(700)
.fontSize(19)
.fontColor('#575757')
}.margin({ top: 40, bottom: 230 }).alignItems(HorizontalAlign.Center)
Row() {
Text('听歌识曲榜')
.border({ width: { right: 2 }, color: Color.Gray })
.width(100)
.margin({ right: 15, left: 20 })
.fontColor('#4487f5')
.fontWeight(700)
Text('第57次取消发送-菲菲公主')
.fontColor(Color.Gray)
.fontSize(14)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.maxLines(1)
.width(160)
Image($r('app.media.ai_listen_chevron_right'))
.fillColor(Color.Gray)
.width(10)
.margin({ right: 10 })
}.backgroundColor('#f3f4fc').height(40).borderRadius(30).width('90%')
}.padding({ top: px2vp(this.topRectHeight) })
.linearGradient({ direction: GradientDirection.Bottom, colors: [['#d7e7ff', 0], ['#fff', 0.6]] })
}.hideTitleBar(true)
}
}
更多关于HarmonyOS鸿蒙Next中如何实现呼吸灯动画效果?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS Next中,实现呼吸灯动画效果主要使用ArkTS的动画API。通过animateTo方法或属性动画,改变组件的透明度(opacity)或缩放比例(scale),并设置curve为Curves.EaseInOut来模拟呼吸的平滑节奏。关键是在动画配置中循环播放(设置iterations为-1)并交替反向(设置alternate为true),即可实现明暗循环变化的呼吸效果。
在HarmonyOS Next中,实现呼吸灯动画效果的核心是使用ArkUI的动画API,特别是属性动画。以下是两种主流且简洁的实现方案:
方案一:使用显式动画(animateTo)
这是最直接的方法,通过animateTo函数控制组件的透明度(opacity)或尺寸(scale)等属性,在两种状态间循环过渡,模拟呼吸效果。
示例代码(基于ArkTS):
import { animateTo } from '@kit.ArkUI';
@Entry
@Component
struct BreathLightDemo {
@State opacityValue: number = 0.2; // 初始透明度
build() {
Column() {
// 需要呼吸的组件,例如一个圆形灯
Circle({ width: 100, height: 100 })
.fill(Color.Red)
.opacity(this.opacityValue) // 绑定透明度
.onClick(() => {
this.startBreathAnimation();
})
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
// 启动呼吸动画
private startBreathAnimation() {
// 从暗到亮(透明度增加)
animateTo({
duration: 1000, // 动画时长1秒
curve: Curve.EaseInOut, // 缓动曲线使过渡更自然
iterations: -1, // 无限循环
playMode: PlayMode.Alternate // 交替反向播放
}, () => {
this.opacityValue = 1.0; // 目标透明度
});
}
}
关键点:
iterations: -1设置动画无限循环。playMode: PlayMode.Alternate使动画在起点和终点间自动往返,形成“呼吸”节奏。- 通过调整
duration和curve可控制呼吸速度和平滑度。
方案二:使用属性动画(animation)
通过组件的animation方法定义属性动画,实现更精细的控制。
示例代码:
@Entry
@Component
struct BreathLightDemo2 {
@State scaleValue: number = 0.8;
build() {
Column() {
Circle({ width: 100, height: 100 })
.fill(Color.Blue)
.scale({ x: this.scaleValue, y: this.scaleValue }) // 绑定缩放属性
.animation({
duration: 1500,
curve: Curve.EaseInOut,
iterations: -1,
playMode: PlayMode.Alternate
})
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
.onClick(() => {
// 点击触发状态改变,动画自动执行
this.scaleValue = this.scaleValue === 0.8 ? 1.2 : 0.8;
})
}
}
关键点:
- 将
animation修饰符直接附加到组件,当绑定的状态变量(如scaleValue)变化时自动触发动画。 - 可通过修改
scale(缩放)或opacity(透明度)等属性实现不同视觉效果。
方案选择建议
- 简单场景:使用方案一(
animateTo),代码控制逻辑更集中。 - 复杂交互:使用方案二(
animation),将动画声明与组件绑定,响应状态变化更灵活。
两种方案均能高效实现平滑的呼吸灯效果,且性能开销低。可根据具体UI交互需求选择。

