@castlenine/svelte-canvas-confetti 1.0.0 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  # MIT License
2
2
 
3
- Copyright (c) 2024 Alexandre "Castlenine"
3
+ Copyright (c) 2024–present Alex "Castlenine"
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -2,28 +2,24 @@
2
2
 
3
3
  # `@castlenine/svelte-canvas-confetti`
4
4
 
5
- [![npm.badge]][npm] [![download.badge]][download]
5
+ [![npm.badge]][npm] [![download.badge]][download] [![contribution.badge]][contribution]
6
6
 
7
- Canvas-based confetti for Svelte 🎉, without dependencies
7
+ Canvas-based confetti for Svelte 🎉, with no dependencies.
8
8
  </div>
9
9
 
10
10
  ## Features
11
11
 
12
12
  * Uses a single canvas to render full-screen confetti.
13
13
  * Supports image-based confetti.
14
- * Allows full customization of confetti behavior using `onCreate` and `onUpdate` hooks.
14
+ * Allows full customization of confetti behavior using the `onCreate` and `onUpdate` hooks.
15
15
 
16
- ## Examples
16
+ ## 🚀 [Demo](https://svelte-canvas-confetti.vercel.app/)
17
17
 
18
- [Simple Demo](https://svelte.dev/repl/84bb431468264dabbfdd0750ef949f9f?version=3.50.1)
18
+ ## Installation
19
19
 
20
- [Firework Demo](https://svelte.dev/repl/8d05b7c60c244fe0b7e09b027dd3bc5d?version=3.50.1)
20
+ Use your package manager to install:
21
21
 
22
- [Advanced Demo](https://svelte.dev/repl/5cefe21763c445d986c6e23ddea1327a?version=3.50.1)
23
-
24
- ## Installing
25
-
26
- ```bash
22
+ ```shell
27
23
  npm i @castlenine/svelte-canvas-confetti
28
24
  ```
29
25
 
@@ -45,7 +41,7 @@ Adds confetti falling from the top of the screen.
45
41
 
46
42
  ### ConfettiBurst
47
43
 
48
- Adds a confetti burst anywhere on the screen. It requires an origin position.
44
+ Adds a confetti burst anywhere on the screen. Requires an origin position.
49
45
 
50
46
  ```svelte
51
47
  <script>
@@ -57,7 +53,7 @@ Adds a confetti burst anywhere on the screen. It requires an origin position.
57
53
 
58
54
  ### ConfettiCannon
59
55
 
60
- Adds a confetti cannon that can shoot out directional confetti. It requires an origin position.
56
+ Adds a confetti cannon that can shoot directional confetti. Requires an origin position.
61
57
 
62
58
  ```svelte
63
59
  <script>
@@ -69,9 +65,9 @@ Adds a confetti cannon that can shoot out directional confetti. It requires an o
69
65
 
70
66
  ### Confetti
71
67
 
72
- Adds any type of confetti. This is the main component that the other three are just simple wrappers around.
68
+ Adds any type of confetti. This is the main component, and the other three are simple wrappers around it.
73
69
 
74
- If no properties are passed in, it will create the same result as **FallingConfetti**.
70
+ If no properties are passed in, it will behave the same as **FallingConfetti**.
75
71
 
76
72
  ```svelte
77
73
  <script>
@@ -81,11 +77,48 @@ If no properties are passed in, it will create the same result as **FallingConfe
81
77
  <Confetti />
82
78
  ```
83
79
 
80
+ ## Image Handling
81
+
82
+ You can use images instead of colors by passing `HTMLImageElement` instances to the `styles` prop. It is recommended to use [Vite's built-in image handling](https://svelte.dev/docs/kit/images#Vite's-built-in-handling) to import images from `$lib/assets` — this ensures proper asset hashing, inlining of small files, and tree-shaking.
83
+
84
+ ```svelte
85
+ <script lang="ts">
86
+ import { onMount } from 'svelte';
87
+
88
+ import { FallingConfetti } from '@castlenine/svelte-canvas-confetti';
89
+
90
+ import SmallLogo from '$lib/assets/logos/logo-small.png';
91
+
92
+ let imageLogo = $state<HTMLImageElement | null>(null);
93
+ let showConfetti = $state(false);
94
+
95
+ onMount(() => {
96
+ imageLogo = new Image();
97
+ imageLogo.src = SmallLogo;
98
+
99
+ imageLogo.onload = () => {
100
+ showConfetti = true;
101
+ };
102
+ });
103
+ </script>
104
+
105
+ {#if showConfetti && imageLogo}
106
+ <FallingConfetti
107
+ particleCount={142}
108
+ styles={[imageLogo]}
109
+ onCompleted={() => {
110
+ showConfetti = false;
111
+ }} />
112
+ {/if}
113
+ ```
114
+
115
+ The image import path can be placed wherever appropriate in your project, using any alias you prefer (e.g., `$lib/assets/images/`, `$lib/assets/logos/`, `$assets/images/`).
116
+
84
117
  ## Props
85
118
 
86
119
  ### particleCount
87
120
 
88
- Number of particles to create.
121
+ The number of particles to create.
89
122
 
90
123
  **Type:** `number`
91
124
  **Default value:** `50`
@@ -97,10 +130,10 @@ Number of particles to create.
97
130
 
98
131
  ### styles
99
132
 
100
- A list of styles used to render particles. Can be any valid HTML color or an HTMLImageElement.
133
+ A list of styles used to render particles. Can be any valid HTML color or an `HTMLImageElement`.
101
134
 
102
- **Type:** `Array<string | HTMLImageElement>`
103
- **Default value:** `['hotpink','gold','dodgerblue','tomato','rebeccapurple','lightgreen','turquoise']`
135
+ **Type:** `readonly ParticleStyle[]`
136
+ **Default value:** `['hotpink', 'gold', 'dodgerblue', 'tomato', 'rebeccapurple', 'lightgreen', 'turquoise']`
104
137
  **Example:**
105
138
 
106
139
  ```svelte
@@ -109,9 +142,9 @@ A list of styles used to render particles. Can be any valid HTML color or an HTM
109
142
 
110
143
  ### origin
111
144
 
112
- The origin of the particles. If this is not used, the particles will fall from the top of the screen.
145
+ The origin of the particles. If this is not provided, the particles will fall from the top of the screen.
113
146
 
114
- **Type:** `[number, number]`
147
+ **Type:** `Position`
115
148
  **Default value:** `undefined`
116
149
  **Example:**
117
150
 
@@ -133,7 +166,7 @@ The initial force used to shoot out confetti. This has no effect if `origin` is
133
166
 
134
167
  ### angle
135
168
 
136
- The angle used to shoot out confetti. This has no effect if `origin` is not used. It can be combined with `spread` to create a "cannon".
169
+ The angle used to shoot out confetti. This has no effect if `origin` is not used. Can be combined with `spread` to create a "cannon" effect.
137
170
 
138
171
  **Type:** `number`
139
172
  **Default value:** 0
@@ -145,7 +178,7 @@ The angle used to shoot out confetti. This has no effect if `origin` is not used
145
178
 
146
179
  ### spread
147
180
 
148
- The spread used when creating each particles initial direction. The particle's initial direction will be a value between `angle - spread / 2` and `angle + spread / 2`. This has no effect if `origin` is not used.
181
+ The spread used when creating each particle’s initial direction. The particle's initial direction will be a value between `angle - spread / 2` and `angle + spread / 2`. This has no effect if `origin` is not used.
149
182
 
150
183
  **Type:** `number`
151
184
  **Default value:** 360
@@ -155,12 +188,12 @@ The spread used when creating each particles initial direction. The particle's i
155
188
  <Confetti origin={[100, 100]} spread={45} />
156
189
  ```
157
190
 
158
- ## onCreate
191
+ ### onCreate
159
192
 
160
193
  This can be used to override the properties of each particle at creation time.
161
194
 
162
195
  **Type:** `(particle) => particle`
163
- **Default value:** undefined
196
+ **Default value:** `undefined`
164
197
  **Example:**
165
198
 
166
199
  ```svelte
@@ -173,27 +206,47 @@ This can be used to override the properties of each particle at creation time.
173
206
  />
174
207
  ```
175
208
 
176
- ## onUpdate
209
+ ### onUpdate
177
210
 
178
211
  This can be used to override the properties of each particle at update time.
179
212
 
180
213
  **Type:** `(particle, deltaTime) => void`
181
- **Default value:** undefined
214
+ **Default value:** `undefined`
182
215
  **Example:**
183
216
 
184
217
  ```svelte
185
218
  <Confetti
186
- onCreate={(particle) => {
219
+ onUpdate={(particle) => {
187
220
  particle.x += Math.random() * 5;
188
221
  }}
189
222
  />
190
223
  ```
191
224
 
192
- ## Particle object
225
+ ### onCompleted
226
+
227
+ A callback fired when all particles have exited the screen.
228
+
229
+ **Type:** `() => void`
230
+ **Default value:** `undefined`
231
+ **Example:**
232
+
233
+ ```svelte
234
+ <script>
235
+ import { Confetti } from '@castlenine/svelte-canvas-confetti';
236
+
237
+ let showConfetti = $state(true);
238
+ </script>
239
+
240
+ {#if showConfetti}
241
+ <Confetti onCompleted={() => { showConfetti = false; }} />
242
+ {/if}
243
+ ```
244
+
245
+ ## Particle Object
193
246
 
194
247
  ```typescript
195
248
  export type Particle = {
196
- // Stop updating/rendering the particle once it is "dead" (ie off screen)
249
+ // Stop updating/rendering the particle once it is "dead" (i.e., off screen)
197
250
  dead: boolean;
198
251
 
199
252
  // The total time since the particle was created.
@@ -229,7 +282,7 @@ export type Particle = {
229
282
  // Vertical gravity.
230
283
  gy: number;
231
284
 
232
- // The "width" of the falling motion. The falling motion is calculated as Math.sin(life * xw)
285
+ // The "width" of the falling motion. The falling motion is calculated as Math.sin(life * xw).
233
286
  xw: number;
234
287
 
235
288
  // The style of the particle. Either an HTML color or an HTMLImageElement.
@@ -237,6 +290,22 @@ export type Particle = {
237
290
  };
238
291
  ```
239
292
 
293
+ ## Exported Types
294
+
295
+ The following types are exported from the package:
296
+
297
+ ```typescript
298
+ import type { Particle, ParticleStyle, Position, OnCreateParticle, OnUpdateParticle } from '@castlenine/svelte-canvas-confetti';
299
+ ```
300
+
301
+ | Type | Description |
302
+ | --- | --- |
303
+ | `Particle` | The particle object used in `onCreate` and `onUpdate` callbacks. |
304
+ | `ParticleStyle` | `string \| HTMLImageElement` — a valid HTML color or an image element. |
305
+ | `Position` | `[number, number]` — an `[x, y]` coordinate tuple. |
306
+ | `OnCreateParticle` | `(p: Particle) => Particle` — callback to customize particles at creation. |
307
+ | `OnUpdateParticle` | `(p: Particle, dt: number) => void` — callback to modify particles each frame. |
308
+
240
309
  ---
241
310
 
242
311
  Forked from [andreasmcdermott/svelte-canvas-confetti](https://github.com/andreasmcdermott/svelte-canvas-confetti)
@@ -245,3 +314,5 @@ Forked from [andreasmcdermott/svelte-canvas-confetti](https://github.com/andreas
245
314
  [npm.badge]: https://img.shields.io/npm/v/@castlenine/svelte-canvas-confetti
246
315
  [download]: https://www.npmjs.com/package/@castlenine/svelte-canvas-confetti
247
316
  [download.badge]: https://img.shields.io/npm/d18m/@castlenine/svelte-canvas-confetti
317
+ [contribution]: https://github.com/Castlenine/svelte-aoe
318
+ [contribution.badge]: https://img.shields.io/badge/contributions-welcome-green
@@ -1,76 +1,165 @@
1
- <script context="module">import { COLORS } from "./utils/constants";
2
- import { createParticle, isOutOfBounds, renderParticle, updateParticle } from "./utils/particle";
3
- const renderParticles = (context, particles) => {
4
- context.clearRect(0, 0, context.canvas.width, context.canvas.height);
5
- for (let i = 0; i < particles.length; ++i) {
6
- renderParticle(context, particles[i]);
7
- }
8
- };
9
- const updateParticles = (context, particles, dt, onUpdate) => {
10
- let livingParticles = particles.length;
11
- for (let i = 0; i < particles.length; ++i) {
12
- const P = particles[i];
13
- if (P.dead) {
14
- livingParticles--;
15
- }
16
- else {
17
- updateParticle(P, dt);
18
- if (isOutOfBounds(context, P))
19
- P.dead = true;
20
- if (onUpdate)
21
- onUpdate(P, dt);
22
- }
23
- }
24
- return livingParticles > 0;
25
- };
26
- const start = (canvas, onCompleted, particleCount, origin, force, angle, spread, styles, onCreate, onUpdate) => {
27
- const CONTEXT = canvas.getContext("2d");
28
- if (!CONTEXT)
29
- throw new Error("No context?");
30
- const PARTICLES = Array.from({ length: particleCount }, () => createParticle(CONTEXT, origin, force, angle, spread, styles, onCreate));
31
- let frameId;
32
- let t;
33
- const run = (_t) => {
34
- renderParticles(CONTEXT, PARTICLES);
35
- const STILL_RUNNING = updateParticles(CONTEXT, PARTICLES, (_t - t) / 1e3, onUpdate);
36
- if (STILL_RUNNING) {
37
- t = _t;
38
- frameId = requestAnimationFrame(run);
39
- }
40
- else {
41
- onCompleted();
42
- }
43
- };
44
- t = performance.now();
45
- frameId = requestAnimationFrame(run);
46
- return () => {
47
- cancelAnimationFrame(frameId);
48
- };
49
- };
1
+ <!--
2
+ @component
3
+ Full-screen canvas-based confetti renderer. Spawns particles on mount and animates them via `requestAnimationFrame` until all exit the viewport, then fires `onCompleted`. Used internally by `ConfettiBurst`, `ConfettiCannon`, and `FallingConfetti`.
4
+
5
+ &nbsp;
6
+
7
+ @prop styles {readonly ParticleStyle[]} [COLORS] - Render styles for confetti. Each particle gets a random value. Valid HTML colors or HTMLImageElement.
8
+ @prop particleCount {number} [50] - Number of particles to create.
9
+ @prop origin {Position} [undefined] - Origin position [x, y]. If omitted, confetti falls from the top.
10
+ @prop force {number} [15] - Burst velocity. Higher = faster/further. No effect without origin.
11
+ @prop angle {number} [0] - Burst direction in degrees. Use with spread for directed bursts. No effect without origin.
12
+ @prop spread {number} [360] - Angular spread in degrees. Use with angle for directed bursts. No effect without origin.
13
+ @prop onCreate {OnCreateParticle} [undefined] - Callback to override initial particle values at creation time.
14
+ @prop onUpdate {OnUpdateParticle} [undefined] - Callback called each frame per particle for custom animation logic.
15
+ @prop onCompleted {() => void} [undefined] - Callback fired when all particles have exited the screen.
16
+ -->
17
+
18
+ <script module lang="ts">
19
+ import type { OnCreateParticle, OnUpdateParticle, Particle, ParticleStyle, Position } from './utils/types';
20
+
21
+ import { COLORS } from './utils/constants';
22
+ import { createParticle, isOutOfBounds, renderParticle, updateParticle } from './utils/particle';
23
+
24
+ function renderParticles(context: CanvasRenderingContext2D, particles: Particle[]): void {
25
+ context.clearRect(0, 0, context.canvas.width, context.canvas.height);
26
+
27
+ for (let index = 0; index < particles.length; ++index) {
28
+ const PARTICLE = particles[index];
29
+
30
+ if (!PARTICLE.dead && PARTICLE.life >= PARTICLE.delay) renderParticle(context, PARTICLE);
31
+ }
32
+ }
33
+
34
+ /**
35
+ * @returns {boolean} Returns false if no more confettis on the screen.
36
+ */
37
+ function updateParticles(
38
+ context: CanvasRenderingContext2D,
39
+ particles: Particle[],
40
+ dt: number,
41
+ onUpdate?: OnUpdateParticle,
42
+ ): boolean {
43
+ const CW = context.canvas.width;
44
+ const CH = context.canvas.height;
45
+ let livingParticles = particles.length;
46
+
47
+ for (let index = 0; index < particles.length; ++index) {
48
+ const PARTICLE = particles[index];
49
+
50
+ if (PARTICLE.dead) {
51
+ livingParticles--;
52
+ } else {
53
+ updateParticle(PARTICLE, dt);
54
+
55
+ if (isOutOfBounds(PARTICLE, CW, CH)) PARTICLE.dead = true;
56
+ if (onUpdate) onUpdate(PARTICLE, dt);
57
+ }
58
+ }
59
+
60
+ return livingParticles > 0;
61
+ }
62
+
63
+ interface StartOptions {
64
+ canvas: HTMLCanvasElement;
65
+ onCompleted: () => void;
66
+ particleCount: number;
67
+ origin: Position | undefined;
68
+ force: number;
69
+ angle: number;
70
+ spread: number;
71
+ styles: readonly ParticleStyle[];
72
+ onCreate?: OnCreateParticle;
73
+ onUpdate?: OnUpdateParticle;
74
+ }
75
+
76
+ function start(options: StartOptions): () => void {
77
+ const { canvas, onCompleted, particleCount, origin, force, angle, spread, styles, onCreate, onUpdate } = options;
78
+ const MAYBE_CONTEXT = canvas.getContext('2d');
79
+
80
+ if (!MAYBE_CONTEXT) throw new Error('No context?');
81
+
82
+ const CONTEXT: CanvasRenderingContext2D = MAYBE_CONTEXT;
83
+
84
+ const PARTICLES: Particle[] = Array.from({ length: particleCount }, () =>
85
+ createParticle({ context: CONTEXT, origin, force, angle, spread, styles, onCreate }),
86
+ );
87
+
88
+ let frameId: number;
89
+ let timestamp: number;
90
+
91
+ function run(currentTimestamp: number): void {
92
+ renderParticles(CONTEXT, PARTICLES);
93
+ const DT = Math.min((currentTimestamp - timestamp) / 1e3, 0.1);
94
+ const STILL_RUNNING = updateParticles(CONTEXT, PARTICLES, DT, onUpdate);
95
+
96
+ if (STILL_RUNNING) {
97
+ timestamp = currentTimestamp;
98
+ frameId = requestAnimationFrame(run);
99
+ } else {
100
+ onCompleted();
101
+ }
102
+ }
103
+
104
+ timestamp = performance.now();
105
+ frameId = requestAnimationFrame(run);
106
+
107
+ return () => {
108
+ cancelAnimationFrame(frameId);
109
+ };
110
+ }
50
111
  </script>
51
112
 
52
- <script>import { onMount, createEventDispatcher } from "svelte";
53
- export let styles = COLORS;
54
- export let particleCount = 50;
55
- export let origin = void 0;
56
- export let force = 15;
57
- export let angle = 0;
58
- export let spread = 360;
59
- export let onCreate = void 0;
60
- export let onUpdate = void 0;
61
- const dispatch = createEventDispatcher();
62
- let canvas;
63
- let w;
64
- let h;
65
- onMount(() => {
66
- canvas.width = w;
67
- canvas.height = h;
68
- return start(canvas, () => dispatch("completed"), particleCount, origin, force, angle, spread, styles, onCreate, onUpdate);
69
- });
113
+ <script lang="ts">
114
+ import { onMount } from 'svelte';
115
+
116
+ const {
117
+ styles = COLORS,
118
+ particleCount = 50,
119
+ origin = undefined,
120
+ force = 15,
121
+ angle = 0,
122
+ spread = 360,
123
+ onCreate = undefined,
124
+ onUpdate = undefined,
125
+ onCompleted,
126
+ } = $props<{
127
+ styles?: readonly ParticleStyle[];
128
+ particleCount?: number;
129
+ origin?: Position;
130
+ force?: number;
131
+ angle?: number;
132
+ spread?: number;
133
+ onCreate?: OnCreateParticle;
134
+ onUpdate?: OnUpdateParticle;
135
+ onCompleted?: () => void;
136
+ }>();
137
+
138
+ let canvasWidth: number = $state(0);
139
+ let canvasHeight: number = $state(0);
140
+ let canvas: HTMLCanvasElement;
141
+
142
+ onMount(() => {
143
+ canvas.width = canvasWidth;
144
+ canvas.height = canvasHeight;
145
+
146
+ return start({
147
+ canvas,
148
+ onCompleted: () => onCompleted?.(),
149
+ particleCount,
150
+ origin,
151
+ force,
152
+ angle,
153
+ spread,
154
+ styles,
155
+ onCreate,
156
+ onUpdate,
157
+ });
158
+ });
70
159
  </script>
71
160
 
72
- <svelte:window bind:innerWidth={w} bind:innerHeight={h} />
73
- <canvas bind:this={canvas} width={w} height={h} />
161
+ <svelte:window bind:innerHeight={canvasHeight} bind:innerWidth={canvasWidth} />
162
+ <canvas width={canvasWidth} height={canvasHeight} bind:this={canvas}></canvas>
74
163
 
75
164
  <style>
76
165
  canvas {
@@ -1,96 +1,31 @@
1
- import { SvelteComponentTyped } from "svelte";
2
1
  import type { OnCreateParticle, OnUpdateParticle, ParticleStyle, Position } from './utils/types';
3
- declare const __propDef: {
4
- props: {
5
- /**
6
- * A list of render styles to use for the confetti. Each confetti will be assigned a random value from the list.
7
- * The values can either be valid HTML colors or an HTMLImageElement.
8
- * @default ['hotpink','gold','dodgerblue','tomato','rebeccapurple','lightgreen','turquoise']
9
- * @example
10
- * ```
11
- * <Confetti colors={['red', '#ff0000', 'hsl(250, 54%, 85%)']} />
12
- * ```
13
- */ styles?: ParticleStyle[] | undefined;
14
- /**
15
- * The number of particles to create.
16
- * @default 50
17
- * @example
18
- * ```
19
- * <Confetti particleCount={100} />
20
- * ```
21
- */ particleCount?: number | undefined;
22
- /**
23
- * The origin position of the confetti. If this is not passed in, the confetti will fall from the top of the screen.
24
- * @default undefined
25
- * @example
26
- * ```
27
- * <Confetti origin={[50, 50]} />
28
- * ```
29
- */ origin?: Position | undefined;
30
- /**
31
- * The force of the burst. A larger number will shoot the confetti faster and further. Has no effect if origin isn't passed in.
32
- * @default 15
33
- * @example
34
- * ```
35
- * <Confetti origin={[50, 50]} force={15} />
36
- * ```
37
- */ force?: number | undefined;
38
- /**
39
- * Angle in degrees of the burst. This can be used together with spread to create a directed burst. Has no effect if origin isn't passed in.
40
- * @default 0
41
- * @example
42
- * ```
43
- * <Confetti origin={[50, 50]} angle={90} />
44
- * ```
45
- */ angle?: number | undefined;
46
- /**
47
- * The spread in degrees of the burst. This can be used together with angle to create a directed burst. Has no effect if origin isn't passed in.
48
- * @default 360
49
- * @example
50
- * ```
51
- * <Confetti origin={[50, 50]} spread={90} />
52
- * ```
53
- */ spread?: number | undefined;
54
- /**
55
- * By default, each particle is created with some random variation. The initial values of each particle can be overridden using the onCreate callback.
56
- * @default undefined
57
- * @example
58
- * ```
59
- * <Confetti
60
- * onCreate={(particle) => {
61
- * particle.style = 'blue';
62
- * particle.x = window.innerWidth / 2;
63
- * return particle;
64
- * }}
65
- * />
66
- * ```
67
- */ onCreate?: OnCreateParticle | undefined;
68
- /**
69
- * The onUpdate callback can be used to modify the particle on each frame.
70
- * @default undefined
71
- * @example
72
- * ```
73
- * <Confetti
74
- * onUpdate={(particle, deltaTime) => {
75
- * if (particle.angle < 0 && particle.da < 0) {
76
- * particle.da *= -1;
77
- * }
78
- * }}
79
- * />
80
- * ```
81
- */ onUpdate?: OnUpdateParticle | undefined;
82
- };
83
- events: {
84
- completed: CustomEvent<any>;
85
- } & {
86
- [evt: string]: CustomEvent<any>;
87
- };
88
- slots: {};
2
+ type $$ComponentProps = {
3
+ styles?: readonly ParticleStyle[];
4
+ particleCount?: number;
5
+ origin?: Position;
6
+ force?: number;
7
+ angle?: number;
8
+ spread?: number;
9
+ onCreate?: OnCreateParticle;
10
+ onUpdate?: OnUpdateParticle;
11
+ onCompleted?: () => void;
89
12
  };
90
- export type ConfettiProps = typeof __propDef.props;
91
- export type ConfettiEvents = typeof __propDef.events;
92
- export type ConfettiSlots = typeof __propDef.slots;
93
- export default class Confetti extends SvelteComponentTyped<ConfettiProps, ConfettiEvents, ConfettiSlots> {
94
- }
95
- export {};
13
+ /**
14
+ * Full-screen canvas-based confetti renderer. Spawns particles on mount and animates them via `requestAnimationFrame` until all exit the viewport, then fires `onCompleted`. Used internally by `ConfettiBurst`, `ConfettiCannon`, and `FallingConfetti`.
15
+ *
16
+ * &nbsp;
17
+ *
18
+ * @prop styles {readonly ParticleStyle[]} [COLORS] - Render styles for confetti. Each particle gets a random value. Valid HTML colors or HTMLImageElement.
19
+ * @prop particleCount {number} [50] - Number of particles to create.
20
+ * @prop origin {Position} [undefined] - Origin position [x, y]. If omitted, confetti falls from the top.
21
+ * @prop force {number} [15] - Burst velocity. Higher = faster/further. No effect without origin.
22
+ * @prop angle {number} [0] - Burst direction in degrees. Use with spread for directed bursts. No effect without origin.
23
+ * @prop spread {number} [360] - Angular spread in degrees. Use with angle for directed bursts. No effect without origin.
24
+ * @prop onCreate {OnCreateParticle} [undefined] - Callback to override initial particle values at creation time.
25
+ * @prop onUpdate {OnUpdateParticle} [undefined] - Callback called each frame per particle for custom animation logic.
26
+ * @prop onCompleted {() => void} [undefined] - Callback fired when all particles have exited the screen.
27
+ */
28
+ declare const Confetti: import("svelte").Component<$$ComponentProps, {}, "">;
29
+ type Confetti = ReturnType<typeof Confetti>;
30
+ export default Confetti;
96
31
  //# sourceMappingURL=Confetti.svelte.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Confetti.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/Confetti.svelte"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,QAAQ,CAE5C;AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAY,aAAa,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AA2Q5G,QAAA,MAAM,SAAS;;QA7Ef;;;;;;;;eAQI;QACJ;;;;;;;eAOI;QACJ;;;;;;;eAOI,UAAS,QAAQ,GAAG,SAAS;QACjC;;;;;;;eAOI;QACJ;;;;;;;eAOI;QACJ;;;;;;;eAOI;QACJ;;;;;;;;;;;;;eAaI,YAAW,gBAAgB,GAAG,SAAS;QAC3C;;;;;;;;;;;;;eAaI,YAAW,gBAAgB,GAAG,SAAS;;;;;;;;CACY,CAAC;AACxD,MAAM,MAAM,aAAa,GAAG,OAAO,SAAS,CAAC,KAAK,CAAC;AACnD,MAAM,MAAM,cAAc,GAAG,OAAO,SAAS,CAAC,MAAM,CAAC;AACrD,MAAM,MAAM,aAAa,GAAG,OAAO,SAAS,CAAC,KAAK,CAAC;AAEnD,MAAM,CAAC,OAAO,OAAO,QAAS,SAAQ,oBAAoB,CAAC,aAAa,EAAE,cAAc,EAAE,aAAa,CAAC;CACvG"}
1
+ {"version":3,"file":"Confetti.svelte.d.ts","sourceRoot":"","sources":["../src/lib/Confetti.svelte.ts"],"names":[],"mappings":"AAGC,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAY,aAAa,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAgG3G,KAAK,gBAAgB,GAAG;IACvB,MAAM,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;IAClC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,QAAQ,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;CACzB,CAAC;AAkDH;;;;;;;;;;;;;;GAcG;AACH,QAAA,MAAM,QAAQ,sDAAwC,CAAC;AACvD,KAAK,QAAQ,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;AAC5C,eAAe,QAAQ,CAAC"}