@castlenine/svelte-canvas-confetti 1.0.0 → 1.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.
@@ -1,6 +1,6 @@
1
1
  # MIT License
2
2
 
3
- Copyright (c) 2024 Alexandre "Castlenine"
3
+ Copyright (c) 2024–present Alex "Castlenine"
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -2,16 +2,16 @@
2
2
 
3
3
  # `@castlenine/svelte-canvas-confetti`
4
4
 
5
- [![npm.badge]][npm] [![download.badge]][download]
5
+ [![npm.badge]][npm] [![download.badge]][download] [![contribution.badge]][contribution]
6
6
 
7
- Canvas-based confetti for Svelte 🎉, without dependencies
7
+ Canvas-based confetti for Svelte 🎉, with no dependencies.
8
8
  </div>
9
9
 
10
10
  ## Features
11
11
 
12
12
  * Uses a single canvas to render full-screen confetti.
13
13
  * Supports image-based confetti.
14
- * Allows full customization of confetti behavior using `onCreate` and `onUpdate` hooks.
14
+ * Allows full customization of confetti behavior using the `onCreate` and `onUpdate` hooks.
15
15
 
16
16
  ## Examples
17
17
 
@@ -21,9 +21,11 @@ Canvas-based confetti for Svelte 🎉, without dependencies
21
21
 
22
22
  [Advanced Demo](https://svelte.dev/repl/5cefe21763c445d986c6e23ddea1327a?version=3.50.1)
23
23
 
24
- ## Installing
24
+ ## Installation
25
25
 
26
- ```bash
26
+ Use your package manager to install:
27
+
28
+ ```shell
27
29
  npm i @castlenine/svelte-canvas-confetti
28
30
  ```
29
31
 
@@ -45,7 +47,7 @@ Adds confetti falling from the top of the screen.
45
47
 
46
48
  ### ConfettiBurst
47
49
 
48
- Adds a confetti burst anywhere on the screen. It requires an origin position.
50
+ Adds a confetti burst anywhere on the screen. Requires an origin position.
49
51
 
50
52
  ```svelte
51
53
  <script>
@@ -57,7 +59,7 @@ Adds a confetti burst anywhere on the screen. It requires an origin position.
57
59
 
58
60
  ### ConfettiCannon
59
61
 
60
- Adds a confetti cannon that can shoot out directional confetti. It requires an origin position.
62
+ Adds a confetti cannon that can shoot directional confetti. Requires an origin position.
61
63
 
62
64
  ```svelte
63
65
  <script>
@@ -69,9 +71,9 @@ Adds a confetti cannon that can shoot out directional confetti. It requires an o
69
71
 
70
72
  ### Confetti
71
73
 
72
- Adds any type of confetti. This is the main component that the other three are just simple wrappers around.
74
+ Adds any type of confetti. This is the main component, and the other three are simple wrappers around it.
73
75
 
74
- If no properties are passed in, it will create the same result as **FallingConfetti**.
76
+ If no properties are passed in, it will behave the same as **FallingConfetti**.
75
77
 
76
78
  ```svelte
77
79
  <script>
@@ -85,7 +87,7 @@ If no properties are passed in, it will create the same result as **FallingConfe
85
87
 
86
88
  ### particleCount
87
89
 
88
- Number of particles to create.
90
+ The number of particles to create.
89
91
 
90
92
  **Type:** `number`
91
93
  **Default value:** `50`
@@ -97,10 +99,10 @@ Number of particles to create.
97
99
 
98
100
  ### styles
99
101
 
100
- A list of styles used to render particles. Can be any valid HTML color or an HTMLImageElement.
102
+ A list of styles used to render particles. Can be any valid HTML color or an `HTMLImageElement`.
101
103
 
102
- **Type:** `Array<string | HTMLImageElement>`
103
- **Default value:** `['hotpink','gold','dodgerblue','tomato','rebeccapurple','lightgreen','turquoise']`
104
+ **Type:** `ParticleStyle[]`
105
+ **Default value:** `['hotpink', 'gold', 'dodgerblue', 'tomato', 'rebeccapurple', 'lightgreen', 'turquoise']`
104
106
  **Example:**
105
107
 
106
108
  ```svelte
@@ -109,9 +111,9 @@ A list of styles used to render particles. Can be any valid HTML color or an HTM
109
111
 
110
112
  ### origin
111
113
 
112
- The origin of the particles. If this is not used, the particles will fall from the top of the screen.
114
+ The origin of the particles. If this is not provided, the particles will fall from the top of the screen.
113
115
 
114
- **Type:** `[number, number]`
116
+ **Type:** `Position`
115
117
  **Default value:** `undefined`
116
118
  **Example:**
117
119
 
@@ -133,7 +135,7 @@ The initial force used to shoot out confetti. This has no effect if `origin` is
133
135
 
134
136
  ### angle
135
137
 
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".
138
+ The angle used to shoot out confetti. This has no effect if `origin` is not used. Can be combined with `spread` to create a "cannon" effect.
137
139
 
138
140
  **Type:** `number`
139
141
  **Default value:** 0
@@ -145,7 +147,7 @@ The angle used to shoot out confetti. This has no effect if `origin` is not used
145
147
 
146
148
  ### spread
147
149
 
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.
150
+ The spread used when creating each particle’s initial direction. The particle's initial direction will be a value between `angle - spread / 2` and `angle + spread / 2`. This has no effect if `origin` is not used.
149
151
 
150
152
  **Type:** `number`
151
153
  **Default value:** 360
@@ -160,7 +162,7 @@ The spread used when creating each particles initial direction. The particle's i
160
162
  This can be used to override the properties of each particle at creation time.
161
163
 
162
164
  **Type:** `(particle) => particle`
163
- **Default value:** undefined
165
+ **Default value:** `undefined`
164
166
  **Example:**
165
167
 
166
168
  ```svelte
@@ -178,12 +180,12 @@ This can be used to override the properties of each particle at creation time.
178
180
  This can be used to override the properties of each particle at update time.
179
181
 
180
182
  **Type:** `(particle, deltaTime) => void`
181
- **Default value:** undefined
183
+ **Default value:** `undefined`
182
184
  **Example:**
183
185
 
184
186
  ```svelte
185
187
  <Confetti
186
- onCreate={(particle) => {
188
+ onUpdate={(particle) => {
187
189
  particle.x += Math.random() * 5;
188
190
  }}
189
191
  />
@@ -193,7 +195,7 @@ This can be used to override the properties of each particle at update time.
193
195
 
194
196
  ```typescript
195
197
  export type Particle = {
196
- // Stop updating/rendering the particle once it is "dead" (ie off screen)
198
+ // Stop updating/rendering the particle once it is "dead" (i.e., off screen)
197
199
  dead: boolean;
198
200
 
199
201
  // The total time since the particle was created.
@@ -229,7 +231,7 @@ export type Particle = {
229
231
  // Vertical gravity.
230
232
  gy: number;
231
233
 
232
- // The "width" of the falling motion. The falling motion is calculated as Math.sin(life * xw)
234
+ // The "width" of the falling motion. The falling motion is calculated as Math.sin(life * xw).
233
235
  xw: number;
234
236
 
235
237
  // The style of the particle. Either an HTML color or an HTMLImageElement.
@@ -237,6 +239,22 @@ export type Particle = {
237
239
  };
238
240
  ```
239
241
 
242
+ ## Exported Types
243
+
244
+ The following types are exported from the package:
245
+
246
+ ```typescript
247
+ import type { Particle, ParticleStyle, Position, OnCreateParticle, OnUpdateParticle } from '@castlenine/svelte-canvas-confetti';
248
+ ```
249
+
250
+ | Type | Description |
251
+ | --- | --- |
252
+ | `Particle` | The particle object used in `onCreate` and `onUpdate` callbacks. |
253
+ | `ParticleStyle` | `string \| HTMLImageElement` — a valid HTML color or an image element. |
254
+ | `Position` | `[number, number]` — an `[x, y]` coordinate tuple. |
255
+ | `OnCreateParticle` | `(p: Particle) => Particle` — callback to customize particles at creation. |
256
+ | `OnUpdateParticle` | `(p: Particle, dt: number) => void` — callback to modify particles each frame. |
257
+
240
258
  ---
241
259
 
242
260
  Forked from [andreasmcdermott/svelte-canvas-confetti](https://github.com/andreasmcdermott/svelte-canvas-confetti)
@@ -245,3 +263,5 @@ Forked from [andreasmcdermott/svelte-canvas-confetti](https://github.com/andreas
245
263
  [npm.badge]: https://img.shields.io/npm/v/@castlenine/svelte-canvas-confetti
246
264
  [download]: https://www.npmjs.com/package/@castlenine/svelte-canvas-confetti
247
265
  [download.badge]: https://img.shields.io/npm/d18m/@castlenine/svelte-canvas-confetti
266
+ [contribution]: https://github.com/Castlenine/svelte-aoe
267
+ [contribution.badge]: https://img.shields.io/badge/contributions-welcome-green
@@ -3,10 +3,14 @@ import { createParticle, isOutOfBounds, renderParticle, updateParticle } from ".
3
3
  const renderParticles = (context, particles) => {
4
4
  context.clearRect(0, 0, context.canvas.width, context.canvas.height);
5
5
  for (let i = 0; i < particles.length; ++i) {
6
- renderParticle(context, particles[i]);
6
+ const P = particles[i];
7
+ if (!P.dead && P.life >= P.delay)
8
+ renderParticle(context, P);
7
9
  }
8
10
  };
9
11
  const updateParticles = (context, particles, dt, onUpdate) => {
12
+ const CW = context.canvas.width;
13
+ const CH = context.canvas.height;
10
14
  let livingParticles = particles.length;
11
15
  for (let i = 0; i < particles.length; ++i) {
12
16
  const P = particles[i];
@@ -15,7 +19,7 @@ const updateParticles = (context, particles, dt, onUpdate) => {
15
19
  }
16
20
  else {
17
21
  updateParticle(P, dt);
18
- if (isOutOfBounds(context, P))
22
+ if (isOutOfBounds(P, CW, CH))
19
23
  P.dead = true;
20
24
  if (onUpdate)
21
25
  onUpdate(P, dt);
@@ -32,7 +36,8 @@ const start = (canvas, onCompleted, particleCount, origin, force, angle, spread,
32
36
  let t;
33
37
  const run = (_t) => {
34
38
  renderParticles(CONTEXT, PARTICLES);
35
- const STILL_RUNNING = updateParticles(CONTEXT, PARTICLES, (_t - t) / 1e3, onUpdate);
39
+ const DT = Math.min((_t - t) / 1e3, 0.1);
40
+ const STILL_RUNNING = updateParticles(CONTEXT, PARTICLES, DT, onUpdate);
36
41
  if (STILL_RUNNING) {
37
42
  t = _t;
38
43
  frameId = requestAnimationFrame(run);
@@ -1 +1 @@
1
- {"version":3,"file":"Confetti.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/Confetti.svelte"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,QAAQ,CAE5C;AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAY,aAAa,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AA2Q5G,QAAA,MAAM,SAAS;;QA7Ef;;;;;;;;eAQI;QACJ;;;;;;;eAOI;QACJ;;;;;;;eAOI,UAAS,QAAQ,GAAG,SAAS;QACjC;;;;;;;eAOI;QACJ;;;;;;;eAOI;QACJ;;;;;;;eAOI;QACJ;;;;;;;;;;;;;eAaI,YAAW,gBAAgB,GAAG,SAAS;QAC3C;;;;;;;;;;;;;eAaI,YAAW,gBAAgB,GAAG,SAAS;;;;;;;;CACY,CAAC;AACxD,MAAM,MAAM,aAAa,GAAG,OAAO,SAAS,CAAC,KAAK,CAAC;AACnD,MAAM,MAAM,cAAc,GAAG,OAAO,SAAS,CAAC,MAAM,CAAC;AACrD,MAAM,MAAM,aAAa,GAAG,OAAO,SAAS,CAAC,KAAK,CAAC;AAEnD,MAAM,CAAC,OAAO,OAAO,QAAS,SAAQ,oBAAoB,CAAC,aAAa,EAAE,cAAc,EAAE,aAAa,CAAC;CACvG"}
1
+ {"version":3,"file":"Confetti.svelte.d.ts","sourceRoot":"","sources":["../src/lib/Confetti.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,QAAQ,CAE5C;AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAY,aAAa,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AA+Q5G,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;;;;;;;;CACc,CAAC;AAC1D,MAAM,MAAM,aAAa,GAAG,OAAO,SAAS,CAAC,KAAK,CAAC;AACnD,MAAM,MAAM,cAAc,GAAG,OAAO,SAAS,CAAC,MAAM,CAAC;AACrD,MAAM,MAAM,aAAa,GAAG,OAAO,SAAS,CAAC,KAAK,CAAC;AAEnD,MAAM,CAAC,OAAO,OAAO,QAAS,SAAQ,oBAAoB,CAAC,aAAa,EAAE,cAAc,EAAE,aAAa,CAAC;CACvG"}
@@ -1 +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"}
1
+ {"version":3,"file":"ConfettiBurst.svelte.d.ts","sourceRoot":"","sources":["../src/lib/ConfettiBurst.svelte.ts"],"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;;;;;;;;CACc,CAAC;AAC1D,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"}
@@ -1 +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"}
1
+ {"version":3,"file":"ConfettiCannon.svelte.d.ts","sourceRoot":"","sources":["../src/lib/ConfettiCannon.svelte.ts"],"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;;;;;;;;CACc,CAAC;AAC1D,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"}
@@ -1 +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"}
1
+ {"version":3,"file":"FallingConfetti.svelte.d.ts","sourceRoot":"","sources":["../src/lib/FallingConfetti.svelte.ts"],"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;;;;;;;;CACc,CAAC;AAC1D,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 CHANGED
@@ -1,4 +1,4 @@
1
- export type { Particle, OnCreateParticle, OnUpdateParticle } from './utils/types';
1
+ export type { Particle, ParticleStyle, Position, OnCreateParticle, OnUpdateParticle } from './utils/types';
2
2
  export { default as FallingConfetti } from './FallingConfetti.svelte';
3
3
  export { default as ConfettiBurst } from './ConfettiBurst.svelte';
4
4
  export { default as ConfettiCannon } from './ConfettiCannon.svelte';
@@ -1 +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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/lib/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,QAAQ,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAE3G,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"}
@@ -1,6 +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[];
1
+ declare const DEG_TO_RAD: number;
2
+ declare const ROTATION_SPEED = 2;
3
+ declare const BOUNDARY = 20;
4
+ declare const COLORS: string[];
5
+ export { DEG_TO_RAD, ROTATION_SPEED, BOUNDARY, COLORS };
6
6
  //# sourceMappingURL=constants.d.ts.map
@@ -1 +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"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/lib/utils/constants.ts"],"names":[],"mappings":"AAAA,QAAA,MAAM,UAAU,QAAgB,CAAC;AACjC,QAAA,MAAM,cAAc,IAAI,CAAC;AACzB,QAAA,MAAM,QAAQ,KAAK,CAAC;AACpB,QAAA,MAAM,MAAM,UAA0F,CAAC;AAEvG,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC"}
@@ -1,5 +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'];
1
+ const DEG_TO_RAD = Math.PI / 180;
2
+ const ROTATION_SPEED = 2;
3
+ const BOUNDARY = 20;
4
+ const COLORS = ['hotpink', 'gold', 'dodgerblue', 'tomato', 'rebeccapurple', 'lightgreen', 'turquoise'];
5
+ export { DEG_TO_RAD, ROTATION_SPEED, BOUNDARY, COLORS };
@@ -1,6 +1,7 @@
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;
1
+ import type { OnCreateParticle, Particle, ParticleStyle, Position } from './types';
2
+ declare const createParticle: (context: CanvasRenderingContext2D, origin: Position | undefined, force: number, angle: number, spread: number, styles: ParticleStyle[], onCreate?: OnCreateParticle) => Particle;
3
+ declare const renderParticle: (context: CanvasRenderingContext2D, p: Particle) => void;
4
+ declare const updateParticle: (p: Particle, dt: number) => void;
5
+ declare const isOutOfBounds: (p: Particle, canvasWidth: number, canvasHeight: number) => boolean;
6
+ export { createParticle, renderParticle, updateParticle, isOutOfBounds };
6
7
  //# sourceMappingURL=particle.d.ts.map
@@ -1 +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"}
1
+ {"version":3,"file":"particle.d.ts","sourceRoot":"","sources":["../../src/lib/utils/particle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,QAAQ,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAKnF,QAAA,MAAM,cAAc,YACV,wBAAwB,UACzB,QAAQ,GAAG,SAAS,SACrB,MAAM,SACN,MAAM,UACL,MAAM,UACN,aAAa,EAAE,aACZ,gBAAgB,aAiD3B,CAAC;AAEF,QAAA,MAAM,cAAc,YAAa,wBAAwB,KAAK,QAAQ,SAYrE,CAAC;AAEF,QAAA,MAAM,cAAc,MAAO,QAAQ,MAAM,MAAM,SAY9C,CAAC;AAEF,QAAA,MAAM,aAAa,MAAO,QAAQ,eAAe,MAAM,gBAAgB,MAAM,YAE5E,CAAC;AAEF,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,CAAC"}
@@ -1,17 +1,15 @@
1
- import { BOUNDARY, DEG_TO_RAD, MOVEMENT_SPEED, ROTATION_SPEED } from './constants';
1
+ import { BOUNDARY, DEG_TO_RAD, ROTATION_SPEED } from './constants';
2
2
  import { random } from './random';
3
- export const createParticle = (context, origin, force, angle, spread, styles, onCreate) => {
3
+ const createParticle = (context, origin, force, angle, spread, styles, onCreate) => {
4
4
  let dir;
5
5
  let x;
6
6
  let y;
7
7
  let vx;
8
8
  let vy;
9
- let dx;
10
- let dy;
11
- const style = styles[Math.floor(random(styles.length))];
9
+ const STYLE = styles[Math.floor(random(styles.length))];
12
10
  let da = random(90, -90);
13
11
  if (origin) {
14
- // When we have an origin, we create a confetti burst
12
+ // Generate a confetti burst effect using the provided origin coordinates
15
13
  x = origin[0];
16
14
  y = origin[1];
17
15
  vx = random(force, 5);
@@ -20,17 +18,15 @@ export const createParticle = (context, origin, force, angle, spread, styles, on
20
18
  da *= 2;
21
19
  }
22
20
  else {
23
- // Otherwise we drop confetti from the top of the screen
21
+ // If no origin is provided, confetti falls from the top edge of the canvas
24
22
  x = random(context.canvas.width);
25
23
  y = random(-BOUNDARY);
26
24
  vx = random(5);
27
25
  vy = random(5, 1);
28
26
  dir = random(180) * DEG_TO_RAD;
29
27
  }
30
- // eslint-disable-next-line prefer-const
31
- dx = Math.cos(dir);
32
- // eslint-disable-next-line prefer-const
33
- dy = Math.sin(dir);
28
+ const DX = Math.cos(dir);
29
+ const DY = Math.sin(dir);
34
30
  let particle = {
35
31
  dead: false,
36
32
  life: 0,
@@ -39,45 +35,47 @@ export const createParticle = (context, origin, force, angle, spread, styles, on
39
35
  y,
40
36
  angle: random(360),
41
37
  da,
42
- dx: dx * vx,
43
- dy: dy * vy,
38
+ dx: DX * vx,
39
+ dy: DY * vy,
44
40
  w: random(18, 10),
45
41
  h: random(6, 4),
46
42
  gy: random(4.5, 2),
47
43
  xw: random(6, 1),
48
- style,
44
+ style: STYLE,
49
45
  };
50
46
  if (onCreate)
51
47
  particle = onCreate(particle);
52
48
  return particle;
53
49
  };
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);
50
+ const renderParticle = (context, p) => {
51
+ const ANGLE_IN_RADIANS = p.angle * DEG_TO_RAD;
52
+ const COS = Math.cos(ANGLE_IN_RADIANS);
53
+ const SIN = Math.sin(ANGLE_IN_RADIANS);
54
+ context.setTransform(COS, SIN, -SIN, COS, p.x, p.y);
60
55
  if (p.style instanceof HTMLImageElement) {
61
56
  context.drawImage(p.style, -p.style.width / 2, -p.style.height / 2);
62
57
  }
63
58
  else {
64
59
  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();
60
+ context.fillRect(p.w * -0.5, p.h * -0.5, p.w, p.h);
68
61
  }
69
- context.restore();
62
+ context.setTransform(1, 0, 0, 1, 0, 0);
70
63
  };
71
- export const updateParticle = (p, dt) => {
64
+ const updateParticle = (p, dt) => {
72
65
  p.life += dt;
73
66
  if (p.dead || p.life < p.delay)
74
67
  return;
68
+ const FRAME_SCALE = dt * 60;
75
69
  p.angle += p.da * dt * ROTATION_SPEED;
76
70
  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;
71
+ p.dx += (3 * Math.sin(p.life * p.xw) + Math.sin(p.life * p.xw * 2.3)) * dt;
72
+ const DRAG = Math.pow(0.98, FRAME_SCALE);
73
+ p.dx *= DRAG;
74
+ p.dy *= DRAG;
75
+ p.x += p.dx * FRAME_SCALE;
76
+ p.y += p.dy * FRAME_SCALE;
77
+ };
78
+ const isOutOfBounds = (p, canvasWidth, canvasHeight) => {
79
+ return p.x < -BOUNDARY || p.x > canvasWidth + BOUNDARY || p.y > canvasHeight + BOUNDARY;
82
80
  };
83
- export const isOutOfBounds = (context, p) => p.x < -BOUNDARY || p.x > context.canvas.width + BOUNDARY || p.y > context.canvas.height + BOUNDARY;
81
+ export { createParticle, renderParticle, updateParticle, isOutOfBounds };
@@ -1,3 +1,4 @@
1
- export declare const random: (max: number, min?: number) => number;
2
- export declare const coinFlip: () => boolean;
1
+ declare const random: (max: number, min?: number) => number;
2
+ declare const coinFlip: () => boolean;
3
+ export { random, coinFlip };
3
4
  //# sourceMappingURL=random.d.ts.map
@@ -1 +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"}
1
+ {"version":3,"file":"random.d.ts","sourceRoot":"","sources":["../../src/lib/utils/random.ts"],"names":[],"mappings":"AAAA,QAAA,MAAM,MAAM,QAAS,MAAM,yBAA+C,CAAC;AAE3E,QAAA,MAAM,QAAQ,eAA6B,CAAC;AAE5C,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC"}
@@ -1,2 +1,3 @@
1
- export const random = (max, min = 0) => Math.random() * (max - min) + min;
2
- export const coinFlip = () => Math.random() >= 0.5;
1
+ const random = (max, min = 0) => Math.random() * (max - min) + min;
2
+ const coinFlip = () => Math.random() >= 0.5;
3
+ export { random, coinFlip };
@@ -1,6 +1,6 @@
1
- export type ParticleStyle = string | HTMLImageElement;
2
- export type Position = [number, number];
3
- export type Particle = {
1
+ type ParticleStyle = string | HTMLImageElement;
2
+ type Position = [number, number];
3
+ type Particle = {
4
4
  dead: boolean;
5
5
  life: number;
6
6
  delay: number;
@@ -16,6 +16,7 @@ export type Particle = {
16
16
  xw: number;
17
17
  style: ParticleStyle;
18
18
  };
19
- export type OnCreateParticle = (p: Particle) => Particle;
20
- export type OnUpdateParticle = (p: Particle, dt: number) => void;
19
+ type OnCreateParticle = (p: Particle) => Particle;
20
+ type OnUpdateParticle = (p: Particle, dt: number) => void;
21
+ export type { ParticleStyle, Position, Particle, OnCreateParticle, OnUpdateParticle };
21
22
  //# sourceMappingURL=types.d.ts.map
@@ -1 +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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/utils/types.ts"],"names":[],"mappings":"AAAA,KAAK,aAAa,GAAG,MAAM,GAAG,gBAAgB,CAAC;AAE/C,KAAK,QAAQ,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAEjC,KAAK,QAAQ,GAAG;IACf,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,KAAK,gBAAgB,GAAG,CAAC,CAAC,EAAE,QAAQ,KAAK,QAAQ,CAAC;AAElD,KAAK,gBAAgB,GAAG,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;AAE1D,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,QAAQ,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@castlenine/svelte-canvas-confetti",
3
- "version": "1.0.0",
4
- "description": "Canvas-based confetti for Svelte, without dependencies",
3
+ "version": "1.1.0",
4
+ "description": "Canvas-based confetti for Svelte, with no dependencies",
5
5
  "license": "MIT",
6
6
  "keywords": [
7
7
  "svelte",
@@ -10,7 +10,7 @@
10
10
  "canvas"
11
11
  ],
12
12
  "author": {
13
- "name": "Alexandre Castlenine",
13
+ "name": "Alex Castlenine",
14
14
  "url": "https://github.com/Castlenine"
15
15
  },
16
16
  "homepage": "https://github.com/castlenine/svelte-canvas-confetti",
@@ -28,8 +28,9 @@
28
28
  "exports": {
29
29
  ".": {
30
30
  "types": "./dist/index.d.ts",
31
+ "svelte": "./dist/index.js",
31
32
  "import": "./dist/index.js",
32
- "svelte": "./dist/index.js"
33
+ "default": "./dist/index.js"
33
34
  }
34
35
  },
35
36
  "files": [
@@ -40,7 +41,7 @@
40
41
  "build": "npm run check && vite build",
41
42
  "preview": "vite preview",
42
43
  "package": "npm run remove-dist-folder && svelte-kit sync && svelte-package && publint",
43
- "prepublishOnly": "npm run package",
44
+ "prepublish-only": "npm run package",
44
45
  "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
45
46
  "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
46
47
  "eslint": "eslint --ignore-path ./.eslintignore .",
@@ -58,26 +59,26 @@
58
59
  "devDependencies": {
59
60
  "@sveltejs/adapter-static": "^2.0.3",
60
61
  "@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",
62
+ "@sveltejs/package": "^2.5.8",
63
+ "@typescript-eslint/eslint-plugin": "^7.18.0",
64
+ "@typescript-eslint/parser": "^7.18.0",
65
+ "eslint": "^8.57.1",
66
+ "eslint-config-prettier": "^9.1.2",
67
+ "eslint-import-resolver-typescript": "^3.10.1",
68
+ "eslint-plugin-html": "^8.1.4",
69
+ "eslint-plugin-import": "^2.32.0",
69
70
  "eslint-plugin-no-loops": "^0.3.0",
70
- "eslint-plugin-only-warn": "^1.1.0",
71
- "eslint-plugin-prettier": "^5.1.3",
71
+ "eslint-plugin-only-warn": "^1.2.1",
72
+ "eslint-plugin-prettier": "^5.5.6",
72
73
  "eslint-plugin-security": "^1.7.1",
73
- "eslint-plugin-svelte": "^2.38.0",
74
- "prettier": "^3.2.5",
75
- "prettier-eslint": "^16.3.0",
74
+ "eslint-plugin-svelte": "^2.46.1",
75
+ "prettier": "^3.8.3",
76
+ "prettier-eslint": "^16.4.2",
76
77
  "prettier-eslint-cli": "^8.0.1",
77
- "prettier-plugin-svelte": "^3.2.3",
78
+ "prettier-plugin-svelte": "^3.5.2",
78
79
  "prettier-stylelint": "^0.4.2",
79
- "publint": "^0.2.7",
80
- "rimraf": "^5.0.5",
80
+ "publint": "^0.3.21",
81
+ "rimraf": "^6.1.3",
81
82
  "stylelint": "^15.11.0",
82
83
  "stylelint-config-html": "^1.1.0",
83
84
  "stylelint-config-standard": "^34.0.0",
@@ -85,12 +86,12 @@
85
86
  "stylelint-order": "^6.0.4",
86
87
  "stylelint-scss": "^5.3.2",
87
88
  "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",
89
+ "svelte": "^4.2.20",
90
+ "svelte-check": "^3.8.6",
91
+ "svelte-eslint-parser": "^0.43.0",
91
92
  "svelte-preprocess": "^5.1.4",
92
- "tslib": "^2.6.2",
93
- "typescript": "^5.4.5",
94
- "vite": "^4.5.3"
93
+ "tslib": "^2.8.1",
94
+ "typescript": "^4.9.5",
95
+ "vite": "^4.5.14"
95
96
  }
96
- }
97
+ }