From 7bf0984698e43b9aa2dd879f65951318ed410390 Mon Sep 17 00:00:00 2001 From: Maze <167211895+mazeincoding@users.noreply.github.com> Date: Sat, 31 Jan 2026 00:20:04 +0100 Subject: codebase overhaul (#697) --- .../renderer/nodes/blur-background-node.ts | 75 ++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 apps/web/src/services/renderer/nodes/blur-background-node.ts (limited to 'apps/web/src/services/renderer/nodes/blur-background-node.ts') diff --git a/apps/web/src/services/renderer/nodes/blur-background-node.ts b/apps/web/src/services/renderer/nodes/blur-background-node.ts new file mode 100644 index 00000000..504161d9 --- /dev/null +++ b/apps/web/src/services/renderer/nodes/blur-background-node.ts @@ -0,0 +1,75 @@ +import type { CanvasRenderer } from "../canvas-renderer"; +import { BaseNode } from "./base-node"; + +export type BlurBackgroundNodeParams = { + blurIntensity: number; + contentNodes: BaseNode[]; +}; + +export class BlurBackgroundNode extends BaseNode { + private blurIntensity: number; + private contentNodes: BaseNode[]; + + constructor(params: BlurBackgroundNodeParams) { + super(params); + this.blurIntensity = params.blurIntensity; + this.contentNodes = params.contentNodes; + } + + async render({ + renderer, + time, + }: { + renderer: CanvasRenderer; + time: number; + }): Promise { + let offscreen: OffscreenCanvas | HTMLCanvasElement; + let offscreenCtx: + | OffscreenCanvasRenderingContext2D + | CanvasRenderingContext2D; + + try { + offscreen = new OffscreenCanvas(renderer.width, renderer.height); + const ctx = offscreen.getContext("2d"); + if (!ctx) { + throw new Error("failed to get offscreen canvas context"); + } + offscreenCtx = ctx; + } catch { + offscreen = document.createElement("canvas"); + offscreen.width = renderer.width; + offscreen.height = renderer.height; + const ctx = offscreen.getContext("2d"); + if (!ctx) { + throw new Error("failed to get canvas context"); + } + offscreenCtx = ctx; + } + + const originalContext = renderer.context; + renderer.context = offscreenCtx; + + for (const node of this.contentNodes) { + await node.render({ renderer, time }); + } + + renderer.context = originalContext; + + const zoomScale = 1.4; + const scaledWidth = renderer.width * zoomScale; + const scaledHeight = renderer.height * zoomScale; + const offsetX = (renderer.width - scaledWidth) / 2; + const offsetY = (renderer.height - scaledHeight) / 2; + + renderer.context.save(); + renderer.context.filter = `blur(${this.blurIntensity}px)`; + renderer.context.drawImage( + offscreen as CanvasImageSource, + offsetX, + offsetY, + scaledWidth, + scaledHeight, + ); + renderer.context.restore(); + } +} -- cgit v1.3.1