鸿蒙NEXT开发动画案例12
1.创建空白项目
2.Page文件夹下面新建Spin.ets文件,代码如下:
/*** TODO SpinKit - 十二点扩散动画组件* author: CSDN-鸿蒙布道师* since: 2025/05/20*/ @ComponentV2 export struct SpinTwelve {@Require @Param spinSize: number = 36; // 整体尺寸@Require @Param spinColor: ResourceColor; // 圆点颜色@Require @Param dotCount: number = 12; // 圆点数量,默认为12// 每个圆点大小@Local roundSize: number = this.spinSize * 0.14;// 每个圆点透明度数组@Local opacities: number[] = Array(this.dotCount).fill(0.3);aboutToAppear(): void {this.roundSize = this.spinSize * 0.14;}build() {Stack() {ForEach(range(0, this.dotCount), (index: number) => {Column() {Canvas().width(this.roundSize / 2).height(this.roundSize * 1.51).borderRadius(10).backgroundColor(this.spinColor).shadow(ShadowStyle.OUTER_DEFAULT_XS).opacity(this.opacities[index])}.width(this.roundSize).height('100%').rotate({ angle: index * (360 / this.dotCount) })});}.renderFit(RenderFit.CENTER).width(this.spinSize).height(this.spinSize).onAppear(() => {this.startAnimations();});}private startAnimations() {const totalDuration = 1200; // 总动画周期时间const delayStep = Math.floor(totalDuration / this.dotCount); // 自动计算延迟步长for (let i = 0; i < this.dotCount; i++) {const delay = -(i * delayStep); // 使用负数延迟制造交错效果const keyframes: KeyframeState[] = [{duration: 480,curve: Curve.Linear,event: () => {this.opacities[i] = 1;}},{duration: 720,curve: Curve.Linear,event: () => {this.opacities[i] = 0.3;}}];this.getUIContext().keyframeAnimateTo({ iterations: -1, delay: delay }, // -1 表示无限循环keyframes);}} }function range(start: number, end: number): number[] {const result: number[] = [];for (let i = start; i < end; i++) {result.push(i);}return result; }
代码如下:
/*** TODO SpinKit - 十二点扩散动画组件* author: CSDN-鸿蒙布道师* since: 2025/05/20*/
@ComponentV2
export struct SpinTwelve {@Require @Param spinSize: number = 36; // 整体尺寸@Require @Param spinColor: ResourceColor; // 圆点颜色@Require @Param dotCount: number = 12; // 圆点数量,默认为12// 每个圆点大小@Local roundSize: number = this.spinSize * 0.14;// 每个圆点透明度数组@Local opacities: number[] = Array(this.dotCount).fill(0.3);aboutToAppear(): void {this.roundSize = this.spinSize * 0.14;}build() {Stack() {ForEach(range(0, this.dotCount), (index: number) => {Column() {Canvas().width(this.roundSize / 2).height(this.roundSize * 1.51).borderRadius(10).backgroundColor(this.spinColor).shadow(ShadowStyle.OUTER_DEFAULT_XS).opacity(this.opacities[index])}.width(this.roundSize).height('100%').rotate({ angle: index * (360 / this.dotCount) })});}.renderFit(RenderFit.CENTER).width(this.spinSize).height(this.spinSize).onAppear(() => {this.startAnimations();});}private startAnimations() {const totalDuration = 1200; // 总动画周期时间const delayStep = Math.floor(totalDuration / this.dotCount); // 自动计算延迟步长for (let i = 0; i < this.dotCount; i++) {const delay = -(i * delayStep); // 使用负数延迟制造交错效果const keyframes: KeyframeState[] = [{duration: 480,curve: Curve.Linear,event: () => {this.opacities[i] = 1;}},{duration: 720,curve: Curve.Linear,event: () => {this.opacities[i] = 0.3;}}];this.getUIContext().keyframeAnimateTo({ iterations: -1, delay: delay }, // -1 表示无限循环keyframes);}}
}function range(start: number, end: number): number[] {const result: number[] = [];for (let i = start; i < end; i++) {result.push(i);}return result;
}
3.修改Index.ets文件,代码如下:
import { SpinTwelve } from './Spin';@Entry @Component struct Index {@State message: string = 'Hello World';build() {Column() {SpinTwelve({spinSize: 60,spinColor: '#FF0000',dotCount:12})}.alignItems(HorizontalAlign.Center).justifyContent(FlexAlign.Center).height('100%').width('100%')} }
代码如下:
import { SpinTwelve } from './Spin';@Entry
@Component
struct Index {@State message: string = 'Hello World';build() {Column() {SpinTwelve({spinSize: 60,spinColor: '#FF0000',dotCount:12})}.alignItems(HorizontalAlign.Center).justifyContent(FlexAlign.Center).height('100%').width('100%')}
}
4.运行项目,登录华为账号,需进行签名
5.动画效果如下: