@castlenine/svelte-canvas-confetti 1.1.0 → 5.0.1
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/README.md +62 -11
- package/dist/Confetti.svelte +158 -74
- 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/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 +2 -2
- package/dist/utils/constants.d.ts.map +1 -1
- package/dist/utils/constants.js +1 -1
- package/dist/utils/particle.d.ts +15 -5
- package/dist/utils/particle.d.ts.map +1 -1
- package/dist/utils/particle.js +34 -33
- package/dist/utils/random.d.ts +1 -1
- package/dist/utils/random.d.ts.map +1 -1
- package/dist/utils/random.js +1 -1
- package/dist/utils/types.d.ts +3 -3
- package/dist/utils/types.d.ts.map +1 -1
- package/package.json +104 -96
package/README.md
CHANGED
|
@@ -13,13 +13,7 @@ Canvas-based confetti for Svelte 🎉, with no dependencies.
|
|
|
13
13
|
* Supports image-based confetti.
|
|
14
14
|
* Allows full customization of confetti behavior using the `onCreate` and `onUpdate` hooks.
|
|
15
15
|
|
|
16
|
-
##
|
|
17
|
-
|
|
18
|
-
[Simple Demo](https://svelte.dev/repl/84bb431468264dabbfdd0750ef949f9f?version=3.50.1)
|
|
19
|
-
|
|
20
|
-
[Firework Demo](https://svelte.dev/repl/8d05b7c60c244fe0b7e09b027dd3bc5d?version=3.50.1)
|
|
21
|
-
|
|
22
|
-
[Advanced Demo](https://svelte.dev/repl/5cefe21763c445d986c6e23ddea1327a?version=3.50.1)
|
|
16
|
+
## 🚀 [Demo](https://svelte-canvas-confetti.vercel.app/)
|
|
23
17
|
|
|
24
18
|
## Installation
|
|
25
19
|
|
|
@@ -83,6 +77,43 @@ If no properties are passed in, it will behave the same as **FallingConfetti**.
|
|
|
83
77
|
<Confetti />
|
|
84
78
|
```
|
|
85
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
|
+
|
|
86
117
|
## Props
|
|
87
118
|
|
|
88
119
|
### particleCount
|
|
@@ -101,7 +132,7 @@ The number of particles to create.
|
|
|
101
132
|
|
|
102
133
|
A list of styles used to render particles. Can be any valid HTML color or an `HTMLImageElement`.
|
|
103
134
|
|
|
104
|
-
**Type:** `ParticleStyle[]`
|
|
135
|
+
**Type:** `readonly ParticleStyle[]`
|
|
105
136
|
**Default value:** `['hotpink', 'gold', 'dodgerblue', 'tomato', 'rebeccapurple', 'lightgreen', 'turquoise']`
|
|
106
137
|
**Example:**
|
|
107
138
|
|
|
@@ -157,7 +188,7 @@ The spread used when creating each particle’s initial direction. The particle'
|
|
|
157
188
|
<Confetti origin={[100, 100]} spread={45} />
|
|
158
189
|
```
|
|
159
190
|
|
|
160
|
-
|
|
191
|
+
### onCreate
|
|
161
192
|
|
|
162
193
|
This can be used to override the properties of each particle at creation time.
|
|
163
194
|
|
|
@@ -175,7 +206,7 @@ This can be used to override the properties of each particle at creation time.
|
|
|
175
206
|
/>
|
|
176
207
|
```
|
|
177
208
|
|
|
178
|
-
|
|
209
|
+
### onUpdate
|
|
179
210
|
|
|
180
211
|
This can be used to override the properties of each particle at update time.
|
|
181
212
|
|
|
@@ -191,7 +222,27 @@ This can be used to override the properties of each particle at update time.
|
|
|
191
222
|
/>
|
|
192
223
|
```
|
|
193
224
|
|
|
194
|
-
|
|
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
|
|
195
246
|
|
|
196
247
|
```typescript
|
|
197
248
|
export type Particle = {
|
package/dist/Confetti.svelte
CHANGED
|
@@ -1,81 +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
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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
|
+
}
|
|
55
111
|
</script>
|
|
56
112
|
|
|
57
|
-
<script
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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
|
+
});
|
|
75
159
|
</script>
|
|
76
160
|
|
|
77
|
-
<svelte:window bind:
|
|
78
|
-
<canvas
|
|
161
|
+
<svelte:window bind:innerHeight={canvasHeight} bind:innerWidth={canvasWidth} />
|
|
162
|
+
<canvas width={canvasWidth} height={canvasHeight} bind:this={canvas}></canvas>
|
|
79
163
|
|
|
80
164
|
<style>
|
|
81
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":["../src/lib/Confetti.svelte.ts"],"names":[],"mappings":"
|
|
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"}
|
|
@@ -1,9 +1,37 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
<!--
|
|
2
|
+
@component
|
|
3
|
+
Confetti burst effect. Spawns particles from a single origin point that explode outward in all directions (360° spread).
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@prop origin {Position} - Origin position [x, y] of the confetti burst. Required.
|
|
8
|
+
@prop styles {readonly ParticleStyle[]} [undefined] - Render styles for confetti. Valid HTML colors or HTMLImageElement.
|
|
9
|
+
@prop particleCount {number} [50] - Number of particles to create.
|
|
10
|
+
@prop onCreate {OnCreateParticle} [undefined] - Callback to override initial particle values at creation time.
|
|
11
|
+
@prop onUpdate {OnUpdateParticle} [undefined] - Callback called each frame per particle for custom animation logic.
|
|
12
|
+
@prop onCompleted {() => void} [undefined] - Callback fired when all particles have exited the screen.
|
|
13
|
+
-->
|
|
14
|
+
|
|
15
|
+
<script lang="ts">
|
|
16
|
+
import type { OnCreateParticle, OnUpdateParticle, ParticleStyle, Position } from './utils/types';
|
|
17
|
+
|
|
18
|
+
import Confetti from './Confetti.svelte';
|
|
19
|
+
|
|
20
|
+
const {
|
|
21
|
+
origin,
|
|
22
|
+
styles = undefined,
|
|
23
|
+
particleCount = 50,
|
|
24
|
+
onCreate = undefined,
|
|
25
|
+
onUpdate = undefined,
|
|
26
|
+
onCompleted,
|
|
27
|
+
} = $props<{
|
|
28
|
+
origin: Position;
|
|
29
|
+
styles?: readonly ParticleStyle[];
|
|
30
|
+
particleCount?: number;
|
|
31
|
+
onCreate?: OnCreateParticle;
|
|
32
|
+
onUpdate?: OnUpdateParticle;
|
|
33
|
+
onCompleted?: () => void;
|
|
34
|
+
}>();
|
|
7
35
|
</script>
|
|
8
36
|
|
|
9
|
-
<Confetti {
|
|
37
|
+
<Confetti {origin} {particleCount} {styles} {onCompleted} {onCreate} {onUpdate} />
|
|
@@ -1,72 +1,25 @@
|
|
|
1
|
-
import { SvelteComponentTyped } from "svelte";
|
|
2
1
|
import type { OnCreateParticle, OnUpdateParticle, ParticleStyle, Position } from './utils/types';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
* <ConfettiBurst origin={[50, 50]} />
|
|
11
|
-
* ```
|
|
12
|
-
*/ origin: Position;
|
|
13
|
-
/**
|
|
14
|
-
* A list of render styles to use for the confetti. Each confetti will be assigned a random value from the list.
|
|
15
|
-
* The values can either be valid HTML colors or an HTMLImageElement.
|
|
16
|
-
* @default ['hotpink','gold','dodgerblue','tomato','rebeccapurple','lightgreen','turquoise']
|
|
17
|
-
* @example
|
|
18
|
-
* ```
|
|
19
|
-
* <ConfettiBurst colors={['red', '#ff0000', 'hsl(250, 54%, 85%)']} />
|
|
20
|
-
* ```
|
|
21
|
-
*/ styles?: ParticleStyle[] | undefined;
|
|
22
|
-
/**
|
|
23
|
-
* The number of particles to create.
|
|
24
|
-
* @default 50
|
|
25
|
-
* @example
|
|
26
|
-
* ```
|
|
27
|
-
* <ConfettiBurst particleCount={100} />
|
|
28
|
-
* ```
|
|
29
|
-
*/ particleCount?: number | undefined;
|
|
30
|
-
/**
|
|
31
|
-
* By default, each particle is created with some random variation. The initial values of each particle can be overridden using the onCreate callback.
|
|
32
|
-
* @default undefined
|
|
33
|
-
* @example
|
|
34
|
-
* ```
|
|
35
|
-
* <ConfettiBurst
|
|
36
|
-
* onCreate={(particle) => {
|
|
37
|
-
* particle.style = 'blue';
|
|
38
|
-
* particle.x = window.innerWidth / 2;
|
|
39
|
-
* return particle;
|
|
40
|
-
* }}
|
|
41
|
-
* />
|
|
42
|
-
* ```
|
|
43
|
-
*/ onCreate?: OnCreateParticle | undefined;
|
|
44
|
-
/**
|
|
45
|
-
* The onUpdate callback can be used to modify the particle on each frame.
|
|
46
|
-
* @default undefined
|
|
47
|
-
* @example
|
|
48
|
-
* ```
|
|
49
|
-
* <ConfettiBurst
|
|
50
|
-
* onUpdate={(particle, deltaTime) => {
|
|
51
|
-
* if (particle.angle < 0 && particle.da < 0) {
|
|
52
|
-
* particle.da *= -1;
|
|
53
|
-
* }
|
|
54
|
-
* }}
|
|
55
|
-
* />
|
|
56
|
-
* ```
|
|
57
|
-
*/ onUpdate?: OnUpdateParticle | undefined;
|
|
58
|
-
};
|
|
59
|
-
events: {
|
|
60
|
-
completed: CustomEvent<any>;
|
|
61
|
-
} & {
|
|
62
|
-
[evt: string]: CustomEvent<any>;
|
|
63
|
-
};
|
|
64
|
-
slots: {};
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
origin: Position;
|
|
4
|
+
styles?: readonly ParticleStyle[];
|
|
5
|
+
particleCount?: number;
|
|
6
|
+
onCreate?: OnCreateParticle;
|
|
7
|
+
onUpdate?: OnUpdateParticle;
|
|
8
|
+
onCompleted?: () => void;
|
|
65
9
|
};
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
10
|
+
/**
|
|
11
|
+
* Confetti burst effect. Spawns particles from a single origin point that explode outward in all directions (360° spread).
|
|
12
|
+
*
|
|
13
|
+
*
|
|
14
|
+
*
|
|
15
|
+
* @prop origin {Position} - Origin position [x, y] of the confetti burst. Required.
|
|
16
|
+
* @prop styles {readonly ParticleStyle[]} [undefined] - Render styles for confetti. Valid HTML colors or HTMLImageElement.
|
|
17
|
+
* @prop particleCount {number} [50] - Number of particles to create.
|
|
18
|
+
* @prop onCreate {OnCreateParticle} [undefined] - Callback to override initial particle values at creation time.
|
|
19
|
+
* @prop onUpdate {OnUpdateParticle} [undefined] - Callback called each frame per particle for custom animation logic.
|
|
20
|
+
* @prop onCompleted {() => void} [undefined] - Callback fired when all particles have exited the screen.
|
|
21
|
+
*/
|
|
22
|
+
declare const ConfettiBurst: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
23
|
+
type ConfettiBurst = ReturnType<typeof ConfettiBurst>;
|
|
24
|
+
export default ConfettiBurst;
|
|
72
25
|
//# sourceMappingURL=ConfettiBurst.svelte.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConfettiBurst.svelte.d.ts","sourceRoot":"","sources":["../src/lib/ConfettiBurst.svelte.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ConfettiBurst.svelte.d.ts","sourceRoot":"","sources":["../src/lib/ConfettiBurst.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAIhG,KAAK,gBAAgB,GAAG;IACvB,MAAM,EAAE,QAAQ,CAAC;IACjB,MAAM,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;IAClC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;CACzB,CAAC;AAsBH;;;;;;;;;;;GAWG;AACH,QAAA,MAAM,aAAa,sDAAwC,CAAC;AAC5D,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,eAAe,aAAa,CAAC"}
|