1# Particle Animation 2 3Particle animation is an animation composed of a multitude of particles randomly generated within a certain range. The particles can be points or images. By animating different aspects of the particles, such as color, opacity, scale, velocity, acceleration, and spin angle, you can create engaging and dynamic aesthetics. For example, you can create an impressive snowfall animation by animating the particles – snowflakes. 4 5The component used for producing particle animations is **Particle**. 6 7 8> **NOTE** 9> 10> This component is supported since API version 10. Updates will be marked with a superscript to indicate their earliest API version. 11 12 13## Child Components 14 15Not supported 16 17 18## APIs 19 20```typescript 21function Particle 22< 23 PARTICLE extends ParticleType, 24 COLOR_UPDATER extends ParticleUpdater, 25 OPACITY_UPDATER extends ParticleUpdater, 26 SCALE_UPDATER extends ParticleUpdater, 27 ACC_SPEED_UPDATER extends ParticleUpdater, 28 ACC_ANGLE_UPDATER extends ParticleUpdater, 29 SPIN_UPDATER extends ParticleUpdater 30>(value: { 31 particles: Array< 32 ParticleOptions< 33 PARTICLE, 34 COLOR_UPDATER, 35 OPACITY_UPDATER, 36 SCALE_UPDATER, 37 ACC_SPEED_UPDATER, 38 ACC_ANGLE_UPDATER, 39 SPIN_UPDATER 40 > 41 > 42}) 43 44``` 45 46**Parameters** 47 48| Name| Type| Mandatory| Description| 49| -------- | -------- | -------- | -------- | 50| value | {<br>particles:Array<[ParticleOptions](#particleoptions)<<br>[PARTICLE](#particletype), <br>[COLOR_UPDATER](#particleupdater),<br>[OPACITY_UPDATER](#particleupdater),<br>[SCALE_UPDATER](#particleupdater),<br>[ACC_SPEED_UPDATER](#particleupdater),<br> [ACC_ANGLE_UPDATER](#particleupdater),<br>[SPIN_UPDATER](#particleupdater)<br>>><br>} | Yes| An array of particle options, each of which covers the emitter, color, opacity, scale, velocity, acceleration, and spin speed of particles. For details, see [ParticleOptions](#particleoptions). | 51 52## Attributes 53The universal attributes are supported. 54 55## Events 56The universal events are supported. 57 58## ParticleOptions 59 60```typescript 61interface ParticleOptions< 62 PARTICLE extends ParticleType, 63 COLOR_UPDATER extends ParticleUpdater, 64 OPACITY_UPDATER extends ParticleUpdater, 65 SCALE_UPDATER extends ParticleUpdater, 66 ACC_SPEED_UPDATER extends ParticleUpdater, 67 ACC_ANGLE_UPDATER extends ParticleUpdater, 68 SPIN_UPDATER extends ParticleUpdater 69> { 70 emitter: EmitterOptions<PARTICLE>; 71 color?: ParticleColorPropertyOptions<COLOR_UPDATER>; 72 opacity?: ParticlePropertyOptions<number, OPACITY_UPDATER>; 73 scale?: ParticlePropertyOptions<number, SCALE_UPDATER>; 74 velocity?: { 75 speed: [number, number]; 76 angle: [number, number]; 77 }; 78 acceleration?: { 79 speed?: ParticlePropertyOptions<number, ACC_SPEED_UPDATER>; 80 angle?: ParticlePropertyOptions<number, ACC_ANGLE_UPDATER>; 81 }; 82 spin?: ParticlePropertyOptions<number, SPIN_UPDATER>; 83} 84``` 85 86| Name| Type| Mandatory| Description| 87| -------- | -------- | -------- | -------- | 88| emitter | [EmitterOptions](#emitteroptions)<[PARTICLE](#particletype)> | Yes| Particle emitter.| 89| color | [ParticleColorPropertyOptions](#particlecolorpropertyoptions)<[COLOR_UPDATER](#particleupdater)> | No| Particle color.<br>**NOTE**<br>Default value: **{ range:[Color.White,Color.White] }.** Colors cannot be set for image particles.| 90| opacity | [ParticlePropertyOptions](#particlepropertyoptions)\<number, [OPACITY_UPDATER](#particleupdater)> | No| Particle opacity.<br>Default value: **{range: [1.0,1.0] }**| 91| scale | [ParticlePropertyOptions](#particlepropertyoptions)\<number, [SCALE_UPDATER](#particleupdater)> | No| Particle scale.<br>Default value: **{range: [1.0,1.0] }**| 92| velocity | {<br>speed: [number, number];<br>angle: [number, number];<br>} |No| Particle velocity.<br>**NOTE**<br>**speed** indicates the time rate at which the particle moves, and **angle** indicates the direction (in angles) in which the particle moves.<br>Default value: **{speed: [0.0,0.0],angle: [0.0,0.0] }**| 93| acceleration | {<br>speed?: [ParticlePropertyOptions](#particlepropertyoptions)<number, [ACC_SPEED_UPDATER](#particleupdater)>;<br>angle?: [ParticlePropertyOptions](#particlepropertyoptions)<number, [ACC_ANGLE_UPDATER](#particleupdater)>;<br>} | No| Particle acceleration.<br>**NOTE**<br>**speed** indicates the acceleration speed, and **angle** indicates the acceleration direction (in angles).<br>Default value: **{speed:{range: [0.0,0.0] },angle:{range: [0.0,0.0] }}**| 94| spin | [ParticlePropertyOptions](#particlepropertyoptions)<number, [SPIN_UPDATER](#particleupdater)> | No| Particle spin angle.<br>Default value: **{range: [0.0,0.0] }**| 95 96 97## EmitterOptions 98Provides particle emitter configuration. 99 100```typescript 101interface EmitterOptions<PARTICLE extends ParticleType> { 102 particle: { 103 type: PARTICLE; 104 config: ParticleConfigs[PARTICLE]; 105 count: number; 106 lifetime?: number; 107 }; 108 emitRate?: number; 109 shape?: ParticleEmitterShape; 110 position?: [Dimension, Dimension]; 111 size?: [Dimension, Dimension]; 112} 113``` 114| Name| Type| Mandatory| Description| 115| -------- | -------- | -------- | -------- | 116| particle | {<br>type: [PARTICLE](#particletype),<br>config: [ParticleConfigs](#particleconfigs),<br>count: number,<br>lifetime?: number<br>} | Yes| Particle configuration.<br>- **type**: particle type, which can be **IMAGE** or **POINT**.<br>- **config**: configuration of the particle type.<br>- The value type of **config** is subject to the value of **type**.<br>1. If **type** is **ParticleType.POINT**, the **config** type is [PointParticleParameters](#pointparticleparameters).<br>2. If **type** is **ParticleType.IMAGE**, the **config** type is [ImageParticleParameters](#imageparticleparameters).<br>- **count**: number of particles. The value is greater than or equal to -1. The value **-1** indicates that the number of particles is infinite.<br>- **lifetime**: lifetime of a single particle. The default value is **1000** (that is, 1000 ms, 1s). The value is greater than or equal to -1. The value **-1** indicates that the lifetime of the particle is infinite.| 117| emitRate | number | No| Emit rate (that is, the number of particles emitted per second). Default value: **5**| 118| shape | [ParticleEmitterShape](#particleemittershape) | No| Emitter shape. Default value: **ParticleEmitterShape.RECTANGLE**| 119| position | [Dimension, Dimension] | No| Emitter position (distance from the upper left corner of the component).<br>Default value: **[0.0, 0.0]**| 120| size | [Dimension, Dimension] |No| Size of the emit window.<br>Default value: \['100%','100%'\] (that is, the emit window fully occupies the component).| 121 122## ParticleConfigs 123 124```typescript 125interface ParticleConfigs { 126 [ParticleType.POINT]: PointParticleParameters; 127 [ParticleType.IMAGE]: ImageParticleParameters; 128} 129``` 130 131 132| Parameter | Type | Mandatory| Description| 133| -------- | -------------- | -------- | -------- | 134| [ParticleType.POINT] | [PointParticleParameters](#pointparticleparameters) | Yes | Point particle configuration.| 135| [ParticleType.IMAGE] | [ImageParticleParameters](#imageparticleparameters) | Yes | Image particle configuration.| 136 137## PointParticleParameters 138```typescript 139interface PointParticleParameters { 140 radius: VP; 141} 142``` 143| Parameter | Type | Mandatory| Description| 144| -------- | -------------- | -------- | -------- | 145| radius | [VP](ts-types.md#vp)| Yes | Particle radius.| 146 147## ImageParticleParameters 148```typescript 149interface ImageParticleParameters { 150 src: ResourceStr; 151 size: [Dimension, Dimension]; 152 objectFit?: ImageFit; 153} 154``` 155| Parameter | Type | Mandatory| Description| 156| -------- | -------------- | -------- | -------- | 157| src | [ResourceStr](ts-types.md#resourcestr) | Yes | Image path. SVG and GIF images are not supported.| 158| size | \[[Dimension](ts-types.md#dimension10), [Dimension](ts-types.md#dimension10)\]| Yes | Image size.| 159| objectFit| [ImageFit](ts-appendix-enums.md#imagefit)| No | Image display mode.| 160 161## ParticleColorPropertyOptions 162 163```typescript 164interface ParticleColorPropertyOptions<UPDATER extends ParticleUpdater> { 165 range: [ResourceColor, ResourceColor]; 166 updater?: { 167 type: UPDATER; 168 config: ParticleColorPropertyUpdaterConfigs[UPDATER]; 169 }; 170} 171``` 172| Name| Type| Mandatory| Description| 173| -------- | -------- | -------- | -------- | 174| range | \[[ResourceColor](ts-types.md#resourcecolor), [ResourceColor](ts-types.md#resourcecolor)\] | Yes| Initial color range of the particle. The initial color of particles generated by the particle emitter is randomly selected in this range.<br>Default value: **range:[Color.White,Color.White]**| 175| updater | {<br>type: [UPDATER](#particleupdater);<br>config: [ParticleColorPropertyUpdaterConfigs](#particlecolorpropertyupdaterconfigs)[UPDATER];<br>} | No| How the color attribute is updated. The available options of **type** are as follows:<br>1. **ParticleUpdater.NONE**: The attribute does not change. In this case, the **config** type is [ParticleColorPropertyUpdaterConfigs](#particlecolorpropertyupdaterconfigs)[ParticleUpdater.NONE].<br>2. **ParticleUpdater.RANDOM**: The attribute changes randomly. In this case, the **config** type is [ParticleColorPropertyUpdaterConfigs](#particlecolorpropertyupdaterconfigs)[ParticleUpdater.RANDOM].<br>3. **ParticleUpdater.CURVE**: The attribute changes with the animation curve. In this case, the **config** type is [ParticleColorPropertyUpdaterConfigs](#particlecolorpropertyupdaterconfigs)[ParticleUpdater.CURVE].| 176 177 178## ParticleColorPropertyUpdaterConfigs 179```typescript 180interface ParticleColorPropertyUpdaterConfigs { 181 [ParticleUpdater.NONE]: void; 182 [ParticleUpdater.RANDOM]: { 183 r: [number, number]; 184 g: [number, number]; 185 b: [number, number]; 186 a: [number, number]; 187 }; 188 [ParticleUpdater.CURVE]: Array<ParticlePropertyAnimation<ResourceColor>>; 189} 190``` 191| Name| Type| Mandatory| Description| 192| -------- | -------- | -------- | -------- | 193| [ParticleUpdater.NONE]|void | Yes| The color does not change. The default value is **undefined**.| 194| [ParticleUpdater.RANDOM] | {<br> r: [number, number];<br> g: [number, number];<br> b: [number, number];<br> a: [number, number];<br>} | Yes| The color changes randomly. The color changes randomly.The target color is obtained by changing the value of each of the R, R, B, A channels and taking in the current color value.| 195| [ParticleUpdater.CURVE]|Array<[ParticlePropertyAnimation](#particlepropertyanimation)\<[ResourceColor](ts-types.md#resourcecolor)\>> | Yes| The color changes with the animation curve. The array type indicates that multiple animation segments can be set for the current attribute, for example, 0-3000 ms, 3000-5000 ms, and 5000-8000 ms.| 196 197## ParticlePropertyOptions 198```typescript 199interface ParticlePropertyOptions<TYPE, UPDATER extends ParticleUpdater> { 200 range: [TYPE, TYPE]; 201 updater?: { 202 type: UPDATER; 203 config: ParticlePropertyUpdaterConfigs<TYPE>[UPDATER]; 204 }; 205} 206``` 207| Name| Type| Mandatory| Description| 208| -------- | -------- | -------- | -------- | 209| range | [number, number] | Yes| Initial attribute value range of the particle. The initial attribute value of particles generated by the particle emitter is randomly selected in this range.<br>**NOTE**<br>The default values of different attributes are different:<br>1. Default value of the **opacity** attribute: **range: [1.0,1.0]**<br>2. Default value of the **scale** attribute: **range:[1.01.0]**<br>3. Default value of the acceleration **speed** attribute: **range: [0.0,0.0]**<br>4. Default value of the acceleration **angle** attribute: **range:[0.0,0.0]**<br>5. Default value of the **spin** attribute: **range: [0.0,0.0]**| 210| updater | {type: [UPDATER](#particleupdater);config: [ParticlePropertyUpdaterConfigs](#particlepropertyupdaterconfigs)[UPDATER];} | No| How the attribute is updated. The available options of **type** are as follows:<br>1. **ParticleUpdater.NONE**: The attribute does not change. In this case, the **config** type is [ParticlePropertyUpdaterConfigs](#particlepropertyupdaterconfigs)[ParticleUpdater.NONE].<br>2. **ParticleUpdater.RANDOM**: The attribute changes randomly. In this case, the **config** type is [ParticlePropertyUpdaterConfigs](#particlepropertyupdaterconfigs)[ParticleUpdater.RANDOM].<br>3. **ParticleUpdater.CURVE**: The attribute changes with the animation curve. In this case, the **config** type is [ParticlePropertyUpdaterConfigs](#particlepropertyupdaterconfigs)[ParticleUpdater.CURVE].| 211 212 213## ParticlePropertyUpdaterConfigs 214```typescript 215interface ParticlePropertyUpdaterConfigs<T> { 216 [ParticleUpdater.NONE]: void; 217 [ParticleUpdater.RANDOM]: [T, T]; 218 [ParticleUpdater.CURVE]: Array<ParticlePropertyAnimation<T>>; 219} 220``` 221| Name| Type| Mandatory| Description| 222| -------- | -------- | -------- | -------- | 223| [[ParticleUpdater.NONE]|void | Yes| The attribute does not change. The default value is **undefined**.| 224| [ParticleUpdater.RANDOM] | [number, number] | Yes| The attribute changes randomly, with the change difference being a value randomly generated from the range.<br>The target attribute value is obtained by applying the change difference to the current attribute value. For example, if the current attribute value is **0.2** and **config** is set to **[0.1,1.0]**, then:<br>1. When the random change difference is 0.5, the target attribute value is 0.2 + 0.5 = 0.7.<br>2. The change difference may also be a negative value. For example, if the current attribute value is **0.2** and **config** is set to **[-3.0,2.0]**, then when the random change difference is **-2.0**, the target attribute value is 0.2 - 2.0 = -1.8.<br>**NOTE**<br>**config** sets the value range of the change difference. While the change difference does not have a maximum or minimum value limit, the target attribute value does. Therefore, if the target attribute value is greater than the maximum attribute value, the maximum attribute value will be used instead; if the target attribute value is less than the minimum attribute value, the minimum attribute value will be used instead.<br>For example, if the value range of **opacity** is **[0.0,1.0]**, then if the target attribute value is greater than 1.0, **1.0** will be used instead.| 225| [ParticleUpdater.CURVE]|Array<[ParticlePropertyAnimation](#particlepropertyanimation)\<number\>> | Yes| The attribute changes with the animation curve. The array type indicates that multiple animation segments can be set for the current attribute, for example, 0-3000 ms, 3000-5000 ms, and 5000-8000 ms.| 226 227 228 229## ParticlePropertyAnimation 230```typescript 231interface ParticlePropertyAnimation<T> { 232 from: T; 233 to: T; 234 startMillis: number; 235 endMillis: number; 236 curve?: Curve | ICurve; 237} 238``` 239| Name| Type| Mandatory| Description| 240| -------- | -------- | -------- | -------- | 241|from| T | Yes| Initial value of the attribute.| 242| to | T | Yes| Target value of the attribute.| 243|startMillis|number | Yes| Start time of the animation.| 244|endMillis|number | Yes| End time of the animation.| 245|curve|[Curve](ts-appendix-enums.md#curve) \| [ICurve](../apis/js-apis-curve.md#icurve)| No| Animation curve.<br>Default value: **Curve.Linear**| 246 247 248## ParticleType 249```typescript 250enum ParticleType { 251 POINT = 'point', 252 IMAGE = 'image', 253} 254``` 255| Name | Description| 256| -------- | -------- | 257|POINT |Poin particle.| 258|IMAGE | Image particle.| 259 260 261 262## ParticleEmitterShape 263```typescript 264enum ParticleEmitterShape { 265 RECTANGLE = 'rectangle', 266 CIRCLE = 'circle', 267 ELLIPSE = 'ellipse', 268} 269``` 270| Name | Description| 271| -------- | -------- | 272|RECTANGLE |The particle emitter is rectangular.| 273|CIRCLE | The particle emitter is circular.| 274|ELLIPSE |The particle emitter is elliptical.| 275 276 277## ParticleUpdater 278```typescript 279enum ParticleUpdater { 280 NONE = 'none', 281 RANDOM = 'random', 282 CURVE = 'curve', 283} 284``` 285| Name | Description| 286| -------- | -------- | 287|NONE |No change.| 288|RANDOM | Random change.| 289|CURVE |Change with the animation curve.| 290 291## Example 292 293### Example 1 294```ts 295// xxx.ets 296// xxx.ets 297@Entry 298@Component 299struct ParticleExample { 300 build() { 301 Stack() { 302 Text() 303 .width(300).height(300).backgroundColor(Color.Black) 304 Particle({particles:[ 305 { 306 emitter:{ 307 particle:{ 308 type:ParticleType.POINT,// Particle type. 309 config:{ 310 radius:10// Point radius. 311 }, 312 count: 500,// Total number of particles. 313 lifetime:10000// Particle lifetime, in ms. 314 }, 315 emitRate:10,// Number of particles emitted per second. 316 position:[0,0], 317 shape:ParticleEmitterShape.RECTANGLE// Emitter shape. 318 }, 319 color:{ 320 range:[Color.Red,Color.Yellow],// Initial color range. 321 updater:{ 322 type:ParticleUpdater.CURVE,// Change with the animation curve. 323 config:[ 324 { 325 from:Color.White,// Initial value of the change. 326 to:Color.Pink,// Target value of the change. 327 startMillis:0,// Start time. 328 endMillis:3000,// End time. 329 curve:Curve.EaseIn// Animation curve. 330 }, 331 { 332 from:Color.Pink, 333 to:Color.Orange, 334 startMillis:3000, 335 endMillis:5000, 336 curve:Curve.EaseIn 337 }, 338 { 339 from:Color.Orange, 340 to:Color.Pink, 341 startMillis:5000, 342 endMillis:8000, 343 curve:Curve.EaseIn 344 }, 345 ] 346 } 347 }, 348 opacity:{ 349 range: [0.0,0.0],// The initial value of particle opacity is randomly generated from 0.0 to 1.0. 350 updater:{ 351 type:ParticleUpdater.CURVE,// Opacity changes randomly. 352 config:[ 353 { 354 from:0.0, 355 to:1.0, 356 startMillis:0, 357 endMillis:3000, 358 curve:Curve.EaseIn 359 }, 360 { 361 from:1.0, 362 to:0.0, 363 startMillis:5000, 364 endMillis:10000, 365 curve:Curve.EaseIn 366 } 367 ] 368 } 369 }, 370 scale:{ 371 range:[0.0,0.0], 372 updater:{ 373 type:ParticleUpdater.CURVE, 374 config:[ 375 { 376 from:0.0, 377 to:0.5, 378 startMillis:0, 379 endMillis:3000, 380 curve: Curve.EaseIn 381 } 382 ] 383 } 384 }, 385 acceleration:{// Acceleration. speed indicates the acceleration speed, and angle indicates the acceleration direction. 386 speed:{ 387 range:[3,9], 388 updater:{ 389 type:ParticleUpdater.RANDOM, 390 config:[1,20] 391 } 392 }, 393 angle:{ 394 range:[90,90] 395 } 396 } 397 398 } 399 ] 400 }).width(300).height(300) 401 }.width("100%").height("100%").align(Alignment.Center) 402 } 403} 404``` 405 406 407 408### Example 2 409```ts 410@Entry 411@Component 412struct ParticleExample { 413 @State 414 myCount : number = 100 415 flag : boolean = false; 416 build() { 417 Column(){ 418 Stack() { 419 Particle({particles:[ 420 { 421 emitter:{ 422 particle:{ 423 type:ParticleType.IMAGE, 424 config:{ 425 src:$r("app.media.glass"), 426 size:[10,10] 427 }, 428 count: this.myCount, 429 lifetime:10000 430 }, 431 emitRate:3, 432 shape:ParticleEmitterShape.CIRCLE 433 }, 434 color:{ 435 range:[Color.White,Color.White] 436 }, 437 opacity:{ 438 range:[1.0,1.0], 439 updater:{ 440 type:ParticleUpdater.CURVE, 441 config:[ 442 { 443 from:0, 444 to:1.0, 445 startMillis:0, 446 endMillis:6000 447 }, 448 { 449 from:1.0, 450 to:.0, 451 startMillis:6000, 452 endMillis:10000 453 } 454 ] 455 } 456 }, 457 scale:{ 458 range:[0.1,1.0], 459 updater:{ 460 type:ParticleUpdater.CURVE, 461 config:[ 462 { 463 from: 0, 464 to: 1.5, 465 startMillis: 0, 466 endMillis: 8000, 467 curve: Curve.EaseIn 468 } 469 470 ] 471 } 472 }, 473 acceleration:{ 474 speed:{ 475 range:[3,9], 476 updater:{ 477 type: ParticleUpdater.CURVE, 478 config:[ 479 { 480 from:10, 481 to:20, 482 startMillis:0, 483 endMillis:3000, 484 curve:Curve.EaseIn 485 }, 486 { 487 from:10, 488 to:2, 489 startMillis:3000, 490 endMillis:8000, 491 curve:Curve.EaseIn 492 } 493 ] 494 } 495 }, 496 angle:{ 497 range:[0,180], 498 updater:{ 499 type:ParticleUpdater.CURVE, 500 config:[{ 501 from:1, 502 to:2, 503 startMillis:0, 504 endMillis:1000, 505 curve:Curve.EaseIn 506 }, 507 { 508 from:50, 509 to:-50, 510 startMillis:1000, 511 endMillis:3000, 512 curve:Curve.EaseIn 513 }, 514 { 515 from:3, 516 to:5, 517 startMillis:3000, 518 endMillis:8000, 519 curve:Curve.EaseIn 520 } 521 ] 522 } 523 } 524 }, 525 spin:{ 526 range:[0.1,1.0], 527 updater:{ 528 type:ParticleUpdater.CURVE, 529 config:[ 530 { 531 from: 0, 532 to: 360, 533 startMillis: 0, 534 endMillis: 8000, 535 curve: Curve.EaseIn 536 } 537 ] 538 } 539 }, 540 } 541 ,{ 542 emitter:{ 543 particle:{ 544 type:ParticleType.IMAGE, 545 config:{ 546 src:$r('app.media.book'), 547 size:[10,10] 548 }, 549 count: this.myCount, 550 lifetime:10000 551 }, 552 emitRate:3, 553 shape:ParticleEmitterShape.CIRCLE 554 }, 555 color:{ 556 range:[Color.White,Color.White] 557 }, 558 opacity:{ 559 range:[1.0,1.0], 560 updater:{ 561 type:ParticleUpdater.CURVE, 562 config:[ 563 { 564 from:0, 565 to:1.0, 566 startMillis:0, 567 endMillis:6000 568 }, 569 { 570 from:1.0, 571 to:.0, 572 startMillis:6000, 573 endMillis:10000 574 } 575 ] 576 } 577 }, 578 scale:{ 579 range:[0.1,1.0], 580 updater:{ 581 type:ParticleUpdater.CURVE, 582 config:[ 583 { 584 from: 0, 585 to: 2.0, 586 startMillis: 0, 587 endMillis: 10000, 588 curve: Curve.EaseIn 589 } 590 591 ] 592 } 593 }, 594 acceleration:{ 595 speed:{ 596 range:[3,9], 597 updater:{ 598 type: ParticleUpdater.CURVE, 599 config:[ 600 { 601 from:10, 602 to:20, 603 startMillis:0, 604 endMillis:3000, 605 curve:Curve.EaseIn 606 }, 607 { 608 from:10, 609 to:2, 610 startMillis:3000, 611 endMillis:8000, 612 curve:Curve.EaseIn 613 } 614 ] 615 } 616 }, 617 angle:{ 618 range:[0,180], 619 updater:{ 620 type:ParticleUpdater.CURVE, 621 config:[{ 622 from:1, 623 to:2, 624 startMillis:0, 625 endMillis:1000, 626 curve:Curve.EaseIn 627 }, 628 { 629 from:50, 630 to:-50, 631 startMillis:0, 632 endMillis:3000, 633 curve:Curve.EaseIn 634 }, 635 { 636 from:3, 637 to:5, 638 startMillis:3000, 639 endMillis:10000, 640 curve:Curve.EaseIn 641 } 642 ] 643 } 644 } 645 }, 646 spin:{ 647 range:[0.1,1.0], 648 updater:{ 649 type:ParticleUpdater.CURVE, 650 config:[ 651 { 652 from: 0, 653 to: 360, 654 startMillis: 0, 655 endMillis: 10000, 656 curve: Curve.EaseIn 657 } 658 ] 659 } 660 }, 661 },{ 662 emitter:{ 663 particle:{ 664 type:ParticleType.IMAGE, 665 config:{ 666 src:$r('app.media.squares'), 667 size:[10,10] 668 }, 669 count: this.myCount, 670 lifetime:10000 671 }, 672 emitRate:3, 673 shape:ParticleEmitterShape.CIRCLE 674 }, 675 color:{ 676 range:[Color.White,Color.White] 677 }, 678 opacity:{ 679 range:[1.0,1.0], 680 updater:{ 681 type:ParticleUpdater.CURVE, 682 config:[ 683 { 684 from:0, 685 to:1.0, 686 startMillis:0, 687 endMillis:6000 688 }, 689 { 690 from:1.0, 691 to:.0, 692 startMillis:6000, 693 endMillis:10000 694 } 695 ] 696 } 697 }, 698 scale:{ 699 range:[0.1,1.0], 700 updater:{ 701 type:ParticleUpdater.CURVE, 702 config:[ 703 { 704 from: 0, 705 to: 2.0, 706 startMillis: 0, 707 endMillis: 10000, 708 curve: Curve.EaseIn 709 } 710 711 ] 712 } 713 }, 714 acceleration:{ 715 speed:{ 716 range:[3,9], 717 updater:{ 718 type: ParticleUpdater.CURVE, 719 config:[ 720 { 721 from:10, 722 to:20, 723 startMillis:0, 724 endMillis:3000, 725 curve:Curve.EaseIn 726 }, 727 { 728 from:10, 729 to:2, 730 startMillis:3000, 731 endMillis:8000, 732 curve:Curve.EaseIn 733 } 734 ] 735 } 736 }, 737 angle:{ 738 range:[0,180], 739 updater:{ 740 type:ParticleUpdater.CURVE, 741 config:[{ 742 from:1, 743 to:2, 744 startMillis:0, 745 endMillis:1000, 746 curve:Curve.EaseIn 747 }, 748 { 749 from:50, 750 to:-50, 751 startMillis:1000, 752 endMillis:3000, 753 curve:Curve.EaseIn 754 }, 755 { 756 from:3, 757 to:5, 758 startMillis:3000, 759 endMillis:8000, 760 curve:Curve.EaseIn 761 } 762 ] 763 } 764 } 765 }, 766 spin:{ 767 range:[0.1,1.0], 768 updater:{ 769 type:ParticleUpdater.CURVE, 770 config:[ 771 { 772 from: 0, 773 to: 360, 774 startMillis: 0, 775 endMillis: 10000, 776 curve: Curve.EaseIn 777 } 778 ] 779 } 780 }, 781 } 782 ] 783 }).width(300).height(300) 784 785 }.width(500).height(500).align(Alignment.Center) 786 }.width("100%").height("100%") 787 788 } 789} 790``` 791 792