Keep export masks stable during zoom transforms

This commit is contained in:
young committed 2026-09-04 20:19:06 +10:00
1 parent 0c3cdb24ce
commit 704103c200
2 files changed
+23 -2

No files matched your search

+17
View File
@@ -1,3 +1,5 @@
import { readFileSync } from "node:fs";
import { fileURLToPath } from "node:url";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { DEFAULT_WEBCAM_OVERLAY } from "../../components/video-editor/types";
@@ -90,6 +92,11 @@ vi.mock("./localMediaSource", () => ({
import { FrameRenderer } from "./frameRenderer";
const rendererSource = readFileSync(
fileURLToPath(new URL("./frameRenderer.ts", import.meta.url)),
"utf8",
);
type MockFunction = ReturnType<typeof vi.fn>;
type MockContext = {
beginPath: MockFunction;
@@ -123,6 +130,16 @@ type FrameRendererTestAccess = {
) => void;
};
describe("FrameRenderer mask hierarchy", () => {
it("keeps the mask in the video wrapper when camera transforms change", () => {
expect(rendererSource).toContain(
"this.cameraContainer.addChild(this.videoEffectsContainer)",
);
expect(rendererSource).toContain("this.videoEffectsContainer.addChild(this.maskGraphics)");
expect(rendererSource).not.toContain("this.cameraContainer.addChild(this.maskGraphics)");
});
});
type Listener = {
callback: () => void;
once: boolean;
+6 -2
View File
@@ -233,6 +233,7 @@ function configureHighQuality2DContext(
export class FrameRenderer {
private app: Application | null = null;
private cameraContainer: Container | null = null;
private videoEffectsContainer: Container | null = null;
private videoContainer: Container | null = null;
private cursorContainer: Container | null = null;
private videoSprite: Sprite | null = null;
@@ -399,11 +400,13 @@ export class FrameRenderer {
// Setup containers
this.cameraContainer = new Container();
this.videoEffectsContainer = new Container();
this.videoContainer = new Container();
this.cursorContainer = new Container();
this.app.stage.addChild(this.cameraContainer);
this.cameraContainer.addChild(this.videoContainer);
this.cameraContainer.addChild(this.videoEffectsContainer);
this.cameraContainer.addChild(this.cursorContainer);
this.videoEffectsContainer.addChild(this.videoContainer);
if (cursorOverlayEnabled) {
this.cursorOverlay = new PixiCursorOverlay({
@@ -499,7 +502,7 @@ export class FrameRenderer {
// Setup mask
this.maskGraphics = new Graphics();
this.cameraContainer.addChild(this.maskGraphics);
this.videoEffectsContainer.addChild(this.maskGraphics);
this.videoContainer.mask = this.maskGraphics;
if (this.cursorOverlay) {
this.cursorContainer.addChild(this.cursorOverlay.container);
@@ -2208,6 +2211,7 @@ export class FrameRenderer {
this.zoomBlurFilter?.destroy();
this.motionBlurFilter?.destroy();
this.cameraContainer = null;
this.videoEffectsContainer = null;
this.videoContainer = null;
this.maskGraphics = null;
this.zoomBlurFilter = null;