@castlenine/svelte-canvas-confetti 0.1.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 +21 -0
- package/README.md +247 -0
- package/dist/Confetti.svelte +85 -0
- package/dist/Confetti.svelte.d.ts +96 -0
- package/dist/Confetti.svelte.d.ts.map +1 -0
- package/dist/ConfettiBurst.svelte +9 -0
- package/dist/ConfettiBurst.svelte.d.ts +72 -0
- package/dist/ConfettiBurst.svelte.d.ts.map +1 -0
- package/dist/ConfettiCannon.svelte +12 -0
- package/dist/ConfettiCannon.svelte.d.ts +96 -0
- package/dist/ConfettiCannon.svelte.d.ts.map +1 -0
- package/dist/FallingConfetti.svelte +8 -0
- package/dist/FallingConfetti.svelte.d.ts +64 -0
- package/dist/FallingConfetti.svelte.d.ts.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/utils/constants.d.ts +6 -0
- package/dist/utils/constants.d.ts.map +1 -0
- package/dist/utils/constants.js +5 -0
- package/dist/utils/particle.d.ts +6 -0
- package/dist/utils/particle.d.ts.map +1 -0
- package/dist/utils/particle.js +83 -0
- package/dist/utils/random.d.ts +3 -0
- package/dist/utils/random.d.ts.map +1 -0
- package/dist/utils/random.js +2 -0
- package/dist/utils/types.d.ts +21 -0
- package/dist/utils/types.d.ts.map +1 -0
- package/dist/utils/types.js +1 -0
- package/package.json +96 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Alexandre "Castlenine"
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# `@castlenine/svelte-canvas-confetti`
|
|
4
|
+
|
|
5
|
+
[![npm.badge]][npm] [![download.badge]][download]
|
|
6
|
+
|
|
7
|
+
Canvas-based confetti for Svelte 🎉, without dependencies
|
|
8
|
+
</div>
|
|
9
|
+
|
|
10
|
+
## Features
|
|
11
|
+
|
|
12
|
+
* Uses a single canvas to render full-screen confetti.
|
|
13
|
+
* Supports image-based confetti.
|
|
14
|
+
* Allows full customization of confetti behavior using `onCreate` and `onUpdate` hooks.
|
|
15
|
+
|
|
16
|
+
## Examples
|
|
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)
|
|
23
|
+
|
|
24
|
+
## Installing
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npm i @castlenine/svelte-canvas-confetti
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Basic Usage
|
|
31
|
+
|
|
32
|
+
The package includes four Svelte components.
|
|
33
|
+
|
|
34
|
+
### FallingConfetti
|
|
35
|
+
|
|
36
|
+
Adds confetti falling from the top of the screen.
|
|
37
|
+
|
|
38
|
+
```svelte
|
|
39
|
+
<script>
|
|
40
|
+
import { FallingConfetti } from '@castlenine/svelte-canvas-confetti';
|
|
41
|
+
</script>
|
|
42
|
+
|
|
43
|
+
<FallingConfetti />
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### ConfettiBurst
|
|
47
|
+
|
|
48
|
+
Adds a confetti burst anywhere on the screen. It requires an origin position.
|
|
49
|
+
|
|
50
|
+
```svelte
|
|
51
|
+
<script>
|
|
52
|
+
import { ConfettiBurst } from '@castlenine/svelte-canvas-confetti';
|
|
53
|
+
</script>
|
|
54
|
+
|
|
55
|
+
<ConfettiBurst origin={[window.innerWidth / 2, window.innerHeight / 2]} />
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### ConfettiCannon
|
|
59
|
+
|
|
60
|
+
Adds a confetti cannon that can shoot out directional confetti. It requires an origin position.
|
|
61
|
+
|
|
62
|
+
```svelte
|
|
63
|
+
<script>
|
|
64
|
+
import { ConfettiCannon } from '@castlenine/svelte-canvas-confetti';
|
|
65
|
+
</script>
|
|
66
|
+
|
|
67
|
+
<ConfettiCannon origin={[window.innerWidth / 2, window.innerHeight]} />
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Confetti
|
|
71
|
+
|
|
72
|
+
Adds any type of confetti. This is the main component that the other three are just simple wrappers around.
|
|
73
|
+
|
|
74
|
+
If no properties are passed in, it will create the same result as **FallingConfetti**.
|
|
75
|
+
|
|
76
|
+
```svelte
|
|
77
|
+
<script>
|
|
78
|
+
import { Confetti } from '@castlenine/svelte-canvas-confetti';
|
|
79
|
+
</script>
|
|
80
|
+
|
|
81
|
+
<Confetti />
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Props
|
|
85
|
+
|
|
86
|
+
### particleCount
|
|
87
|
+
|
|
88
|
+
Number of particles to create.
|
|
89
|
+
|
|
90
|
+
**Type:** `number`
|
|
91
|
+
**Default value:** `50`
|
|
92
|
+
**Example:**
|
|
93
|
+
|
|
94
|
+
```svelte
|
|
95
|
+
<Confetti particleCount={100} />
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### styles
|
|
99
|
+
|
|
100
|
+
A list of styles used to render particles. Can be any valid HTML color or an HTMLImageElement.
|
|
101
|
+
|
|
102
|
+
**Type:** `Array<string | HTMLImageElement>`
|
|
103
|
+
**Default value:** `['hotpink','gold','dodgerblue','tomato','rebeccapurple','lightgreen','turquoise']`
|
|
104
|
+
**Example:**
|
|
105
|
+
|
|
106
|
+
```svelte
|
|
107
|
+
<Confetti styles={['red', '#00ff00', 'hsl(120, 65%, 85%)']} />
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### origin
|
|
111
|
+
|
|
112
|
+
The origin of the particles. If this is not used, the particles will fall from the top of the screen.
|
|
113
|
+
|
|
114
|
+
**Type:** `[number, number]`
|
|
115
|
+
**Default value:** `undefined`
|
|
116
|
+
**Example:**
|
|
117
|
+
|
|
118
|
+
```svelte
|
|
119
|
+
<Confetti origin={[100, 100]} />
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### force
|
|
123
|
+
|
|
124
|
+
The initial force used to shoot out confetti. This has no effect if `origin` is not used.
|
|
125
|
+
|
|
126
|
+
**Type:** `number`
|
|
127
|
+
**Default value:** 15
|
|
128
|
+
**Example:**
|
|
129
|
+
|
|
130
|
+
```svelte
|
|
131
|
+
<Confetti origin={[50, 50]} force={25} />
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### angle
|
|
135
|
+
|
|
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".
|
|
137
|
+
|
|
138
|
+
**Type:** `number`
|
|
139
|
+
**Default value:** 0
|
|
140
|
+
**Example:**
|
|
141
|
+
|
|
142
|
+
```svelte
|
|
143
|
+
<Confetti origin={[50, 50]} angle={90} />
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### spread
|
|
147
|
+
|
|
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.
|
|
149
|
+
|
|
150
|
+
**Type:** `number`
|
|
151
|
+
**Default value:** 360
|
|
152
|
+
**Example:**
|
|
153
|
+
|
|
154
|
+
```svelte
|
|
155
|
+
<Confetti origin={[100, 100]} spread={45} />
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## onCreate
|
|
159
|
+
|
|
160
|
+
This can be used to override the properties of each particle at creation time.
|
|
161
|
+
|
|
162
|
+
**Type:** `(particle) => particle`
|
|
163
|
+
**Default value:** undefined
|
|
164
|
+
**Example:**
|
|
165
|
+
|
|
166
|
+
```svelte
|
|
167
|
+
<Confetti
|
|
168
|
+
onCreate={(particle) => {
|
|
169
|
+
particle.x = 0;
|
|
170
|
+
particle.y = 0;
|
|
171
|
+
return particle;
|
|
172
|
+
}}
|
|
173
|
+
/>
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## onUpdate
|
|
177
|
+
|
|
178
|
+
This can be used to override the properties of each particle at update time.
|
|
179
|
+
|
|
180
|
+
**Type:** `(particle, deltaTime) => void`
|
|
181
|
+
**Default value:** undefined
|
|
182
|
+
**Example:**
|
|
183
|
+
|
|
184
|
+
```svelte
|
|
185
|
+
<Confetti
|
|
186
|
+
onCreate={(particle) => {
|
|
187
|
+
particle.x += Math.random() * 5;
|
|
188
|
+
}}
|
|
189
|
+
/>
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## Particle object
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
export type Particle = {
|
|
196
|
+
// Stop updating/rendering the particle once it is "dead" (ie off screen)
|
|
197
|
+
dead: boolean;
|
|
198
|
+
|
|
199
|
+
// The total time since the particle was created.
|
|
200
|
+
life: number;
|
|
201
|
+
|
|
202
|
+
// The delay between the creation of the particle and when it starts updating/rendering (in seconds).
|
|
203
|
+
delay: number;
|
|
204
|
+
|
|
205
|
+
// The x position of the particle.
|
|
206
|
+
x: number;
|
|
207
|
+
|
|
208
|
+
// The y position of the particle.
|
|
209
|
+
y: number;
|
|
210
|
+
|
|
211
|
+
// The current angle of the particle.
|
|
212
|
+
angle: number;
|
|
213
|
+
|
|
214
|
+
// The rotation speed of the particle.
|
|
215
|
+
da: number;
|
|
216
|
+
|
|
217
|
+
// The horizontal speed of the particle.
|
|
218
|
+
dx: number;
|
|
219
|
+
|
|
220
|
+
// The vertical speed of the particle.
|
|
221
|
+
dy: number;
|
|
222
|
+
|
|
223
|
+
// The width of the particle (not used with images).
|
|
224
|
+
w: number;
|
|
225
|
+
|
|
226
|
+
// The height of the particle (not used with images).
|
|
227
|
+
h: number;
|
|
228
|
+
|
|
229
|
+
// Vertical gravity.
|
|
230
|
+
gy: number;
|
|
231
|
+
|
|
232
|
+
// The "width" of the falling motion. The falling motion is calculated as Math.sin(life * xw)
|
|
233
|
+
xw: number;
|
|
234
|
+
|
|
235
|
+
// The style of the particle. Either an HTML color or an HTMLImageElement.
|
|
236
|
+
style: ParticleStyle;
|
|
237
|
+
};
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
Forked from [andreasmcdermott/svelte-canvas-confetti](https://github.com/andreasmcdermott/svelte-canvas-confetti)
|
|
243
|
+
|
|
244
|
+
[npm]: https://www.npmjs.com/package/@castlenine/svelte-canvas-confetti
|
|
245
|
+
[npm.badge]: https://img.shields.io/npm/v/@castlenine/svelte-canvas-confetti
|
|
246
|
+
[download]: https://www.npmjs.com/package/@castlenine/svelte-canvas-confetti
|
|
247
|
+
[download.badge]: https://img.shields.io/npm/d18m/@castlenine/svelte-canvas-confetti
|
|
@@ -0,0 +1,85 @@
|
|
|
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
|
+
};
|
|
50
|
+
</script>
|
|
51
|
+
|
|
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
|
+
});
|
|
70
|
+
</script>
|
|
71
|
+
|
|
72
|
+
<svelte:window bind:innerWidth={w} bind:innerHeight={h} />
|
|
73
|
+
<canvas bind:this={canvas} width={w} height={h} />
|
|
74
|
+
|
|
75
|
+
<style>
|
|
76
|
+
canvas {
|
|
77
|
+
position: fixed;
|
|
78
|
+
top: 0;
|
|
79
|
+
left: 0;
|
|
80
|
+
z-index: 999999;
|
|
81
|
+
width: 100%;
|
|
82
|
+
height: 100%;
|
|
83
|
+
pointer-events: none;
|
|
84
|
+
}
|
|
85
|
+
</style>
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
|
+
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: {};
|
|
89
|
+
};
|
|
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 {};
|
|
96
|
+
//# sourceMappingURL=Confetti.svelte.d.ts.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<script>import Confetti from "./Confetti.svelte";
|
|
2
|
+
export let origin;
|
|
3
|
+
export let styles = void 0;
|
|
4
|
+
export let particleCount = 50;
|
|
5
|
+
export let onCreate = void 0;
|
|
6
|
+
export let onUpdate = void 0;
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<Confetti {particleCount} {origin} {styles} {onCreate} {onUpdate} on:completed />
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
|
+
import type { OnCreateParticle, OnUpdateParticle, ParticleStyle, Position } from './utils/types';
|
|
3
|
+
declare const __propDef: {
|
|
4
|
+
props: {
|
|
5
|
+
/**
|
|
6
|
+
* The origin position of the confetti burst.
|
|
7
|
+
* @required
|
|
8
|
+
* @example
|
|
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: {};
|
|
65
|
+
};
|
|
66
|
+
export type ConfettiBurstProps = typeof __propDef.props;
|
|
67
|
+
export type ConfettiBurstEvents = typeof __propDef.events;
|
|
68
|
+
export type ConfettiBurstSlots = typeof __propDef.slots;
|
|
69
|
+
export default class ConfettiBurst extends SvelteComponentTyped<ConfettiBurstProps, ConfettiBurstEvents, ConfettiBurstSlots> {
|
|
70
|
+
}
|
|
71
|
+
export {};
|
|
72
|
+
//# sourceMappingURL=ConfettiBurst.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConfettiBurst.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/ConfettiBurst.svelte"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,QAAQ,CAE5C;AACD,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AA8HjG,QAAA,MAAM,SAAS;;QArDf;;;;;;;eAOI;QACJ;;;;;;;;eAQI,UAAS,aAAa,EAAE,GAAG,SAAS;QACxC;;;;;;;eAOI;QACJ;;;;;;;;;;;;;eAaI,YAAW,gBAAgB,GAAG,SAAS;QAC3C;;;;;;;;;;;;;eAaI,YAAW,gBAAgB,GAAG,SAAS;;;;;;;;CACY,CAAC;AACxD,MAAM,MAAM,kBAAkB,GAAG,OAAO,SAAS,CAAC,KAAK,CAAC;AACxD,MAAM,MAAM,mBAAmB,GAAG,OAAO,SAAS,CAAC,MAAM,CAAC;AAC1D,MAAM,MAAM,kBAAkB,GAAG,OAAO,SAAS,CAAC,KAAK,CAAC;AAExD,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,oBAAoB,CAAC,kBAAkB,EAAE,mBAAmB,EAAE,kBAAkB,CAAC;CAC3H"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<script>import Confetti from "./Confetti.svelte";
|
|
2
|
+
export let origin;
|
|
3
|
+
export let styles = void 0;
|
|
4
|
+
export let particleCount = 50;
|
|
5
|
+
export let force = 15;
|
|
6
|
+
export let angle = -90;
|
|
7
|
+
export let spread = 360;
|
|
8
|
+
export let onCreate = void 0;
|
|
9
|
+
export let onUpdate = void 0;
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<Confetti {particleCount} {origin} {force} {spread} {angle} {styles} {onCreate} {onUpdate} on:completed />
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
|
+
import type { OnCreateParticle, OnUpdateParticle, ParticleStyle, Position } from './utils/types';
|
|
3
|
+
declare const __propDef: {
|
|
4
|
+
props: {
|
|
5
|
+
/**
|
|
6
|
+
* The origin position of the confetti cannon.
|
|
7
|
+
* @required
|
|
8
|
+
* @example
|
|
9
|
+
* ```
|
|
10
|
+
* <ConfettiCannon 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
|
+
* <ConfettiCannon 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
|
+
* <ConfettiCannon particleCount={100} />
|
|
28
|
+
* ```
|
|
29
|
+
*/ particleCount?: number | 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
|
+
* <ConfettiCannon 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
|
+
* <ConfettiCannon 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
|
+
* <ConfettiCannon 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
|
+
* <ConfettiCannon
|
|
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
|
+
* <ConfettiCannon
|
|
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: {};
|
|
89
|
+
};
|
|
90
|
+
export type ConfettiCannonProps = typeof __propDef.props;
|
|
91
|
+
export type ConfettiCannonEvents = typeof __propDef.events;
|
|
92
|
+
export type ConfettiCannonSlots = typeof __propDef.slots;
|
|
93
|
+
export default class ConfettiCannon extends SvelteComponentTyped<ConfettiCannonProps, ConfettiCannonEvents, ConfettiCannonSlots> {
|
|
94
|
+
}
|
|
95
|
+
export {};
|
|
96
|
+
//# sourceMappingURL=ConfettiCannon.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConfettiCannon.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/ConfettiCannon.svelte"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,QAAQ,CAE5C;AACD,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAiLjG,QAAA,MAAM,SAAS;;QA7Ef;;;;;;;eAOI;QACJ;;;;;;;;eAQI,UAAS,aAAa,EAAE,GAAG,SAAS;QACxC;;;;;;;eAOI;QACJ;;;;;;;eAOI;QACJ;;;;;;;eAOI;QACJ;;;;;;;eAOI;QACJ;;;;;;;;;;;;;eAaI,YAAW,gBAAgB,GAAG,SAAS;QAC3C;;;;;;;;;;;;;eAaI,YAAW,gBAAgB,GAAG,SAAS;;;;;;;;CACY,CAAC;AACxD,MAAM,MAAM,mBAAmB,GAAG,OAAO,SAAS,CAAC,KAAK,CAAC;AACzD,MAAM,MAAM,oBAAoB,GAAG,OAAO,SAAS,CAAC,MAAM,CAAC;AAC3D,MAAM,MAAM,mBAAmB,GAAG,OAAO,SAAS,CAAC,KAAK,CAAC;AAEzD,MAAM,CAAC,OAAO,OAAO,cAAe,SAAQ,oBAAoB,CAAC,mBAAmB,EAAE,oBAAoB,EAAE,mBAAmB,CAAC;CAC/H"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
|
+
import type { OnCreateParticle, OnUpdateParticle, ParticleStyle } 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
|
+
* By default, each particle is created with some random variation. The initial values of each particle can be overridden using the onCreate callback.
|
|
24
|
+
* @default undefined
|
|
25
|
+
* @example
|
|
26
|
+
* ```
|
|
27
|
+
* <Confetti
|
|
28
|
+
* onCreate={(particle) => {
|
|
29
|
+
* particle.style = 'blue';
|
|
30
|
+
* particle.x = window.innerWidth / 2;
|
|
31
|
+
* return particle;
|
|
32
|
+
* }}
|
|
33
|
+
* />
|
|
34
|
+
* ```
|
|
35
|
+
*/ onCreate?: OnCreateParticle | undefined;
|
|
36
|
+
/**
|
|
37
|
+
* The onUpdate callback can be used to modify the particle on each frame.
|
|
38
|
+
* @default undefined
|
|
39
|
+
* @example
|
|
40
|
+
* ```
|
|
41
|
+
* <Confetti
|
|
42
|
+
* onUpdate={(particle, deltaTime) => {
|
|
43
|
+
* if (particle.angle < 0 && particle.da < 0) {
|
|
44
|
+
* particle.da *= -1;
|
|
45
|
+
* }
|
|
46
|
+
* }}
|
|
47
|
+
* />
|
|
48
|
+
* ```
|
|
49
|
+
*/ onUpdate?: OnUpdateParticle | undefined;
|
|
50
|
+
};
|
|
51
|
+
events: {
|
|
52
|
+
completed: CustomEvent<any>;
|
|
53
|
+
} & {
|
|
54
|
+
[evt: string]: CustomEvent<any>;
|
|
55
|
+
};
|
|
56
|
+
slots: {};
|
|
57
|
+
};
|
|
58
|
+
export type FallingConfettiProps = typeof __propDef.props;
|
|
59
|
+
export type FallingConfettiEvents = typeof __propDef.events;
|
|
60
|
+
export type FallingConfettiSlots = typeof __propDef.slots;
|
|
61
|
+
export default class FallingConfetti extends SvelteComponentTyped<FallingConfettiProps, FallingConfettiEvents, FallingConfettiSlots> {
|
|
62
|
+
}
|
|
63
|
+
export {};
|
|
64
|
+
//# sourceMappingURL=FallingConfetti.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FallingConfetti.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/FallingConfetti.svelte"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,QAAQ,CAE5C;AACD,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AA6GvF,QAAA,MAAM,SAAS;;QA7Cf;;;;;;;;eAQI,UAAS,aAAa,EAAE,GAAG,SAAS;QACxC;;;;;;;eAOI;QACJ;;;;;;;;;;;;;eAaI,YAAW,gBAAgB,GAAG,SAAS;QAC3C;;;;;;;;;;;;;eAaI,YAAW,gBAAgB,GAAG,SAAS;;;;;;;;CACY,CAAC;AACxD,MAAM,MAAM,oBAAoB,GAAG,OAAO,SAAS,CAAC,KAAK,CAAC;AAC1D,MAAM,MAAM,qBAAqB,GAAG,OAAO,SAAS,CAAC,MAAM,CAAC;AAC5D,MAAM,MAAM,oBAAoB,GAAG,OAAO,SAAS,CAAC,KAAK,CAAC;AAE1D,MAAM,CAAC,OAAO,OAAO,eAAgB,SAAQ,oBAAoB,CAAC,oBAAoB,EAAE,qBAAqB,EAAE,oBAAoB,CAAC;CACnI"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type { Particle, OnCreateParticle, OnUpdateParticle } from './utils/types';
|
|
2
|
+
export { default as FallingConfetti } from './FallingConfetti.svelte';
|
|
3
|
+
export { default as ConfettiBurst } from './ConfettiBurst.svelte';
|
|
4
|
+
export { default as ConfettiCannon } from './ConfettiCannon.svelte';
|
|
5
|
+
export { default as Confetti } from './Confetti.svelte';
|
|
6
|
+
export * from './utils/random';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,QAAQ,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAElF,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACxD,cAAc,gBAAgB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { default as FallingConfetti } from './FallingConfetti.svelte';
|
|
2
|
+
export { default as ConfettiBurst } from './ConfettiBurst.svelte';
|
|
3
|
+
export { default as ConfettiCannon } from './ConfettiCannon.svelte';
|
|
4
|
+
export { default as Confetti } from './Confetti.svelte';
|
|
5
|
+
export * from './utils/random';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../../src/lib/utils/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU,QAAgB,CAAC;AAExC,eAAO,MAAM,cAAc,IAAI,CAAC;AAEhC,eAAO,MAAM,cAAc,IAAI,CAAC;AAEhC,eAAO,MAAM,QAAQ,KAAK,CAAC;AAE3B,eAAO,MAAM,MAAM,UAA0F,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { OnCreateParticle, Particle, Position } from './types';
|
|
2
|
+
export declare const createParticle: (context: CanvasRenderingContext2D, origin: Position | undefined, force: number, angle: number, spread: number, styles: (HTMLImageElement | string)[], onCreate?: OnCreateParticle) => Particle;
|
|
3
|
+
export declare const renderParticle: (context: CanvasRenderingContext2D, p: Particle) => void;
|
|
4
|
+
export declare const updateParticle: (p: Particle, dt: number) => void;
|
|
5
|
+
export declare const isOutOfBounds: (context: CanvasRenderingContext2D, p: Particle) => boolean;
|
|
6
|
+
//# sourceMappingURL=particle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"particle.d.ts","sourceRoot":"","sources":["../../../../src/lib/utils/particle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAKpE,eAAO,MAAM,cAAc,YACjB,wBAAwB,UACzB,QAAQ,GAAG,SAAS,SACrB,MAAM,SACN,MAAM,UACL,MAAM,UACN,CAAC,gBAAgB,GAAG,MAAM,CAAC,EAAE,aAC1B,gBAAgB,aAqD3B,CAAC;AAEF,eAAO,MAAM,cAAc,YAAa,wBAAwB,KAAK,QAAQ,SAc5E,CAAC;AAEF,eAAO,MAAM,cAAc,MAAO,QAAQ,MAAM,MAAM,SAUrD,CAAC;AAEF,eAAO,MAAM,aAAa,YAAa,wBAAwB,KAAK,QAAQ,YACuB,CAAC"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { BOUNDARY, DEG_TO_RAD, MOVEMENT_SPEED, ROTATION_SPEED } from './constants';
|
|
2
|
+
import { random } from './random';
|
|
3
|
+
export const createParticle = (context, origin, force, angle, spread, styles, onCreate) => {
|
|
4
|
+
let dir;
|
|
5
|
+
let x;
|
|
6
|
+
let y;
|
|
7
|
+
let vx;
|
|
8
|
+
let vy;
|
|
9
|
+
let dx;
|
|
10
|
+
let dy;
|
|
11
|
+
const style = styles[Math.floor(random(styles.length))];
|
|
12
|
+
let da = random(90, -90);
|
|
13
|
+
if (origin) {
|
|
14
|
+
// When we have an origin, we create a confetti burst
|
|
15
|
+
x = origin[0];
|
|
16
|
+
y = origin[1];
|
|
17
|
+
vx = random(force, 5);
|
|
18
|
+
vy = random(force, 5);
|
|
19
|
+
dir = random(angle + spread / 2, angle - spread / 2) * DEG_TO_RAD;
|
|
20
|
+
da *= 2;
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
// Otherwise we drop confetti from the top of the screen
|
|
24
|
+
x = random(context.canvas.width);
|
|
25
|
+
y = random(-BOUNDARY);
|
|
26
|
+
vx = random(5);
|
|
27
|
+
vy = random(5, 1);
|
|
28
|
+
dir = random(180) * DEG_TO_RAD;
|
|
29
|
+
}
|
|
30
|
+
// eslint-disable-next-line prefer-const
|
|
31
|
+
dx = Math.cos(dir);
|
|
32
|
+
// eslint-disable-next-line prefer-const
|
|
33
|
+
dy = Math.sin(dir);
|
|
34
|
+
let particle = {
|
|
35
|
+
dead: false,
|
|
36
|
+
life: 0,
|
|
37
|
+
delay: 0,
|
|
38
|
+
x,
|
|
39
|
+
y,
|
|
40
|
+
angle: random(360),
|
|
41
|
+
da,
|
|
42
|
+
dx: dx * vx,
|
|
43
|
+
dy: dy * vy,
|
|
44
|
+
w: random(18, 10),
|
|
45
|
+
h: random(6, 4),
|
|
46
|
+
gy: random(4.5, 2),
|
|
47
|
+
xw: random(6, 1),
|
|
48
|
+
style,
|
|
49
|
+
};
|
|
50
|
+
if (onCreate)
|
|
51
|
+
particle = onCreate(particle);
|
|
52
|
+
return particle;
|
|
53
|
+
};
|
|
54
|
+
export const renderParticle = (context, p) => {
|
|
55
|
+
if (p.dead || p.life < p.delay)
|
|
56
|
+
return;
|
|
57
|
+
context.save();
|
|
58
|
+
context.translate(p.x, p.y);
|
|
59
|
+
context.rotate(p.angle * DEG_TO_RAD);
|
|
60
|
+
if (p.style instanceof HTMLImageElement) {
|
|
61
|
+
context.drawImage(p.style, -p.style.width / 2, -p.style.height / 2);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
context.fillStyle = p.style;
|
|
65
|
+
context.beginPath();
|
|
66
|
+
context.rect(p.w * -0.5, p.h * -0.5, p.w, p.h);
|
|
67
|
+
context.fill();
|
|
68
|
+
}
|
|
69
|
+
context.restore();
|
|
70
|
+
};
|
|
71
|
+
export const updateParticle = (p, dt) => {
|
|
72
|
+
p.life += dt;
|
|
73
|
+
if (p.dead || p.life < p.delay)
|
|
74
|
+
return;
|
|
75
|
+
p.angle += p.da * dt * ROTATION_SPEED;
|
|
76
|
+
p.dy += p.gy * dt * ROTATION_SPEED;
|
|
77
|
+
p.dx += random(4, 2) * Math.sin(p.life * p.xw) * dt;
|
|
78
|
+
p.dx *= 0.98;
|
|
79
|
+
p.dy *= 0.98;
|
|
80
|
+
p.x += p.dx * MOVEMENT_SPEED;
|
|
81
|
+
p.y += p.dy * MOVEMENT_SPEED;
|
|
82
|
+
};
|
|
83
|
+
export const isOutOfBounds = (context, p) => p.x < -BOUNDARY || p.x > context.canvas.width + BOUNDARY || p.y > context.canvas.height + BOUNDARY;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"random.d.ts","sourceRoot":"","sources":["../../../../src/lib/utils/random.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,MAAM,QAAS,MAAM,yBAA+C,CAAC;AAElF,eAAO,MAAM,QAAQ,eAA6B,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export type ParticleStyle = string | HTMLImageElement;
|
|
2
|
+
export type Position = [number, number];
|
|
3
|
+
export type Particle = {
|
|
4
|
+
dead: boolean;
|
|
5
|
+
life: number;
|
|
6
|
+
delay: number;
|
|
7
|
+
x: number;
|
|
8
|
+
y: number;
|
|
9
|
+
angle: number;
|
|
10
|
+
da: number;
|
|
11
|
+
dx: number;
|
|
12
|
+
dy: number;
|
|
13
|
+
w: number;
|
|
14
|
+
h: number;
|
|
15
|
+
gy: number;
|
|
16
|
+
xw: number;
|
|
17
|
+
style: ParticleStyle;
|
|
18
|
+
};
|
|
19
|
+
export type OnCreateParticle = (p: Particle) => Particle;
|
|
20
|
+
export type OnUpdateParticle = (p: Particle, dt: number) => void;
|
|
21
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/lib/utils/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,gBAAgB,CAAC;AAEtD,MAAM,MAAM,QAAQ,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAExC,MAAM,MAAM,QAAQ,GAAG;IACtB,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,aAAa,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,EAAE,QAAQ,KAAK,QAAQ,CAAC;AAEzD,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@castlenine/svelte-canvas-confetti",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Canvas-based confetti for Svelte, without dependencies",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"svelte",
|
|
8
|
+
"sveltekit",
|
|
9
|
+
"confetti",
|
|
10
|
+
"canvas"
|
|
11
|
+
],
|
|
12
|
+
"author": {
|
|
13
|
+
"name": "Alexandre Castlenine",
|
|
14
|
+
"url": "https://github.com/Castlenine"
|
|
15
|
+
},
|
|
16
|
+
"homepage": "https://github.com/castlenine/svelte-canvas-confetti",
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/castlenine/svelte-canvas-confetti.git"
|
|
20
|
+
},
|
|
21
|
+
"bugs": {
|
|
22
|
+
"url": "https://github.com/castlenine/svelte-canvas-confetti/issues"
|
|
23
|
+
},
|
|
24
|
+
"type": "module",
|
|
25
|
+
"types": "./dist/index.d.ts",
|
|
26
|
+
"import": "./dist/index.js",
|
|
27
|
+
"svelte": "./dist/index.js",
|
|
28
|
+
"exports": {
|
|
29
|
+
".": {
|
|
30
|
+
"types": "./dist/index.d.ts",
|
|
31
|
+
"import": "./dist/index.js",
|
|
32
|
+
"svelte": "./dist/index.js"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"files": [
|
|
36
|
+
"dist"
|
|
37
|
+
],
|
|
38
|
+
"scripts": {
|
|
39
|
+
"dev": "vite dev",
|
|
40
|
+
"build": "npm run check && vite build",
|
|
41
|
+
"preview": "vite preview",
|
|
42
|
+
"package": "npm run remove-dist-folder && svelte-kit sync && svelte-package && publint",
|
|
43
|
+
"prepublishOnly": "npm run package",
|
|
44
|
+
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
|
45
|
+
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
|
46
|
+
"eslint": "eslint --ignore-path ./.eslintignore .",
|
|
47
|
+
"eslint:fix": "eslint --fix --ignore-path ./.eslintignore .",
|
|
48
|
+
"prettier": "prettier --ignore-path ./.prettierignore --check .",
|
|
49
|
+
"prettier:fix": "prettier --ignore-path ./.prettierignore --write .",
|
|
50
|
+
"stylelint": "stylelint **/*.{css,scss,sass,html,js,md,mjs,svelte,svg,ts}",
|
|
51
|
+
"clean-code": "npm run stylelint && npm run prettier:fix && npm run eslint:fix",
|
|
52
|
+
"remove-dist-folder": "rimraf dist",
|
|
53
|
+
"publish-package": "npm publish -access public"
|
|
54
|
+
},
|
|
55
|
+
"peerDependencies": {
|
|
56
|
+
"svelte": "^3.54.0 || ^4.0.0"
|
|
57
|
+
},
|
|
58
|
+
"devDependencies": {
|
|
59
|
+
"@sveltejs/adapter-static": "^2.0.3",
|
|
60
|
+
"@sveltejs/kit": "^1.30.4",
|
|
61
|
+
"@sveltejs/package": "^2.3.1",
|
|
62
|
+
"@typescript-eslint/eslint-plugin": "^7.8.0",
|
|
63
|
+
"@typescript-eslint/parser": "^7.8.0",
|
|
64
|
+
"eslint": "^8.57.0",
|
|
65
|
+
"eslint-config-prettier": "^9.1.0",
|
|
66
|
+
"eslint-import-resolver-typescript": "^3.6.1",
|
|
67
|
+
"eslint-plugin-html": "^8.1.1",
|
|
68
|
+
"eslint-plugin-import": "^2.29.1",
|
|
69
|
+
"eslint-plugin-no-loops": "^0.3.0",
|
|
70
|
+
"eslint-plugin-only-warn": "^1.1.0",
|
|
71
|
+
"eslint-plugin-prettier": "^5.1.3",
|
|
72
|
+
"eslint-plugin-security": "^1.7.1",
|
|
73
|
+
"eslint-plugin-svelte": "^2.38.0",
|
|
74
|
+
"prettier": "^3.2.5",
|
|
75
|
+
"prettier-eslint": "^16.3.0",
|
|
76
|
+
"prettier-eslint-cli": "^8.0.1",
|
|
77
|
+
"prettier-plugin-svelte": "^3.2.3",
|
|
78
|
+
"prettier-stylelint": "^0.4.2",
|
|
79
|
+
"publint": "^0.2.7",
|
|
80
|
+
"rimraf": "^5.0.5",
|
|
81
|
+
"stylelint": "^15.11.0",
|
|
82
|
+
"stylelint-config-html": "^1.1.0",
|
|
83
|
+
"stylelint-config-standard": "^34.0.0",
|
|
84
|
+
"stylelint-no-unsupported-browser-features": "^7.0.0",
|
|
85
|
+
"stylelint-order": "^6.0.4",
|
|
86
|
+
"stylelint-scss": "^5.3.2",
|
|
87
|
+
"stylelint-selector-bem-pattern": "^3.0.1",
|
|
88
|
+
"svelte": "^4.2.15",
|
|
89
|
+
"svelte-check": "^3.7.1",
|
|
90
|
+
"svelte-eslint-parser": "^0.35.0",
|
|
91
|
+
"svelte-preprocess": "^5.1.4",
|
|
92
|
+
"tslib": "^2.6.2",
|
|
93
|
+
"typescript": "^5.4.5",
|
|
94
|
+
"vite": "^4.5.3"
|
|
95
|
+
}
|
|
96
|
+
}
|