?1.創建空白項目
2.Page文件夾下面新建Spin.ets文件,代碼如下:
/*** SpinKit動畫組件 (重構版)* author: CSDN-鴻蒙布道師* since: 2025/05/14*/interface AnimationGroup {indexes: number[];delay: number; }@ComponentV2 export struct SpinEight {@Require @Param spinSize: number;@Require @Param spinColor: ResourceColor;// 使用數組管理 scale 狀態@Local scales: number[] = [1, 1, 1, 1, 1, 1, 1, 1, 1];build() {Grid() {// 使用循環構建9個CanvasForEach([0, 1, 2, 3, 4, 5, 6, 7, 8], (index: number) => {GridItem() {Canvas().chunkStyle();}.scale({ x: this.scales[index], y: this.scales[index], z: 1 });});}.rowsTemplate('1fr 1fr 1fr').columnsTemplate('1fr 1fr 1fr').renderFit(RenderFit.CENTER).width(this.spinSize).height(this.spinSize).onAppear(() => {// 動畫分組配置const animationGroups: AnimationGroup[] = [{ indexes: [6], delay: 0 },{ indexes: [3, 7], delay: 100 },{ indexes: [0, 4, 8], delay: 200 },{ indexes: [1, 5], delay: 300 },{ indexes: [2], delay: 400 }];// 遍歷每個動畫組并啟動動畫animationGroups.forEach((group: AnimationGroup) => {this.startAnimation(group.indexes, group.delay);});});}/*** 開始指定索引集合的動畫,并設置延遲* @param indexes - 要進行動畫的索引集合* @param delay - 動畫開始前的延遲時間*/private startAnimation(indexes: number[], delay: number) {let keyframes: Array<KeyframeState> = [{duration: 500,curve: Curve.EaseInOut,event: () => this.updateScales(indexes, 0),},{duration: 500,curve: Curve.Linear,event: () => this.updateScales(indexes, 1),},{duration: 400,curve: Curve.Linear,event: () => {},},];this.getUIContext().keyframeAnimateTo({ iterations: -1, delay: delay },keyframes);}/*** 更新指定索引集合的縮放比例* @param indexes - 縮放比例需要更新的索引集合* @param value - 新的縮放值*/private updateScales(indexes: number[], value: number) {indexes.forEach(index => {this.scales[index] = value;});}// 樣式封裝成函數@StyleschunkStyle() {.width(this.spinSize / 3).height(this.spinSize / 3).backgroundColor(this.spinColor).shadow(ShadowStyle.OUTER_DEFAULT_XS)} }
代碼如下:
/*** SpinKit動畫組件 (重構版)* author: CSDN-鴻蒙布道師* since: 2025/05/14*/interface AnimationGroup {indexes: number[];delay: number;
}@ComponentV2
export struct SpinEight {@Require @Param spinSize: number;@Require @Param spinColor: ResourceColor;// 使用數組管理 scale 狀態@Local scales: number[] = [1, 1, 1, 1, 1, 1, 1, 1, 1];build() {Grid() {// 使用循環構建9個CanvasForEach([0, 1, 2, 3, 4, 5, 6, 7, 8], (index: number) => {GridItem() {Canvas().chunkStyle();}.scale({ x: this.scales[index], y: this.scales[index], z: 1 });});}.rowsTemplate('1fr 1fr 1fr').columnsTemplate('1fr 1fr 1fr').renderFit(RenderFit.CENTER).width(this.spinSize).height(this.spinSize).onAppear(() => {// 動畫分組配置const animationGroups: AnimationGroup[] = [{ indexes: [6], delay: 0 },{ indexes: [3, 7], delay: 100 },{ indexes: [0, 4, 8], delay: 200 },{ indexes: [1, 5], delay: 300 },{ indexes: [2], delay: 400 }];// 遍歷每個動畫組并啟動動畫animationGroups.forEach((group: AnimationGroup) => {this.startAnimation(group.indexes, group.delay);});});}/*** 開始指定索引集合的動畫,并設置延遲* @param indexes - 要進行動畫的索引集合* @param delay - 動畫開始前的延遲時間*/private startAnimation(indexes: number[], delay: number) {let keyframes: Array<KeyframeState> = [{duration: 500,curve: Curve.EaseInOut,event: () => this.updateScales(indexes, 0),},{duration: 500,curve: Curve.Linear,event: () => this.updateScales(indexes, 1),},{duration: 400,curve: Curve.Linear,event: () => {},},];this.getUIContext().keyframeAnimateTo({ iterations: -1, delay: delay },keyframes);}/*** 更新指定索引集合的縮放比例* @param indexes - 縮放比例需要更新的索引集合* @param value - 新的縮放值*/private updateScales(indexes: number[], value: number) {indexes.forEach(index => {this.scales[index] = value;});}// 樣式封裝成函數@StyleschunkStyle() {.width(this.spinSize / 3).height(this.spinSize / 3).backgroundColor(this.spinColor).shadow(ShadowStyle.OUTER_DEFAULT_XS)}
}
3.修改Index.ets文件,代碼如下:
import { SpinEight } from './Spin';@Entry @Component struct Index {@State message: string = 'Hello World';build() {Column() {SpinEight({spinSize: 60,spinColor: '#FF0000'})}.alignItems(HorizontalAlign.Center).justifyContent(FlexAlign.Center).height('100%').width('100%')} }
代碼如下:
import { SpinEight } from './Spin';@Entry
@Component
struct Index {@State message: string = 'Hello World';build() {Column() {SpinEight({spinSize: 60,spinColor: '#FF0000'})}.alignItems(HorizontalAlign.Center).justifyContent(FlexAlign.Center).height('100%').width('100%')}
}
4.運行項目,登錄華為賬號,需進行簽名
5.動畫效果如下:
?