HarmonyOS ArkUI (粒子动画实现动态标题)

一、粒子动画实现动态标题

二、效果:

三、实现思路:

1、使用Column 和 stack布局

2、粒子效果覆盖在文本上方

3、粒子效果实现

Particle({
  particles: [
    // 第一种粒子
    {
      emitter: { ... },  // 发射器配置
      color: { ... },    // 颜色配置
      opacity: { ... },  // 透明度配置
      scale: { ... },    // 缩放配置
      acceleration: { ... }  // 加速度配置
    },
    // 第二种粒子
    { ... }
  ]
}).width(150).height(100)

4、粒子发射器配置

emitter: {
  particle: {
    type: ParticleType.IMAGE,  // 使用图片作为粒子
    config: {
      src: $r("app.media.animation_xin"),  // 粒子图片资源
      size: [10, 10]  // 粒子大小
    },
    count: this.myCount,  // 粒子数量
    lifetime: 7000,  // 粒子生命周期(毫秒)
    lifetimeRange: 100  // 生命周期随机范围
  },
  emitRate: 3,  // 发射速率(粒子/秒)
  position: [0.5, 1.0],  // 发射位置(相对坐标)
  shape: ParticleEmitterShape.CIRCLE  // 发射形状(圆形)
}

5、动画效果实现:使用了两种粒子,第一种粒子生命周期 7 秒,从底部中心向上发射,有完整的透明度和缩放变化;第二个粒子生命周期 8 秒,默认从左上角发射,与第一种粒子类似的动画效果,但持续时间不同。

opacity: {
  range: [1.0, 1.0],
  updater: {
    type: ParticleUpdater.CURVE,
    config: [
      {
        from: 0, to: 1.0,  // 从不透明到完全透明
        startMillis: 0, endMillis: 2000  // 时间范围
      },
      {
        from: 1.0, to: .0,  // 从完全透明到消失
        startMillis: 2000, endMillis: 4000
      }
    ]
  }
}

四、代码实现: myCount 变量来控制粒子的密集程度

@Entry
@Component
struct ParticleExample {
  @State
  myCount: number = 100
  flag: boolean = false;
  build() {
    Column() {
      Stack() {
        Text('云音乐').fontSize(25).fontWeight('bold')
        Particle({
          particles: [
            {
              emitter: {
                particle: {
                  type: ParticleType.IMAGE,
                  config: {
                    src: $r("app.media.animation_xin"),
                    size: [10, 10]
                  },
                  count: this.myCount,
                  lifetime: 7000,
                  lifetimeRange: 100
                },
                emitRate: 3,
                position: [0.5, 1.0],
                shape: ParticleEmitterShape.CIRCLE
              },
              color: {
                range: [Color.White, Color.White]
              },
              opacity: {
                range: [1.0, 1.0],
                updater: {
                  type: ParticleUpdater.CURVE,
                  config: [
                    {
                      from: 0,
                      to: 1.0,
                      startMillis: 0,
                      endMillis: 2000
                    },
                    {
                      from: 1.0,
                      to: .0,
                      startMillis: 2000,
                      endMillis: 4000
                    }
                  ]
                }
              },
              scale: {
                range: [0.8, 2.0],
                updater: {
                  type: ParticleUpdater.CURVE,
                  config: [
                    {
                      from: 0.8,
                      to: 1.5,
                      startMillis: 0,
                      endMillis: 3000,
                      curve: Curve.EaseIn
                    },
                    {
                      from: 1.5,
                      to: 2.0,
                      startMillis: 3000,
                      endMillis: 4000,
                      curve: Curve.EaseIn
                    }
                  ]
                }
              },
              acceleration: {
                speed: {
                  range: [3, 9],
                  updater: {
                    type: ParticleUpdater.CURVE,
                    config: [
                      {
                        from: 10,
                        to: 50,
                        startMillis: 0,
                        endMillis: 5000,
                        curve: Curve.EaseIn
                      },
                    ]
                  }
                },
                angle: {
                  range: [270,270],
                  updater: {
                    type: ParticleUpdater.CURVE,
                    config: [{
                      from: 270,
                      to: 270,
                      startMillis: 0,
                      endMillis: 5000,
                      curve: Curve.EaseIn
                    },
                    ]
                  }
                }
              },
            }
            ,  {
            emitter: {
              particle: {
                type: ParticleType.IMAGE,
                config: {
                  src: $r('app.media.search_x1'),
                  size: [10, 10]
                },
                count: this.myCount,
                lifetime: 8000,
                lifetimeRange: 100
              },
              emitRate: 3,
              shape: ParticleEmitterShape.CIRCLE
            },
            color: {
              range: [Color.White, Color.White]
            },
            opacity: {
              range: [1.0, 1.0],
              updater: {
                type: ParticleUpdater.CURVE,
                config: [
                  {
                    from: 0,
                    to: 1.0,
                    startMillis: 0,
                    endMillis: 2000
                  },
                  {
                    from: 1.0,
                    to: .0,
                    startMillis: 2000,
                    endMillis: 3000
                  }
                ]
              }
            },
            scale: {
              range: [0.8, 2.0],
              updater: {
                type: ParticleUpdater.CURVE,
                config: [
                  {
                    from: 0.8,
                    to: 1.5,
                    startMillis: 0,
                    endMillis: 3000,
                    curve: Curve.EaseIn
                  },
                  {
                    from: 1.5,
                    to: 2.0,
                    startMillis: 3000,
                    endMillis: 4000,
                    curve: Curve.EaseIn
                  }
                ]
              }
            },
            acceleration: {
              speed: {
                range: [3, 9],
                updater: {
                  type: ParticleUpdater.CURVE,
                  config: [
                    {
                      from: 10,
                      to: 50,
                      startMillis: 0,
                      endMillis: 5000,
                      curve: Curve.EaseIn
                    },
                  ]
                }
              },
              angle: {
                range: [270, 270],
                updater: {
                  type: ParticleUpdater.CURVE,
                  config: [{
                    from: 270,
                    to: 270,
                    startMillis: 0,
                    endMillis: 5000,
                    curve: Curve.EaseIn
                  },
                  ]
                }
              }
            },
          }
          ]
        }).width(150).height(100)
      }.width(500).align(Alignment.Center).height(100).margin({top:200})
      // .backgroundColor(Color.Pink)
    }.width("100%").height(100)
  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值