diff options
Diffstat (limited to 'apps/web/src/services')
5 files changed, 180 insertions, 4 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 index f790ebb4..c67a5113 100644 --- a/apps/web/src/services/renderer/nodes/blur-background-node.ts +++ b/apps/web/src/services/renderer/nodes/blur-background-node.ts @@ -1,5 +1,5 @@ import { TIME_EPSILON_SECONDS } from "@/constants/animation-constants"; -import { buildGaussianBlurPasses } from "@/lib/effects/definitions/blur"; +import { buildGaussianBlurPasses, intensityToSigma } from "@/lib/effects/definitions/blur"; import { getSourceTimeAtClipTime } from "@/lib/retime"; import { videoCache } from "@/services/video-cache/service"; import type { RetimeConfig } from "@/lib/timeline"; @@ -128,8 +128,8 @@ export class BlurBackgroundNode extends BaseNode<BlurBackgroundNodeParams> { ); const passes = buildGaussianBlurPasses({ - sigmaX: this.params.blurIntensity * (renderer.width / 1920), - sigmaY: this.params.blurIntensity * (renderer.height / 1080), + sigmaX: intensityToSigma({ intensity: this.params.blurIntensity, resolution: renderer.width, reference: 1920 }), + sigmaY: intensityToSigma({ intensity: this.params.blurIntensity, resolution: renderer.height, reference: 1080 }), }); const effectResult = gpuRenderer.applyEffect({ source: offscreen as CanvasImageSource, diff --git a/apps/web/src/services/storage/migrations/__tests__/v20-to-v21.test.ts b/apps/web/src/services/storage/migrations/__tests__/v20-to-v21.test.ts new file mode 100644 index 00000000..af2124c8 --- /dev/null +++ b/apps/web/src/services/storage/migrations/__tests__/v20-to-v21.test.ts @@ -0,0 +1,92 @@ +import { describe, expect, test } from "bun:test"; +import { DEFAULT_BLUR_INTENSITY } from "@/constants/project-constants"; +import { transformProjectV20ToV21 } from "../transformers/v20-to-v21"; + +describe("V20 to V21 Migration", () => { + test("multiplies blur background intensity by 5", () => { + const result = transformProjectV20ToV21({ + project: { + id: "project-v20-blur", + version: 20, + metadata: { + id: "project-v20-blur", + name: "Project", + createdAt: "2024-01-01T00:00:00.000Z", + updatedAt: "2024-01-01T00:00:00.000Z", + }, + settings: { + fps: 30, + canvasSize: { width: 1920, height: 1080 }, + background: { type: "blur", blurIntensity: 100 }, + }, + currentSceneId: "scene-main", + scenes: [], + }, + }); + + expect(result.skipped).toBe(false); + expect(result.project.version).toBe(21); + const settings = result.project.settings as Record<string, unknown>; + const background = settings.background as Record<string, unknown>; + expect(background.blurIntensity).toBe(500); + }); + + test("uses default blur intensity when blur type but intensity missing", () => { + const result = transformProjectV20ToV21({ + project: { + id: "project-v20-blur-no-intensity", + version: 20, + settings: { + background: { type: "blur" }, + }, + scenes: [], + }, + }); + + expect(result.skipped).toBe(false); + const settings = result.project.settings as Record<string, unknown>; + const background = settings.background as Record<string, unknown>; + expect(background.blurIntensity).toBe(DEFAULT_BLUR_INTENSITY); + }); + + test("leaves color background unchanged", () => { + const result = transformProjectV20ToV21({ + project: { + id: "project-v20-color", + version: 20, + settings: { + background: { type: "color", color: "#000000" }, + }, + scenes: [], + }, + }); + + expect(result.skipped).toBe(false); + const settings = result.project.settings as Record<string, unknown>; + expect(settings.background).toEqual({ type: "color", color: "#000000" }); + }); + + test("skips projects already on v21", () => { + const result = transformProjectV20ToV21({ + project: { + id: "project-v21", + version: 21, + }, + }); + + expect(result.skipped).toBe(true); + expect(result.reason).toBe("already v21"); + }); + + test("skips projects not on v20", () => { + const result = transformProjectV20ToV21({ + project: { + id: "project-v19", + version: 19, + }, + }); + + expect(result.skipped).toBe(true); + expect(result.reason).toBe("not v20"); + }); +}); diff --git a/apps/web/src/services/storage/migrations/index.ts b/apps/web/src/services/storage/migrations/index.ts index d278263b..ea596435 100644 --- a/apps/web/src/services/storage/migrations/index.ts +++ b/apps/web/src/services/storage/migrations/index.ts @@ -19,10 +19,11 @@ import { V16toV17Migration } from "./v16-to-v17"; import { V17toV18Migration } from "./v17-to-v18";
import { V18toV19Migration } from "./v18-to-v19";
import { V19toV20Migration } from "./v19-to-v20";
+import { V20toV21Migration } from "./v20-to-v21";
export { runStorageMigrations } from "./runner";
export type { MigrationProgress } from "./runner";
-export const CURRENT_PROJECT_VERSION = 20;
+export const CURRENT_PROJECT_VERSION = 21;
export const migrations = [
new V0toV1Migration(),
@@ -45,4 +46,5 @@ export const migrations = [ new V17toV18Migration(),
new V18toV19Migration(),
new V19toV20Migration(),
+ new V20toV21Migration(),
];
diff --git a/apps/web/src/services/storage/migrations/transformers/v20-to-v21.ts b/apps/web/src/services/storage/migrations/transformers/v20-to-v21.ts new file mode 100644 index 00000000..63ad24de --- /dev/null +++ b/apps/web/src/services/storage/migrations/transformers/v20-to-v21.ts @@ -0,0 +1,66 @@ +import { DEFAULT_BLUR_INTENSITY } from "@/constants/project-constants"; +import { INTENSITY_TO_SIGMA_DIVISOR } from "@/lib/effects/definitions/blur"; +import type { MigrationResult, ProjectRecord } from "./types"; +import { getProjectId, isRecord } from "./utils"; + +export function transformProjectV20ToV21({ + project, +}: { + project: ProjectRecord; +}): MigrationResult<ProjectRecord> { + if (!getProjectId({ project })) { + return { project, skipped: true, reason: "no project id" }; + } + + const version = project.version; + if (typeof version !== "number") { + return { project, skipped: true, reason: "invalid version" }; + } + if (version >= 21) { + return { project, skipped: true, reason: "already v21" }; + } + if (version !== 20) { + return { project, skipped: true, reason: "not v20" }; + } + + return { + project: { + ...migrateBackgroundBlurScale({ project }), + version: 21, + }, + skipped: false, + }; +} + +function migrateBackgroundBlurScale({ + project, +}: { + project: ProjectRecord; +}): ProjectRecord { + if (!isRecord(project.settings)) { + return project; + } + + const settings = { ...project.settings }; + const background = settings.background; + if (!isRecord(background) || background.type !== "blur") { + return { ...project, settings }; + } + + const raw = background.blurIntensity; + const blurIntensity = + typeof raw === "number" && Number.isFinite(raw) + ? raw * INTENSITY_TO_SIGMA_DIVISOR + : DEFAULT_BLUR_INTENSITY; + + return { + ...project, + settings: { + ...settings, + background: { + ...background, + blurIntensity, + }, + }, + }; +} diff --git a/apps/web/src/services/storage/migrations/v20-to-v21.ts b/apps/web/src/services/storage/migrations/v20-to-v21.ts new file mode 100644 index 00000000..f04ad35f --- /dev/null +++ b/apps/web/src/services/storage/migrations/v20-to-v21.ts @@ -0,0 +1,16 @@ +import { StorageMigration } from "./base"; +import type { ProjectRecord } from "./transformers/types"; +import { transformProjectV20ToV21 } from "./transformers/v20-to-v21"; + +export class V20toV21Migration extends StorageMigration { + from = 20; + to = 21; + + async transform(project: ProjectRecord): Promise<{ + project: ProjectRecord; + skipped: boolean; + reason?: string; + }> { + return transformProjectV20ToV21({ project }); + } +} |
