Skip to content

Commit dcdd8ae

Browse files
committed
Release 2.1.0
1 parent 2a8d62b commit dcdd8ae

11 files changed

+235
-155
lines changed

CHANGES.MD

+10
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,14 @@
11

2+
## 2.1.0
3+
4+
this should technically be breaking but I get the sense I don't have many consumers so I can get away with it :)
5+
6+
* renamed option "explosionHeight" to "explosionMinHeight"
7+
* new option, "explosionMaxHeight" - max height a rocket will reach before exploding.
8+
* various internal refactors
9+
* new `fire` method to fire a single rocket.
10+
* providing 0 for numRockets will not start rocket respawn timer (you must call `fire`)
11+
212
## 2.0.1
313

414
* update build to use webpack.

README.MD

+2-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ const options = {
2424
maxRockets: 3, // max # of rockets to spawn
2525
rocketSpawnInterval: 150, // millisends to check if new rockets should spawn
2626
numParticles: 100, // number of particles to spawn when rocket explodes (+0-10)
27-
explosionHeight: 0.2, // minimum percentage of height of container at which rockets explode
27+
explosionMinHeight: 0.2, // percentage. min height at which rockets can explode
28+
explosionMaxHeight: 0.9, // percentage. max height before a particle is exploded
2829
explosionChance: 0.08 // chance in each tick the rocket will explode
2930
}
3031

dist/fireworks.js

+82-60
Original file line numberDiff line numberDiff line change
@@ -97,46 +97,60 @@ Object.defineProperty(exports, "__esModule", { value: true });
9797
const graphics_1 = __webpack_require__(2);
9898
const things_1 = __webpack_require__(3);
9999
class Fireworks {
100-
constructor(container, { rocketSpawnInterval = 150, maxRockets = 3, numParticles = 100, explosionHeight = 0.2, explosionChance = 0.08 } = {}) {
100+
constructor(container, { rocketSpawnInterval = 150, maxRockets = 3, numParticles = 100, explosionMinHeight = 0.2, explosionMaxHeight = 0.9, explosionChance = 0.08 } = {}) {
101101
this.rocketSpawnInterval = rocketSpawnInterval;
102102
this.maxRockets = maxRockets;
103-
this.numParticles = numParticles;
104-
this.explosionHeight = explosionHeight;
105-
this.explosionChance = explosionChance;
106103
this.cw = container.clientWidth;
107104
this.ch = container.clientHeight;
108105
this.graphics = new graphics_1.default(container);
109-
this.things = new things_1.default({ maxRockets: this.maxRockets, cw: this.cw, ch: this.ch });
106+
this.things = new things_1.default({
107+
maxRockets: this.maxRockets,
108+
numParticles,
109+
explosionMinHeight,
110+
explosionMaxHeight,
111+
explosionChance,
112+
cw: this.cw,
113+
ch: this.ch
114+
});
110115
container.appendChild(this.graphics.canvas);
116+
console.log(this.ch * (1 - explosionMaxHeight));
111117
}
112118
start() {
113-
window.requestAnimationFrame(() => this.update());
114-
this.interval = setInterval(() => this.things.spawnRockets(), this.rocketSpawnInterval);
119+
if (this.maxRockets > 0) {
120+
this.interval = setInterval(() => this.things.spawnRockets(), this.rocketSpawnInterval);
121+
this.rafInterval = window.requestAnimationFrame(() => this.update());
122+
}
115123
return () => this.stop();
116124
}
117125
stop() {
118126
window.clearInterval(this.interval);
119127
this.interval = null;
120128
}
129+
fire() {
130+
this.things.spawnRocket();
131+
if (!this.rafInterval) {
132+
this.rafInterval = window.requestAnimationFrame(() => this.update());
133+
}
134+
}
121135
update() {
122136
this.graphics.clear();
123137
let x = null;
124138
for (const particle of this.things) {
125-
if (!this.graphics.drawParticle(particle)) {
126-
this.things.delete(particle);
127-
continue;
128-
}
139+
this.graphics.drawParticle(particle);
129140
particle.update();
130-
if (particle.shouldExplode(this.ch, this.explosionHeight, this.explosionChance)) {
131-
particle.explode(this.numParticles).forEach(this.things.add, this.things);
141+
if (this.things.shouldRemove(particle)) {
132142
this.things.delete(particle);
133143
}
144+
else if (this.things.shouldExplode(particle)) {
145+
this.things.explode(particle);
146+
}
134147
}
135148
if (this.interval || this.things.size > 0) {
136-
window.requestAnimationFrame(() => this.update());
149+
this.rafInterval = window.requestAnimationFrame(() => this.update());
137150
}
138151
else {
139152
this.graphics.clear(true);
153+
this.rafInterval = null;
140154
}
141155
}
142156
}
@@ -179,16 +193,6 @@ class Graphics {
179193
this.ctx.lineWidth = particle.size;
180194
this.ctx.strokeStyle = `hsla(${particle.hue}, 100%, ${particle.brightness}%, ${particle.alpha})`;
181195
this.ctx.stroke();
182-
if (particle.alpha <= 0.1 || particle.size <= 1) {
183-
return false;
184-
}
185-
if (particle.position.x > this.cw || particle.position.x < 0) {
186-
return false;
187-
}
188-
if (particle.position.y > this.ch || particle.position.y < 0) {
189-
return false;
190-
}
191-
return true;
192196
}
193197
}
194198
exports.default = Graphics;
@@ -204,23 +208,67 @@ Object.defineProperty(exports, "__esModule", { value: true });
204208
const particle_1 = __webpack_require__(4);
205209
const util_1 = __webpack_require__(0);
206210
class Things extends Set {
207-
constructor({ maxRockets, cw, ch }) {
211+
constructor({ maxRockets, numParticles, explosionMinHeight, explosionMaxHeight, explosionChance, cw, ch }) {
208212
super();
209213
this.maxRockets = maxRockets;
214+
this.numParticles = numParticles;
215+
this.explosionMaxHeight = explosionMaxHeight,
216+
this.explosionMinHeight = explosionMinHeight,
217+
this.explosionChance = explosionChance;
210218
this.cw = cw;
211219
this.ch = ch;
212220
}
213-
spawnRockets() {
214-
const rockets = this.rockets;
215-
if (rockets < this.maxRockets) {
221+
shouldRemove(particle) {
222+
if (particle.alpha <= 0.1 || particle.size <= 1) {
223+
return true;
224+
}
225+
if (particle.position.x > this.cw || particle.position.x < 0) {
226+
return true;
227+
}
228+
if (particle.position.y > this.ch || particle.position.y < 0) {
229+
return true;
230+
}
231+
return false;
232+
}
233+
shouldExplode(particle) {
234+
if (!particle.isRocket) {
235+
return false;
236+
}
237+
if (particle.position.y <= this.ch * (1 - this.explosionMaxHeight)) {
238+
return true;
239+
}
240+
if (particle.position.y >= this.ch * (1 - this.explosionMinHeight)) {
241+
return false;
242+
}
243+
return util_1.random(0, 1) <= this.explosionChance;
244+
}
245+
explode(particle) {
246+
for (let i = 0; i < this.numParticles; i += 1) {
216247
this.add(new particle_1.default({
217-
isRocket: true,
218248
position: {
219-
x: util_1.random(0, this.cw),
220-
y: this.ch
221-
}
249+
x: particle.position.x,
250+
y: particle.position.y
251+
},
252+
hue: particle.hue,
253+
brightness: particle.brightness
222254
}));
223255
}
256+
this.delete(particle);
257+
}
258+
spawnRocket() {
259+
this.add(new particle_1.default({
260+
isRocket: true,
261+
position: {
262+
x: util_1.random(0, this.cw),
263+
y: this.ch
264+
}
265+
}));
266+
}
267+
spawnRockets() {
268+
const rockets = this.rockets;
269+
if (rockets < this.maxRockets) {
270+
this.spawnRocket();
271+
}
224272
}
225273
get rockets() {
226274
return [...this].filter(x => x.isRocket).length;
@@ -246,11 +294,10 @@ class Particle {
246294
this.position,
247295
this.position
248296
];
249-
this.velocity = { x: null, y: null };
250297
if (this.isRocket) {
251298
this.velocity = {
252-
x: util_1.random(0, 6) - 3,
253-
y: util_1.random(-3, 0) - 4
299+
x: util_1.random(-3, 3),
300+
y: util_1.random(-7, -3)
254301
};
255302
this.shrink = 0.999;
256303
this.resistance = 1;
@@ -272,31 +319,6 @@ class Particle {
272319
this.hue = hue;
273320
this.brightness = brightness;
274321
}
275-
shouldExplode(ch, explosionHeight, explosionChance) {
276-
if (!this.isRocket) {
277-
return false;
278-
}
279-
const inRange = this.position.y <= ch * (1 - explosionHeight);
280-
if (!inRange) {
281-
return false;
282-
}
283-
const shouldExplode = util_1.random(0, 1) <= explosionChance;
284-
return shouldExplode;
285-
}
286-
explode(count) {
287-
const newParticles = new Set();
288-
for (let i = 0; i < count; i += 1) {
289-
newParticles.add(new Particle({
290-
position: {
291-
x: this.position.x,
292-
y: this.position.y
293-
},
294-
hue: this.hue,
295-
brightness: this.brightness
296-
}));
297-
}
298-
return newParticles;
299-
}
300322
update() {
301323
this.positions.pop();
302324
this.positions.unshift({ x: this.position.x, y: this.position.y });

dist/fireworks.min.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

index.html

+6-3
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,22 @@
1818
</head>
1919
<body>
2020
<div id="container"></div>
21+
<button id="spawn">Fire!</button>
2122
<script>
2223
const container = document.getElementById('container')
2324
const options = {
24-
maxRockets: 5, // max # of rockets to spawn
25+
maxRockets: 3, // max # of rockets to spawn
2526
rocketSpawnInterval: 150, // millisends to check if new rockets should spawn
26-
numParticles: 150, // number of particles to spawn when rocket explodes (+0-10)
27-
explosionHeight: 0.2, // minimum percentage of height of container at which rockets explode
27+
numParticles: 100, // number of particles to spawn when rocket explodes (+0-10)
28+
explosionMinHeight: 0.2, // percentage. min height at which rockets can explode
29+
explosionMaxHeight: 0.9, // percentage. max height before a particle is exploded
2830
explosionChance: 0.08 // chance in each tick the rocket will explode
2931
}
3032
const fireworks = new Fireworks(container, options)
3133
const stop = fireworks.start()
3234

3335
document.addEventListener('keydown', (e) => e.which === 27 && stop())
36+
document.getElementById('spawn').addEventListener('click', () => fireworks.fire())
3437

3538
</script>
3639
</body>

package-lock.json

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "fireworks-canvas",
3-
"version": "2.0.1",
3+
"version": "2.1.0",
44
"description": "fireworks example",
55
"main": "./dist/fireworks..min.js",
66
"scripts": {

0 commit comments

Comments
 (0)