@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 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,8 @@
1
+ <script>import Confetti from "./Confetti.svelte";
2
+ export let styles = void 0;
3
+ export let particleCount = 50;
4
+ export let onCreate = void 0;
5
+ export let onUpdate = void 0;
6
+ </script>
7
+
8
+ <Confetti {particleCount} {styles} {onCreate} {onUpdate} on:completed />
@@ -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"}
@@ -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,6 @@
1
+ export declare const DEG_TO_RAD: number;
2
+ export declare const ROTATION_SPEED = 2;
3
+ export declare const MOVEMENT_SPEED = 1;
4
+ export declare const BOUNDARY = 20;
5
+ export declare const COLORS: string[];
6
+ //# sourceMappingURL=constants.d.ts.map
@@ -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,5 @@
1
+ export const DEG_TO_RAD = Math.PI / 180;
2
+ export const ROTATION_SPEED = 2;
3
+ export const MOVEMENT_SPEED = 1;
4
+ export const BOUNDARY = 20;
5
+ export const COLORS = ['hotpink', 'gold', 'dodgerblue', 'tomato', 'rebeccapurple', 'lightgreen', 'turquoise'];
@@ -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,3 @@
1
+ export declare const random: (max: number, min?: number) => number;
2
+ export declare const coinFlip: () => boolean;
3
+ //# sourceMappingURL=random.d.ts.map
@@ -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,2 @@
1
+ export const random = (max, min = 0) => Math.random() * (max - min) + min;
2
+ export const coinFlip = () => Math.random() >= 0.5;
@@ -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
+ }