UNPKG

raindrop-fx

Version:
121 lines (103 loc) 3.59 kB
import { Rect, TextureData, vec2 } from "@sardinefish/zogra-renderer"; import { RaindropRenderer, RenderOptions } from "./renderer"; import { RaindropSimulator, SimulatorOptions } from "./simulator"; import { Time } from "./utils"; interface Options extends SimulatorOptions, RenderOptions { } class RaindropFX { public options: Options; public renderer: RaindropRenderer; public simulator: RaindropSimulator; private animHandle = 0; constructor(options: Partial<Options> & {canvas: HTMLCanvasElement}) { const canvas = options.canvas; const defaultOptions: Options = { // Simulator options spawnInterval: [0.1, 0.1], spawnSize: [60, 100], spawnLimit: 2000, viewport: new Rect(vec2.zero(), vec2(canvas.width, canvas.height)), canvas: canvas, width: canvas.width, height: canvas.height, background: "", gravity: 2400, slipRate: 0, motionInterval: [0.1, 0.4], colliderSize: 1, trailDropDensity: 0.2, trailDistance: [20, 30], trailDropSize: [0.3, 0.5], trailSpread: 0.6, initialSpread: 0.5, shrinkRate: 0.01, velocitySpread: 0.3, evaporate: 10, xShifting: [0, 0.1], // Rendering options backgroundBlurSteps: 3, mist: true, mistColor: [0.01, 0.01, 0.01, 1], mistBlurStep: 4, mistTime: 10, dropletsPerSeconds: 500, dropletSize: [10, 30], smoothRaindrop: [0.96, 0.99], refractBase: 0.4, refractScale: 0.6, raindropCompose: "smoother", raindropLightPos: [-1, 1, 2, 0], raindropDiffuseLight: [0.2, 0.2, 0.2], raindropShadowOffset: 0.8, raindropEraserSize: [0.93, 1.0], raindropSpecularLight: [0, 0, 0], raindropSpecularShininess: 256, raindropLightBump: 1, }; this.options = { ...defaultOptions, ...options }; this.simulator = new RaindropSimulator(this.options); this.renderer = new RaindropRenderer(this.options); } async start() { await this.renderer.loadAssets(); let lastFrameTime = 0; const update = (delay: number) => { const dt = (delay - lastFrameTime) / 1000; lastFrameTime = delay; const time = <Time>{ dt: 0.03, total: delay / 1000 }; this.update(time); this.animHandle = requestAnimationFrame(update); }; this.animHandle = requestAnimationFrame(update); } stop() { cancelAnimationFrame(this.animHandle); } resize(width: number, height: number) { this.options.width = width; this.options.height = height; this.options.viewport = new Rect(vec2.zero(), vec2(width, height)); this.renderer.resize(); } async setBackground(background: string | TextureData) { this.renderer.options.background = background; await this.renderer.reloadBackground(); } private update(time: Time) { this.simulator.update(time); this.renderer.render(this.simulator.raindrops, time); } } export = RaindropFX;