• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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&lt;[ParticleOptions](#particleoptions)&lt;<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>&gt;&gt;<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![particle](figures/particle.gif)
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![particle](figures/particle_image.gif)
792