当前位置: 首页 > news >正文

鸿蒙NEXT开发动画案例8

 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.动画效果如下:
 

相关文章:

  • wordcount程序
  • Git 用户名与邮箱配置全解析:精准配置——基于场景的参数选择
  • 第二章:磁盘管理与文件管理
  • 六西格玛觉醒:一场数据思维的启蒙运动​
  • 【RabbitMQ】发布确认机制的具体实现
  • MUSE Pi Pro 更换kernel内核及module模块
  • AI智能体的现状和应用前景
  • jQuery知识框架
  • 2020年下半年试题三:论云原生架构及其应用
  • IDEA 新建 SpringBoot 项目时,没有高版本 SpringBoot 可选
  • Kafka 消费者组进度监控方法解析
  • 【SSL证书系列】https双向认证中客户端认证的原理
  • LeetCode 每日一题 3341. 到达最后一个房间的最少时间 I + II
  • Vue ElementUI原生upload修改字体大小和区域宽度
  • SCDN能够运用在物联网加速当中吗?
  • 精益数据分析(58/126):移情阶段的深度实践与客户访谈方法论
  • Kite AI 自动机器人部署教程
  • 【达梦数据库】超出全局hash join空间问题处理
  • 【江苏省】《信息技术应用创新软件适配改造成本评估规范》(DB32/T 4935-2024)-标准解读系列
  • WinFrom 使用 LiveCharts 实现动态折线图
  • 讲武谈兵|视距外的狙杀:从印巴空战谈谈超视距空战
  • 沪喀同心|为新疆青少年提供科普大餐,“小小博物家(喀什版)”启动
  • 以军向也门3个港口的居民发布撤离令
  • 气候多米诺:厄尔尼诺与东南亚跨境害虫或威胁中国粮食安全
  • 山东鄄城发生一起交通事故,造成4人死亡、2人受伤
  • 上海能源科技发展有限公司原董事长李海瑜一审获刑13年