@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.
- package/{LICENSE → LICENSE.md} +1 -1
- package/README.md +102 -31
- package/dist/Confetti.svelte +158 -69
- package/dist/Confetti.svelte.d.ts +28 -93
- package/dist/Confetti.svelte.d.ts.map +1 -1
- package/dist/ConfettiBurst.svelte +35 -7
- package/dist/ConfettiBurst.svelte.d.ts +22 -69
- package/dist/ConfettiBurst.svelte.d.ts.map +1 -1
- package/dist/ConfettiCannon.svelte +44 -10
- package/dist/ConfettiCannon.svelte.d.ts +28 -93
- package/dist/ConfettiCannon.svelte.d.ts.map +1 -1
- package/dist/FallingConfetti.svelte +32 -6
- package/dist/FallingConfetti.svelte.d.ts +20 -61
- package/dist/FallingConfetti.svelte.d.ts.map +1 -1
- package/dist/assets/images/airplane.png +0 -0
- package/dist/assets/images/parachute.png +0 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/utils/constants.d.ts +5 -5
- package/dist/utils/constants.d.ts.map +1 -1
- package/dist/utils/constants.js +5 -5
- package/dist/utils/particle.d.ts +16 -5
- package/dist/utils/particle.d.ts.map +1 -1
- package/dist/utils/particle.js +48 -49
- package/dist/utils/random.d.ts +3 -2
- package/dist/utils/random.d.ts.map +1 -1
- package/dist/utils/random.js +3 -2
- package/dist/utils/types.d.ts +7 -6
- package/dist/utils/types.d.ts.map +1 -1
- package/package.json +103 -94
package/{LICENSE → LICENSE.md}
RENAMED
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 🎉,
|
|
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
|
-
##
|
|
16
|
+
## 🚀 [Demo](https://svelte-canvas-confetti.vercel.app/)
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
## Installation
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
Use your package manager to install:
|
|
21
21
|
|
|
22
|
-
|
|
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.
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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:** `
|
|
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
|
|
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:** `
|
|
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.
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
219
|
+
onUpdate={(particle) => {
|
|
187
220
|
particle.x += Math.random() * 5;
|
|
188
221
|
}}
|
|
189
222
|
/>
|
|
190
223
|
```
|
|
191
224
|
|
|
192
|
-
|
|
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" (
|
|
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
|
package/dist/Confetti.svelte
CHANGED
|
@@ -1,76 +1,165 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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
|
+
|
|
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
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
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:
|
|
73
|
-
<canvas
|
|
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
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
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
|
+
*
|
|
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":["
|
|
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"}
|