Skip to content

Commit 66fd259

Browse files
authored
Merge pull request #85 from crashmax-dev/fps-prop
feat: raf fps property
2 parents 164e114 + d468646 commit 66fd259

File tree

7 files changed

+63
-22
lines changed

7 files changed

+63
-22
lines changed

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ npm install @fireworks-js/web
173173
| `traceSpeed` | number | 10 |
174174
| `intensity` | number | 30 |
175175
| `autoresize` | boolean | true |
176+
| `fps` | number | 60 |
176177

177178
The `hue`, `delay`, `decay`, `brightness`, `lineWidth.explosion`, `lineWidth.trace`, `sound.volume` and `rocketsPoint` options accept an object:
178179

@@ -205,6 +206,7 @@ The `sound` options accept an object:
205206

206207
```js
207208
const fireworks = new Fireworks(container, {
209+
fps: 60,
208210
autoresize: true,
209211
opacity: 0.5,
210212
acceleration: 1.05,
@@ -222,8 +224,8 @@ const fireworks = new Fireworks(container, {
222224
max: 360
223225
},
224226
delay: {
225-
min: 15,
226-
max: 30
227+
min: 30,
228+
max: 60
227229
},
228230
rocketsPoint: {
229231
min: 50,

packages/fireworks-js/src/fireworks.ts

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Explosion } from './explosion.js'
22
import { randomFloat, randomInt } from './helpers.js'
33
import { Mouse } from './mouse.js'
44
import { opts } from './options.js'
5+
import { RequestAnimationFrame } from './raf.js'
56
import { Resize } from './resize.js'
67
import { Sound } from './sound.js'
78
import { Trace } from './trace.js'
@@ -14,17 +15,14 @@ export class Fireworks {
1415
private ctx: CanvasRenderingContext2D
1516
private width: number
1617
private height: number
17-
18-
private tick = 0
19-
private timestamp = performance.now()
20-
private running = false
21-
2218
private sound: Sound
2319
private resize: Resize
2420
private mouse: Mouse
2521
private traces: Trace[] = []
2622
private explosions: Explosion[] = []
2723
private waitStopRaf: (() => void) | null
24+
private raf: RequestAnimationFrame
25+
private running = false
2826

2927
constructor(
3028
container: Element | HTMLCanvasElement,
@@ -39,6 +37,7 @@ export class Fireworks {
3937
this.sound = new Sound()
4038
this.resize = new Resize(this)
4139
this.mouse = new Mouse(this.canvas)
40+
this.raf = new RequestAnimationFrame(this.render.bind(this))
4241
}
4342

4443
get isRunning(): boolean {
@@ -59,8 +58,7 @@ export class Fireworks {
5958
this.running = true
6059
this.resize.subscribe()
6160
this.mouse.subscribe()
62-
this.clear()
63-
this.render()
61+
this.raf.start()
6462
}
6563

6664
stop(dispose = false): void {
@@ -69,6 +67,7 @@ export class Fireworks {
6967
this.running = false
7068
this.resize.unsubscribe()
7169
this.mouse.unsubscribe()
70+
this.raf.stop()
7271
this.clear()
7372

7473
if (dispose) {
@@ -97,7 +96,9 @@ export class Fireworks {
9796
pause(): void {
9897
this.running = !this.running
9998
if (this.running) {
100-
this.render()
99+
this.raf.start()
100+
} else {
101+
this.raf.stop()
101102
}
102103
}
103104

@@ -150,11 +151,9 @@ export class Fireworks {
150151
this.updateSize()
151152
}
152153

153-
private render(timestamp = this.timestamp): void {
154+
private render(): void {
154155
if (!this.ctx || !this.running) return
155156

156-
requestAnimationFrame((timestamp) => this.render(timestamp))
157-
158157
this.ctx.globalCompositeOperation = 'destination-out'
159158
this.ctx.fillStyle = `rgba(0, 0, 0, ${opts.opacity})`
160159
this.ctx.fillRect(0, 0, this.width, this.height)
@@ -165,10 +164,6 @@ export class Fireworks {
165164
this.initTrace()
166165
this.drawTrace()
167166
this.drawExplosion()
168-
169-
const timeDiff = timestamp - this.timestamp
170-
this.timestamp = timestamp
171-
this.tick += (timeDiff * (opts.intensity * Math.PI)) / 1000
172167
}
173168

174169
private initTrace(): void {
@@ -186,7 +181,7 @@ export class Fireworks {
186181
} = opts
187182

188183
if (
189-
this.tick > randomInt(delay.min, delay.max) ||
184+
this.raf.tick > randomInt(delay.min, delay.max) ||
190185
(this.mouse.active && mouse.max > this.traces.length)
191186
) {
192187
this.traces.push(
@@ -209,7 +204,7 @@ export class Fireworks {
209204
})
210205
)
211206

212-
this.tick = 0
207+
this.raf.tick = 0
213208
}
214209
}
215210

packages/fireworks-js/src/options.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import type {
1010
} from './types.js'
1111

1212
class Options implements FireworksOptions {
13+
public fps: number
1314
public hue: MinMax
1415
public rocketsPoint: MinMax
1516
public opacity: number
@@ -33,6 +34,7 @@ class Options implements FireworksOptions {
3334
public autoresize: boolean
3435

3536
constructor() {
37+
this.fps = 60
3638
this.autoresize = true
3739
this.lineStyle = 'round'
3840
this.flickering = 50
@@ -74,8 +76,8 @@ class Options implements FireworksOptions {
7476
}
7577

7678
this.delay = {
77-
min: 15,
78-
max: 30
79+
min: 30,
80+
max: 60
7981
}
8082

8183
this.brightness = {

packages/fireworks-js/src/raf.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { opts } from './options.js'
2+
3+
export class RequestAnimationFrame {
4+
public tick = 0
5+
6+
private rafId = 0
7+
private fps = opts.fps
8+
private tolerance = 0.1
9+
private now: number
10+
11+
constructor(private readonly render: () => void) {}
12+
13+
start(): void {
14+
this.now = performance.now()
15+
const interval = 1000 / this.fps
16+
17+
const raf = (timestamp: number) => {
18+
this.rafId = requestAnimationFrame(raf)
19+
const delta = timestamp - this.now
20+
21+
if (delta >= interval - this.tolerance) {
22+
this.render()
23+
this.now = timestamp - (delta % interval)
24+
this.tick += (delta * (opts.intensity * Math.PI)) / 1000
25+
}
26+
}
27+
28+
this.rafId = requestAnimationFrame(raf)
29+
}
30+
31+
stop() {
32+
cancelAnimationFrame(this.rafId)
33+
}
34+
}

packages/fireworks-js/src/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
export type LineStyle = 'round' | 'square'
22

33
export interface IFireworksOptions {
4+
fps: number
45
hue: MinMax
56
rocketsPoint: MinMax
67
opacity: number

website/src/config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ export const fireworksOptions: FireworksOptions = {
7070
mouse: {
7171
click: true,
7272
move: false,
73-
max: 3
73+
max: 1
7474
}
7575
}
7676

website/src/index.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,14 @@ import {
99
mainContainer
1010
} from './config.js'
1111

12+
declare global {
13+
interface Window {
14+
fireworks: Fireworks
15+
}
16+
}
17+
1218
const fireworks = new Fireworks(fireworksContainer, fireworksOptions)
19+
window.fireworks = fireworks
1320
fireworks.start()
1421

1522
const fireworksGetters = {

0 commit comments

Comments
 (0)