fireworks-engine 1.0.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 +24 -0
- package/README.md +297 -0
- package/index.d.ts +691 -0
- package/package.json +49 -0
- package/src/burstConfigBuilder.js +262 -0
- package/src/burstSpawn.js +764 -0
- package/src/colorUtils.js +80 -0
- package/src/configBuilder.js +300 -0
- package/src/defaults.js +87 -0
- package/src/index.js +13 -0
- package/src/mathResolvers.js +77 -0
- package/src/presets.js +811 -0
- package/src/renderer.js +863 -0
- package/src/rocketLaunch.js +791 -0
- package/src/runtime.js +796 -0
- package/src/runtimeCapabilities.js +7 -0
- package/src/runtimeLifecycle.js +330 -0
- package/src/update.js +307 -0
- package/src/valueNormalizers.js +160 -0
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "fireworks-engine",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"license": "BSD-2-Clause",
|
|
5
|
+
"description": "Reusable canvas fireworks runtime package for standalone integrations and demos.",
|
|
6
|
+
"author": "coinexplain",
|
|
7
|
+
"homepage": "https://github.com/coinexplain/fireworks-engine#readme",
|
|
8
|
+
"bugs": {
|
|
9
|
+
"url": "https://github.com/coinexplain/fireworks-engine/issues"
|
|
10
|
+
},
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "git+https://github.com/coinexplain/fireworks-engine.git"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"src",
|
|
17
|
+
"index.d.ts",
|
|
18
|
+
"README.md",
|
|
19
|
+
"LICENSE"
|
|
20
|
+
],
|
|
21
|
+
"keywords": [
|
|
22
|
+
"fireworks-engine",
|
|
23
|
+
"fireworks",
|
|
24
|
+
"confetti",
|
|
25
|
+
"canvas",
|
|
26
|
+
"animation",
|
|
27
|
+
"effects",
|
|
28
|
+
"particles",
|
|
29
|
+
"standalone"
|
|
30
|
+
],
|
|
31
|
+
"type": "module",
|
|
32
|
+
"main": "./src/index.js",
|
|
33
|
+
"types": "./index.d.ts",
|
|
34
|
+
"exports": {
|
|
35
|
+
".": {
|
|
36
|
+
"types": "./index.d.ts",
|
|
37
|
+
"default": "./src/index.js"
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"sideEffects": false,
|
|
41
|
+
"scripts": {
|
|
42
|
+
"smoke": "node --check src/index.js && node --input-type=module -e \"const mod = await import('./src/index.js'); if (typeof mod.createFireworksEngine !== 'function' || typeof mod.resolveFireworksEnginePreset !== 'function' || typeof mod.default !== 'function') throw new Error('package smoke failed'); console.log('package smoke ok');\"",
|
|
43
|
+
"typecheck": "tsc --noEmit --project tsconfig.types.json",
|
|
44
|
+
"test": "npm run smoke && npm run typecheck"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"typescript": "^5.9.3"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DEFAULT_BURST_FORMS_COUNT,
|
|
3
|
+
DEFAULT_BURST_FORMS_SPEED_MIN,
|
|
4
|
+
DEFAULT_BURST_FORMS_SPEED_MAX,
|
|
5
|
+
DEFAULT_BURST_FORMS_GRAVITY,
|
|
6
|
+
DEFAULT_BURST_FORMS_DIRECTION_DEG,
|
|
7
|
+
DEFAULT_BURST_FORMS_CONE_DEG,
|
|
8
|
+
DEFAULT_BURST_SPARK_GRAVITY,
|
|
9
|
+
DEFAULT_BURST_SPARK_DIRECTION_DEG,
|
|
10
|
+
DEFAULT_BURST_SPARK_CONE_DEG,
|
|
11
|
+
DEFAULT_BURST_FORMS_LIFE_MIN,
|
|
12
|
+
DEFAULT_BURST_FORMS_LIFE_MAX,
|
|
13
|
+
DEFAULT_BURST_FORMS_SIZE_MIN,
|
|
14
|
+
DEFAULT_BURST_FORMS_SIZE_MAX,
|
|
15
|
+
DEFAULT_BURST_FORMS_SPIN,
|
|
16
|
+
DEFAULT_BURST_FORMS_SPIN_COVERAGE,
|
|
17
|
+
DEFAULT_BURST_FORMS_SPIN_DURATION,
|
|
18
|
+
DEFAULT_BURST_FORMS_SPIN_PAUSE,
|
|
19
|
+
DEFAULT_BURST_FORMS_HIGHLIGHT,
|
|
20
|
+
DEFAULT_BURST_FORMS_HIGHLIGHT_ANGLE_DEG,
|
|
21
|
+
DEFAULT_BURST_FORMS_HIGHLIGHT_WIDTH,
|
|
22
|
+
DEFAULT_BURST_FORMS_WOBBLE,
|
|
23
|
+
DEFAULT_BURST_PALETTE,
|
|
24
|
+
BURST_SPARK_COUNT_BASE,
|
|
25
|
+
BURST_SPARK_SPEED_MIN_BASE,
|
|
26
|
+
BURST_SPARK_SPEED_MAX_BASE,
|
|
27
|
+
BURST_SPARK_LIFE_MIN_BASE,
|
|
28
|
+
BURST_SPARK_LIFE_MAX_BASE,
|
|
29
|
+
BURST_SPARK_LENGTH_BASE,
|
|
30
|
+
DEFAULT_BURST_SPARK_TAIL_SCALE,
|
|
31
|
+
BURST_SPARK_THICKNESS_BASE,
|
|
32
|
+
} from './defaults.js';
|
|
33
|
+
import {
|
|
34
|
+
resolveScaledOverride,
|
|
35
|
+
resolveScaledInteger,
|
|
36
|
+
resolveScaledInverseOverride,
|
|
37
|
+
resolveSizeScale,
|
|
38
|
+
resolveEnvelopeTimeScale,
|
|
39
|
+
} from './mathResolvers.js';
|
|
40
|
+
import {
|
|
41
|
+
resolveBurstEntityToggle,
|
|
42
|
+
resolveBurstFormShape,
|
|
43
|
+
normalizeBurstFormGlyph,
|
|
44
|
+
resolveBurstColorMode,
|
|
45
|
+
resolveBurstFlashColorMode,
|
|
46
|
+
resolveBurstSparkShape,
|
|
47
|
+
} from './valueNormalizers.js';
|
|
48
|
+
import { normalizeHexColor } from './colorUtils.js';
|
|
49
|
+
|
|
50
|
+
const MIN_COUNT = 1;
|
|
51
|
+
const TWINKLE_CLOUD_PARTICLE_SIZE_SCALE_FACTOR = 0.5;
|
|
52
|
+
|
|
53
|
+
export function resolveTwinkleParticleSizeScale(sizeScale) {
|
|
54
|
+
return 1 + ((sizeScale - 1) * TWINKLE_CLOUD_PARTICLE_SIZE_SCALE_FACTOR);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function resolveBurstFormsConfig(formsInput, formsCurrent, normalizedOptions, sizeScale, envelopeTimeScale, simple) {
|
|
58
|
+
return {
|
|
59
|
+
enabled: resolveBurstEntityToggle(formsInput.enabled) ?? formsCurrent.enabled,
|
|
60
|
+
count: resolveScaledInteger(
|
|
61
|
+
formsInput.count ?? formsCurrent.count,
|
|
62
|
+
DEFAULT_BURST_FORMS_COUNT,
|
|
63
|
+
MIN_COUNT,
|
|
64
|
+
sizeScale,
|
|
65
|
+
),
|
|
66
|
+
speedMin: resolveScaledOverride(
|
|
67
|
+
formsInput.speedMin ?? formsCurrent.speedMin,
|
|
68
|
+
DEFAULT_BURST_FORMS_SPEED_MIN,
|
|
69
|
+
envelopeTimeScale,
|
|
70
|
+
),
|
|
71
|
+
speedMax: resolveScaledOverride(
|
|
72
|
+
formsInput.speedMax ?? formsCurrent.speedMax,
|
|
73
|
+
DEFAULT_BURST_FORMS_SPEED_MAX,
|
|
74
|
+
envelopeTimeScale,
|
|
75
|
+
),
|
|
76
|
+
gravity: formsInput.gravity ?? formsCurrent.gravity ?? DEFAULT_BURST_FORMS_GRAVITY,
|
|
77
|
+
lifeMin: resolveScaledOverride(
|
|
78
|
+
formsInput.lifeMin ?? formsCurrent.lifeMin,
|
|
79
|
+
DEFAULT_BURST_FORMS_LIFE_MIN,
|
|
80
|
+
envelopeTimeScale,
|
|
81
|
+
),
|
|
82
|
+
lifeMax: resolveScaledOverride(
|
|
83
|
+
formsInput.lifeMax ?? formsCurrent.lifeMax,
|
|
84
|
+
DEFAULT_BURST_FORMS_LIFE_MAX,
|
|
85
|
+
envelopeTimeScale,
|
|
86
|
+
),
|
|
87
|
+
sizeMin: resolveScaledOverride(
|
|
88
|
+
formsInput.sizeMin ?? formsCurrent.sizeMin,
|
|
89
|
+
DEFAULT_BURST_FORMS_SIZE_MIN,
|
|
90
|
+
sizeScale,
|
|
91
|
+
),
|
|
92
|
+
sizeMax: resolveScaledOverride(
|
|
93
|
+
formsInput.sizeMax ?? formsCurrent.sizeMax,
|
|
94
|
+
DEFAULT_BURST_FORMS_SIZE_MAX,
|
|
95
|
+
sizeScale,
|
|
96
|
+
),
|
|
97
|
+
spin: formsInput.spin ?? formsCurrent.spin ?? DEFAULT_BURST_FORMS_SPIN,
|
|
98
|
+
spinCoverage: formsInput.spinCoverage ?? formsCurrent.spinCoverage ?? DEFAULT_BURST_FORMS_SPIN_COVERAGE,
|
|
99
|
+
spinDuration: resolveScaledOverride(
|
|
100
|
+
formsInput.spinDuration ?? formsCurrent.spinDuration,
|
|
101
|
+
DEFAULT_BURST_FORMS_SPIN_DURATION,
|
|
102
|
+
envelopeTimeScale,
|
|
103
|
+
),
|
|
104
|
+
spinPause: resolveScaledOverride(
|
|
105
|
+
formsInput.spinPause ?? formsCurrent.spinPause,
|
|
106
|
+
DEFAULT_BURST_FORMS_SPIN_PAUSE,
|
|
107
|
+
envelopeTimeScale,
|
|
108
|
+
),
|
|
109
|
+
highlight: formsInput.highlight ?? formsCurrent.highlight ?? DEFAULT_BURST_FORMS_HIGHLIGHT,
|
|
110
|
+
highlightAngleDeg: formsInput.highlightAngleDeg
|
|
111
|
+
?? formsCurrent.highlightAngleDeg
|
|
112
|
+
?? DEFAULT_BURST_FORMS_HIGHLIGHT_ANGLE_DEG,
|
|
113
|
+
highlightWidth: formsInput.highlightWidth
|
|
114
|
+
?? formsCurrent.highlightWidth
|
|
115
|
+
?? DEFAULT_BURST_FORMS_HIGHLIGHT_WIDTH,
|
|
116
|
+
wobble: formsInput.wobble ?? formsCurrent.wobble ?? DEFAULT_BURST_FORMS_WOBBLE,
|
|
117
|
+
directionDeg: formsInput.directionDeg ?? formsCurrent.directionDeg ?? DEFAULT_BURST_FORMS_DIRECTION_DEG,
|
|
118
|
+
coneDeg: formsInput.coneDeg ?? formsCurrent.coneDeg ?? DEFAULT_BURST_FORMS_CONE_DEG,
|
|
119
|
+
palette: formsInput.palette
|
|
120
|
+
?? normalizedOptions.palette
|
|
121
|
+
?? formsCurrent.palette
|
|
122
|
+
?? DEFAULT_BURST_PALETTE,
|
|
123
|
+
simple,
|
|
124
|
+
shape: resolveBurstFormShape(formsInput.shape ?? formsCurrent.shape),
|
|
125
|
+
glyph: normalizeBurstFormGlyph(formsInput.glyph, formsCurrent.glyph),
|
|
126
|
+
colorMode: resolveBurstColorMode(formsInput.colorMode ?? formsCurrent.colorMode),
|
|
127
|
+
singleColor: normalizeHexColor(formsInput.singleColor, formsCurrent.singleColor),
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function resolveBurstSparksConfig(sparksInput, sparksCurrent, formsCurrent, burstForms, sizeScale, envelopeTimeScale, simple) {
|
|
132
|
+
return {
|
|
133
|
+
enabled: resolveBurstEntityToggle(sparksInput.enabled) ?? sparksCurrent.enabled,
|
|
134
|
+
count: resolveScaledInteger(
|
|
135
|
+
sparksInput.count ?? sparksCurrent.count,
|
|
136
|
+
BURST_SPARK_COUNT_BASE,
|
|
137
|
+
MIN_COUNT,
|
|
138
|
+
sizeScale,
|
|
139
|
+
),
|
|
140
|
+
speedMin: resolveScaledOverride(
|
|
141
|
+
sparksInput.speedMin ?? (sparksCurrent.speedMin ?? formsCurrent.speedMin),
|
|
142
|
+
BURST_SPARK_SPEED_MIN_BASE,
|
|
143
|
+
envelopeTimeScale,
|
|
144
|
+
),
|
|
145
|
+
speedMax: resolveScaledOverride(
|
|
146
|
+
sparksInput.speedMax ?? (sparksCurrent.speedMax ?? formsCurrent.speedMax),
|
|
147
|
+
BURST_SPARK_SPEED_MAX_BASE,
|
|
148
|
+
envelopeTimeScale,
|
|
149
|
+
),
|
|
150
|
+
gravity: sparksInput.gravity ?? sparksCurrent.gravity ?? formsCurrent.gravity ?? DEFAULT_BURST_SPARK_GRAVITY,
|
|
151
|
+
lifeMin: resolveScaledOverride(
|
|
152
|
+
sparksInput.lifeMin ?? (sparksCurrent.lifeMin ?? formsCurrent.lifeMin),
|
|
153
|
+
BURST_SPARK_LIFE_MIN_BASE,
|
|
154
|
+
envelopeTimeScale,
|
|
155
|
+
),
|
|
156
|
+
lifeMax: resolveScaledOverride(
|
|
157
|
+
sparksInput.lifeMax ?? (sparksCurrent.lifeMax ?? formsCurrent.lifeMax),
|
|
158
|
+
BURST_SPARK_LIFE_MAX_BASE,
|
|
159
|
+
envelopeTimeScale,
|
|
160
|
+
),
|
|
161
|
+
directionDeg: sparksInput.directionDeg ?? sparksCurrent.directionDeg ?? DEFAULT_BURST_SPARK_DIRECTION_DEG,
|
|
162
|
+
coneDeg: sparksInput.coneDeg ?? sparksCurrent.coneDeg ?? DEFAULT_BURST_SPARK_CONE_DEG,
|
|
163
|
+
palette: sparksInput.palette ?? sparksCurrent.palette ?? burstForms.palette,
|
|
164
|
+
simple,
|
|
165
|
+
length: resolveScaledOverride(sparksInput.length ?? sparksCurrent.length, BURST_SPARK_LENGTH_BASE, sizeScale),
|
|
166
|
+
tailScale: sparksInput.tailScale ?? sparksCurrent.tailScale ?? DEFAULT_BURST_SPARK_TAIL_SCALE,
|
|
167
|
+
thickness: resolveScaledOverride(sparksInput.thickness ?? sparksCurrent.thickness, BURST_SPARK_THICKNESS_BASE, sizeScale),
|
|
168
|
+
shape: resolveBurstSparkShape(sparksInput.shape ?? sparksCurrent.shape),
|
|
169
|
+
colorMode: resolveBurstColorMode(
|
|
170
|
+
sparksInput.colorMode ?? sparksCurrent.colorMode ?? formsCurrent.colorMode,
|
|
171
|
+
),
|
|
172
|
+
singleColor: normalizeHexColor(
|
|
173
|
+
sparksInput.singleColor ?? sparksCurrent.singleColor ?? formsCurrent.singleColor,
|
|
174
|
+
formsCurrent.singleColor,
|
|
175
|
+
),
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function resolveBurstCenterFlashConfig(flashInput, flashCurrent, sizeScale) {
|
|
180
|
+
return {
|
|
181
|
+
enabled: resolveBurstEntityToggle(flashInput.enabled) ?? flashCurrent.enabled,
|
|
182
|
+
startSize: resolveScaledOverride(flashInput.startSize, flashCurrent.startSize, sizeScale),
|
|
183
|
+
endSize: resolveScaledOverride(flashInput.endSize, flashCurrent.endSize, sizeScale),
|
|
184
|
+
peakAlpha: flashInput.peakAlpha ?? flashCurrent.peakAlpha,
|
|
185
|
+
attack: flashInput.attack ?? flashCurrent.attack,
|
|
186
|
+
fade: flashInput.fade ?? flashCurrent.fade,
|
|
187
|
+
colorMode: resolveBurstFlashColorMode(flashInput.colorMode ?? flashCurrent.colorMode),
|
|
188
|
+
color: normalizeHexColor(flashInput.color, flashCurrent.color),
|
|
189
|
+
innerStop: flashInput.innerStop ?? flashCurrent.innerStop,
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function resolveBurstTwinkleCloudConfig(twinkleInput, twinkleCurrent, sizeScale, envelopeTimeScale) {
|
|
194
|
+
const particleSizeScale = resolveTwinkleParticleSizeScale(sizeScale);
|
|
195
|
+
return {
|
|
196
|
+
enabled: resolveBurstEntityToggle(twinkleInput.enabled) ?? twinkleCurrent.enabled,
|
|
197
|
+
count: resolveScaledInteger(twinkleInput.count, twinkleCurrent.count, MIN_COUNT, sizeScale),
|
|
198
|
+
radius: resolveScaledOverride(twinkleInput.radius, twinkleCurrent.radius, sizeScale),
|
|
199
|
+
startDelay: resolveScaledOverride(twinkleInput.startDelay, twinkleCurrent.startDelay, envelopeTimeScale),
|
|
200
|
+
duration: resolveScaledOverride(twinkleInput.duration, twinkleCurrent.duration, envelopeTimeScale),
|
|
201
|
+
twinkleLife: resolveScaledOverride(twinkleInput.twinkleLife, twinkleCurrent.twinkleLife, envelopeTimeScale),
|
|
202
|
+
brightness: twinkleInput.brightness ?? twinkleCurrent.brightness,
|
|
203
|
+
size: resolveScaledOverride(twinkleInput.size, twinkleCurrent.size, particleSizeScale),
|
|
204
|
+
spawnSpread: resolveScaledInverseOverride(twinkleInput.spawnSpread, twinkleCurrent.spawnSpread, sizeScale),
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
export function buildBurstOptions(normalizedOptions = {}, currentConfig = {}) {
|
|
209
|
+
const safeOptions = normalizedOptions ?? {};
|
|
210
|
+
const sizeScale = resolveSizeScale(safeOptions.sizeScale, currentConfig.sizeScale ?? 1);
|
|
211
|
+
const envelopeTimeScale = resolveEnvelopeTimeScale(sizeScale);
|
|
212
|
+
const simple = !!safeOptions.simple;
|
|
213
|
+
const {
|
|
214
|
+
burstForms: formsInput = {},
|
|
215
|
+
burstSparks: sparksInput = {},
|
|
216
|
+
burstCenterFlash: flashInput = {},
|
|
217
|
+
burstTwinkleCloud: twinkleInput = {},
|
|
218
|
+
} = safeOptions;
|
|
219
|
+
|
|
220
|
+
const formsCurrent = currentConfig.burstForms ?? {};
|
|
221
|
+
const sparksCurrent = currentConfig.burstSparks ?? {};
|
|
222
|
+
const flashCurrent = currentConfig.burstCenterFlash ?? {};
|
|
223
|
+
const twinkleCurrent = currentConfig.burstTwinkleCloud ?? {};
|
|
224
|
+
|
|
225
|
+
const burstForms = resolveBurstFormsConfig(
|
|
226
|
+
formsInput,
|
|
227
|
+
formsCurrent,
|
|
228
|
+
safeOptions,
|
|
229
|
+
sizeScale,
|
|
230
|
+
envelopeTimeScale,
|
|
231
|
+
simple,
|
|
232
|
+
);
|
|
233
|
+
const burstSparks = resolveBurstSparksConfig(
|
|
234
|
+
sparksInput,
|
|
235
|
+
sparksCurrent,
|
|
236
|
+
formsCurrent,
|
|
237
|
+
burstForms,
|
|
238
|
+
sizeScale,
|
|
239
|
+
envelopeTimeScale,
|
|
240
|
+
simple,
|
|
241
|
+
);
|
|
242
|
+
const burstCenterFlash = resolveBurstCenterFlashConfig(
|
|
243
|
+
flashInput,
|
|
244
|
+
flashCurrent,
|
|
245
|
+
sizeScale,
|
|
246
|
+
);
|
|
247
|
+
const burstTwinkleCloud = resolveBurstTwinkleCloudConfig(
|
|
248
|
+
twinkleInput,
|
|
249
|
+
twinkleCurrent,
|
|
250
|
+
sizeScale,
|
|
251
|
+
envelopeTimeScale,
|
|
252
|
+
);
|
|
253
|
+
|
|
254
|
+
return {
|
|
255
|
+
sizeScale,
|
|
256
|
+
simple,
|
|
257
|
+
burstForms,
|
|
258
|
+
burstSparks,
|
|
259
|
+
burstCenterFlash,
|
|
260
|
+
burstTwinkleCloud,
|
|
261
|
+
};
|
|
262
|
+
}
|