festive-fx 0.0.0-stage → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +217 -2
- package/dist/chunk-JYL2RG4A.cjs +2849 -0
- package/dist/chunk-JYL2RG4A.cjs.map +1 -0
- package/dist/chunk-QYGOFPJM.js +2819 -0
- package/dist/chunk-QYGOFPJM.js.map +1 -0
- package/dist/element.cjs +92 -0
- package/dist/element.cjs.map +1 -0
- package/dist/element.d.cts +34 -0
- package/dist/element.d.ts +34 -0
- package/dist/element.js +89 -0
- package/dist/element.js.map +1 -0
- package/dist/festive-fx.iife.js +2 -0
- package/dist/festive-fx.iife.js.map +1 -0
- package/dist/index.cjs +124 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +95 -0
- package/dist/index.d.ts +95 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/react.cjs +81 -0
- package/dist/react.cjs.map +1 -0
- package/dist/react.d.cts +28 -0
- package/dist/react.d.ts +28 -0
- package/dist/react.js +78 -0
- package/dist/react.js.map +1 -0
- package/dist/types-BoSzQdti.d.cts +89 -0
- package/dist/types-BoSzQdti.d.ts +89 -0
- package/dist/vue.cjs +76 -0
- package/dist/vue.cjs.map +1 -0
- package/dist/vue.d.cts +92 -0
- package/dist/vue.d.ts +92 -0
- package/dist/vue.js +73 -0
- package/dist/vue.js.map +1 -0
- package/package.json +117 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Dipesh Shrestha
|
|
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
CHANGED
|
@@ -1,3 +1,218 @@
|
|
|
1
|
-
#
|
|
1
|
+
# festive-fx
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Lightweight, dependency-free festive overlays for any frontend: **Tihar / Deepawali rockets**, **diyas and sky lanterns**, **marigold garlands**, **Dashain kites**, **Holi colours**, **snow**, **rain**, **thunderstorms**, **stars**, **fireflies**, **confetti**, **falling leaves** and **sakura petals**. Layer several in one canvas.
|
|
4
|
+
|
|
5
|
+
- One canvas, `pointer-events: none`, never blocks your UI
|
|
6
|
+
- Works in React, Vue, Angular, Svelte, Solid, plain HTML. The core is vanilla TS, plus a Web Component and thin React and Vue wrappers
|
|
7
|
+
- ~45 KB minified for the drop-in script build, with zero runtime dependencies
|
|
8
|
+
- HiDPI aware, respects `prefers-reduced-motion`, safe to import during SSR
|
|
9
|
+
- Pauses in background tabs and while a wrapped target is scrolled off-screen
|
|
10
|
+
- Batched drawing: thousands of firework sparks render in a few dozen canvas calls
|
|
11
|
+
- Add your own effects with `registerEffect()`
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
npm i festive-fx
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Effects
|
|
18
|
+
|
|
19
|
+
| name | aliases | `burst(x, y)` |
|
|
20
|
+
| --- | --- | --- |
|
|
21
|
+
| `snow` | | none |
|
|
22
|
+
| `rain` | | splash at point |
|
|
23
|
+
| `storm` | `thunderstorm` | lightning strike at x |
|
|
24
|
+
| `fireworks` | `rockets`, `diwali`, `deepawali`, `tihar` | launches a rocket that bursts at (x, y) |
|
|
25
|
+
| `diyas` | `lanterns`, `lights` | releases a sky lantern |
|
|
26
|
+
| `confetti` | | confetti cannon pop |
|
|
27
|
+
| `leaves` | `autumn` | puff of air blows nearby leaves away |
|
|
28
|
+
| `sakura` | `petals` | puff of air blows nearby petals away |
|
|
29
|
+
| `marigold` | `sayapatri`, `garland` | throws a handful of petals |
|
|
30
|
+
| `kites` | `changa`, `dashain` | cuts the nearest kite loose, or launches a new one |
|
|
31
|
+
| `holi` | `gulal` | throws a fistful of colour |
|
|
32
|
+
| `stars` | `night` | shooting star from that point |
|
|
33
|
+
| `fireflies` | | nearby fireflies flash and scatter |
|
|
34
|
+
|
|
35
|
+
### What's in each
|
|
36
|
+
|
|
37
|
+
- **snow**: three depth layers (far haze, soft flakes, rotating six-armed crystals), parallax, natural gusts, and a drift that piles up along the bottom edge.
|
|
38
|
+
- **rain / storm**: near and far drops with bright leading heads, crown splashes with double ripples, and low ground mist. `storm` adds heavier slanted rain and branching lightning that lights up the whole sky.
|
|
39
|
+
- **fireworks**: rockets with wobble and spark trails, then ten shell types: peony, chrysanthemum (glitter), ring, double ring, gold willow, palm, crossette (stars split into crosses), strobe, colour-change and multi-break. Bursts light up the sky and leave drifting smoke, and anar (flower-pot) fountains erupt from the ground.
|
|
40
|
+
- **diyas**: a row of painted clay oil lamps with layered, flickering flames and warm light pools, rising embers, and paper sky lanterns that drift upward and shrink into the distance.
|
|
41
|
+
- **confetti**: rectangles, squares, circles, triangles, stars and curling streamers. Pieces flip in 3D with a darker back face, and gold/silver foil pieces glint.
|
|
42
|
+
- **marigold**: falling petals and whole ruffled flowers, garlands (toran) swagged along the top edge with hanging strands and mango leaves, petals that settle on the ground.
|
|
43
|
+
- **kites**: Dashain-style paper kites in two-tone patterns with bamboo frames and tassels, strings running down to unseen flyers, loop-the-loop dives, and kites cut loose ("chet!") that drift away trailing string before a new one launches.
|
|
44
|
+
- **holi**: fistfuls of gulal thrown as expanding powder clouds that mix colours, flying grains, and colour splats with satellite drops and drips.
|
|
45
|
+
- **stars**: twinkling field (denser toward the top, a few tinted blue or warm, the brightest with spikes) and shooting stars.
|
|
46
|
+
- **fireflies**: wandering glow-worms with a real firefly blink rhythm; with `ground` on they hover low.
|
|
47
|
+
- **leaves / sakura**: maple, oak and beech leaves, or cherry-blossom petals, with veins, a paler underside, depth layers and gusts that lift them. They settle on the ground and fade.
|
|
48
|
+
|
|
49
|
+
## Layering
|
|
50
|
+
|
|
51
|
+
Pass an array to draw several effects in one canvas, back to front. They share options and every layer gets the burst:
|
|
52
|
+
|
|
53
|
+
```js
|
|
54
|
+
createFx({ effect: ['stars', 'diyas', 'fireworks'], interactive: true }); // Tihar night
|
|
55
|
+
createFx({ effect: ['kites', 'marigold'] }); // Dashain afternoon
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
```html
|
|
59
|
+
<festive-fx effect="stars, fireflies" fullscreen></festive-fx>
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Options
|
|
63
|
+
|
|
64
|
+
| option | default | |
|
|
65
|
+
| --- | --- | --- |
|
|
66
|
+
| `effect` | `'snow'` | effect name, or an array to layer several |
|
|
67
|
+
| `target` | viewport | element or CSS selector to cover |
|
|
68
|
+
| `fullscreen` | `true` when no target | `position: fixed` over the viewport |
|
|
69
|
+
| `density` | `1` | particle amount; `0` means only manual bursts |
|
|
70
|
+
| `speed` | `1` | animation speed |
|
|
71
|
+
| `wind` | `0` | `-1` (left) to `1` (right) |
|
|
72
|
+
| `size` | `1` | particle size |
|
|
73
|
+
| `colors` | per effect | array of CSS colors |
|
|
74
|
+
| `ground` | `true` | edge decorations: snow drifts, rain mist, settled leaves/petals, anar fountains, the diya row, marigold garlands along the top |
|
|
75
|
+
| `zIndex` | `9999` | canvas z-index |
|
|
76
|
+
| `interactive` | `false` | click/tap triggers `burst()` at pointer |
|
|
77
|
+
| `duration` | forever | ms, then fades out and stops |
|
|
78
|
+
| `autoStart` | `true` | |
|
|
79
|
+
| `respectReducedMotion` | `true` | don't animate for reduced-motion users |
|
|
80
|
+
| `maxDpr` | `2` | devicePixelRatio cap |
|
|
81
|
+
|
|
82
|
+
The controller exposes `start()`, `stop()`, `clear()`, `update(opts)`, `burst(x?, y?)`, `destroy()`, plus `running` and `canvas`.
|
|
83
|
+
|
|
84
|
+
## Vanilla JS / any framework
|
|
85
|
+
|
|
86
|
+
```js
|
|
87
|
+
import { createFx } from 'festive-fx';
|
|
88
|
+
|
|
89
|
+
const fx = createFx({ effect: 'snow' }); // whole page
|
|
90
|
+
const hero = createFx({ effect: 'rain', target: '#hero', wind: 0.4 });
|
|
91
|
+
|
|
92
|
+
fx.update({ effect: 'fireworks', interactive: true }); // swap live
|
|
93
|
+
fx.burst(); // one rocket
|
|
94
|
+
fx.destroy();
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Web Component (Angular, Vue, Svelte, plain HTML, ...)
|
|
98
|
+
|
|
99
|
+
```js
|
|
100
|
+
import 'festive-fx/element'; // registers <festive-fx>
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
```html
|
|
104
|
+
<!-- wraps its content -->
|
|
105
|
+
<festive-fx effect="snow" density="1.5" wind="0.3">
|
|
106
|
+
<section class="hero">...</section>
|
|
107
|
+
</festive-fx>
|
|
108
|
+
|
|
109
|
+
<!-- covers the viewport -->
|
|
110
|
+
<festive-fx effect="tihar" fullscreen interactive colors="#ffd700,#ff9933,#ff3d7f"></festive-fx>
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Attributes: `effect density speed wind size colors ground="false" z-index duration interactive fullscreen autostart="false" respect-reduced-motion="false"`.
|
|
114
|
+
Methods: `el.start()`, `el.stop()`, `el.burst(x, y)`, `el.controller`.
|
|
115
|
+
|
|
116
|
+
### Angular
|
|
117
|
+
|
|
118
|
+
```ts
|
|
119
|
+
// main.ts (or any file loaded once)
|
|
120
|
+
import 'festive-fx/element';
|
|
121
|
+
|
|
122
|
+
@Component({
|
|
123
|
+
selector: 'app-root',
|
|
124
|
+
standalone: true,
|
|
125
|
+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
126
|
+
template: `<festive-fx [attr.effect]="effect" fullscreen></festive-fx>`,
|
|
127
|
+
})
|
|
128
|
+
export class AppComponent { effect = 'snow'; }
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Or use `createFx({ target: this.el.nativeElement })` in `ngAfterViewInit` and `destroy()` in `ngOnDestroy`.
|
|
132
|
+
|
|
133
|
+
## React
|
|
134
|
+
|
|
135
|
+
```tsx
|
|
136
|
+
import { FestiveFx, useFestiveFx } from 'festive-fx/react';
|
|
137
|
+
|
|
138
|
+
<FestiveFx effect="fireworks" interactive>
|
|
139
|
+
<Hero />
|
|
140
|
+
</FestiveFx>
|
|
141
|
+
|
|
142
|
+
<FestiveFx effect="snow" fullscreen density={1.5} />
|
|
143
|
+
|
|
144
|
+
// imperative
|
|
145
|
+
const ref = useRef<FxController>(null);
|
|
146
|
+
<FestiveFx ref={ref} effect="confetti" density={0} fullscreen />
|
|
147
|
+
<button onClick={() => ref.current?.burst()}>🎉</button>
|
|
148
|
+
|
|
149
|
+
// hook
|
|
150
|
+
const fx = useFestiveFx({ effect: 'rain' }, sectionRef);
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Vue 3
|
|
154
|
+
|
|
155
|
+
```vue
|
|
156
|
+
<script setup>
|
|
157
|
+
import { FestiveFx } from 'festive-fx/vue';
|
|
158
|
+
</script>
|
|
159
|
+
|
|
160
|
+
<template>
|
|
161
|
+
<FestiveFx effect="leaves" :wind="0.5"><Hero /></FestiveFx>
|
|
162
|
+
<FestiveFx effect="diwali" fullscreen interactive />
|
|
163
|
+
</template>
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Or register it globally with `app.use(FestiveFxPlugin)`.
|
|
167
|
+
|
|
168
|
+
## CDN
|
|
169
|
+
|
|
170
|
+
```html
|
|
171
|
+
<script src="https://unpkg.com/festive-fx"></script>
|
|
172
|
+
<script>FestiveFx.createFx({ effect: 'snow' });</script>
|
|
173
|
+
<!-- <festive-fx> is registered too -->
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## Custom effects
|
|
177
|
+
|
|
178
|
+
```ts
|
|
179
|
+
import { registerEffect, type EffectFactory } from 'festive-fx';
|
|
180
|
+
|
|
181
|
+
const bubbles: EffectFactory = (opts) => {
|
|
182
|
+
let w = 0, h = 0;
|
|
183
|
+
const items: { x: number; y: number; r: number }[] = [];
|
|
184
|
+
return {
|
|
185
|
+
resize(nw, nh) { w = nw; h = nh; /* size your pool from opts.density */ },
|
|
186
|
+
update(dt) { /* move by dt seconds * opts.speed */ },
|
|
187
|
+
draw(ctx) { /* canvas is already cleared */ },
|
|
188
|
+
burst(x, y) { /* optional */ },
|
|
189
|
+
};
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
registerEffect('bubbles', bubbles);
|
|
193
|
+
// createFx({ effect: 'bubbles' }) and <festive-fx effect="bubbles"> both work now
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## Development
|
|
197
|
+
|
|
198
|
+
```sh
|
|
199
|
+
npm install
|
|
200
|
+
npm test # vitest + jsdom
|
|
201
|
+
npm run build # dist/: ESM + CJS + d.ts + IIFE
|
|
202
|
+
open examples/index.html
|
|
203
|
+
open bench/index.html # ms/frame and canvas calls/frame per effect at 1920x1080
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
Performance notes for effect authors: draw with `place()` (one `setTransform`)
|
|
207
|
+
rather than `save/translate/rotate/restore` per particle, remove dead particles
|
|
208
|
+
with `retain()` rather than `splice` in a loop, and group particles that share a
|
|
209
|
+
style (colour, `alphaLevel()`, width) into one path per group. All of these
|
|
210
|
+
are exported for custom effects:
|
|
211
|
+
|
|
212
|
+
```ts
|
|
213
|
+
import { place, retain, alphaLevel, sprite, glowSprite, stamp } from 'festive-fx';
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## License
|
|
217
|
+
|
|
218
|
+
MIT
|