鸿蒙NEXT开发动画案例3
1.创建空白项目
2.Page文件夹下面新建Spin.ets文件,代码如下:
// ===== 接口定义(必须放在使用前)===== interface KeyframeAnimationConfig {iterations: number;delay: number; }interface KeyframeState {duration: number;curve?: Curve;event: () => void; } // ===== 接口定义结束 =====/*** TODO SpinKit动画组件* author: 鸿蒙布道师* since: 2025/05/07*/ @ComponentV2 export struct SpinThree {// 参数定义@Require @Param spinSize: number = 48;@Require @Param spinColor: ResourceColor = '#209ED8';// 动画状态@Local scale1: number = 0.4;@Local scale2: number = 0.4;@Local scale3: number = 0.4;@Local scale4: number = 0.4;@Local scale5: number = 0.4;build() {Row() {Canvas().chunkStyle().scale({ y: this.scale1 })Canvas().chunkStyle().scale({ y: this.scale2 })Canvas().chunkStyle().scale({ y: this.scale3 })Canvas().chunkStyle().scale({ y: this.scale4 })Canvas().chunkStyle().scale({ y: this.scale5 })}.width(this.spinSize).height(this.spinSize * 0.8).onAppear(() => {this.startAnimations();});}/*** 启动所有子动画*/private startAnimations(): void {const uiContext = this.getUIContext();if (!uiContext) return;const ANIMATION_DELAY_INTERVAL = 100; // 每个动画延迟间隔for (let i = 1; i <= 5; i++) {const keyframes = this.createKeyframes(i);const delay = -1100 + (i - 1) * ANIMATION_DELAY_INTERVAL;uiContext.keyframeAnimateTo({ iterations: -1, delay },keyframes);}}/*** 根据索引创建对应的关键帧动画* @param index - 第几个动画(1~5)*/private createKeyframes(index: number): Array<KeyframeState> {const updateScale = (value: number) => {switch (index) {case 1: this.scale1 = value; break;case 2: this.scale2 = value; break;case 3: this.scale3 = value; break;case 4: this.scale4 = value; break;case 5: this.scale5 = value; break;}};return [{duration: 240,curve: Curve.EaseInOut,event: ():void => updateScale(1),},{duration: 240,curve: Curve.EaseInOut,event: ():void => updateScale(0.4),},{duration: 720,event: () => {},}];}/*** 公共样式封装*/@StyleschunkStyle() {.height('100%').width('14%').margin({ left: '3%', right: '3%' }).backgroundColor(this.spinColor).shadow(ShadowStyle.OUTER_DEFAULT_XS)} }
代码如下:
// ===== 接口定义(必须放在使用前)=====
interface KeyframeAnimationConfig {iterations: number;delay: number;
}interface KeyframeState {duration: number;curve?: Curve;event: () => void;
}
// ===== 接口定义结束 =====/*** TODO SpinKit动画组件* author: 鸿蒙布道师* since: 2025/05/07*/
@ComponentV2
export struct SpinThree {// 参数定义@Require @Param spinSize: number = 48;@Require @Param spinColor: ResourceColor = '#209ED8';// 动画状态@Local scale1: number = 0.4;@Local scale2: number = 0.4;@Local scale3: number = 0.4;@Local scale4: number = 0.4;@Local scale5: number = 0.4;build() {Row() {Canvas().chunkStyle().scale({ y: this.scale1 })Canvas().chunkStyle().scale({ y: this.scale2 })Canvas().chunkStyle().scale({ y: this.scale3 })Canvas().chunkStyle().scale({ y: this.scale4 })Canvas().chunkStyle().scale({ y: this.scale5 })}.width(this.spinSize).height(this.spinSize * 0.8).onAppear(() => {this.startAnimations();});}/*** 启动所有子动画*/private startAnimations(): void {const uiContext = this.getUIContext();if (!uiContext) return;const ANIMATION_DELAY_INTERVAL = 100; // 每个动画延迟间隔for (let i = 1; i <= 5; i++) {const keyframes = this.createKeyframes(i);const delay = -1100 + (i - 1) * ANIMATION_DELAY_INTERVAL;uiContext.keyframeAnimateTo({ iterations: -1, delay },keyframes);}}/*** 根据索引创建对应的关键帧动画* @param index - 第几个动画(1~5)*/private createKeyframes(index: number): Array<KeyframeState> {const updateScale = (value: number) => {switch (index) {case 1: this.scale1 = value; break;case 2: this.scale2 = value; break;case 3: this.scale3 = value; break;case 4: this.scale4 = value; break;case 5: this.scale5 = value; break;}};return [{duration: 240,curve: Curve.EaseInOut,event: ():void => updateScale(1),},{duration: 240,curve: Curve.EaseInOut,event: ():void => updateScale(0.4),},{duration: 720,event: () => {},}];}/*** 公共样式封装*/@StyleschunkStyle() {.height('100%').width('14%').margin({ left: '3%', right: '3%' }).backgroundColor(this.spinColor).shadow(ShadowStyle.OUTER_DEFAULT_XS)}
}
3.修改Index.ets文件,代码如下:
import { SpinThree } from './Spin';@Entry @Component struct Index {@State message: string = 'Hello World';build() {Column() {SpinThree({spinSize: 60,spinColor: '#FF0000'})}.alignItems(HorizontalAlign.Center).justifyContent(FlexAlign.Center).height('100%').width('100%')} }
代码如下:
import { SpinThree } from './Spin';@Entry
@Component
struct Index {@State message: string = 'Hello World';build() {Column() {SpinThree({spinSize: 60,spinColor: '#FF0000'})}.alignItems(HorizontalAlign.Center).justifyContent(FlexAlign.Center).height('100%').width('100%')}
}
4.运行项目,登录华为账号,需进行签名
5.动画效果如下: