summaryrefslogtreecommitdiff
path: root/apps/web/src/services/renderer/nodes/blur-background-node.ts
diff options
context:
space:
mode:
authorMaze <167211895+mazeincoding@users.noreply.github.com>2026-01-31 00:20:04 +0100
committerGitHub <noreply@github.com>2026-01-31 00:20:04 +0100
commit7bf0984698e43b9aa2dd879f65951318ed410390 (patch)
treeccf2cd590a47d550152afc07129cb55c71a9ec35 /apps/web/src/services/renderer/nodes/blur-background-node.ts
parent0173db99448d1c4c6415dcf15272e17551b48b04 (diff)
downloadopencut-7bf0984698e43b9aa2dd879f65951318ed410390.tar.gz
codebase overhaul (#697)
Diffstat (limited to 'apps/web/src/services/renderer/nodes/blur-background-node.ts')
-rw-r--r--apps/web/src/services/renderer/nodes/blur-background-node.ts75
1 files changed, 75 insertions, 0 deletions
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<BlurBackgroundNodeParams> {
+ 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<void> {
+ 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();
+ }
+}