mirror of
https://github.com/webadderallorg/Recordly.git
synced 2026-09-24 23:05:49 +00:00
Keep window crops aligned as windows change
This commit is contained in:
@@ -21,6 +21,7 @@ import {
|
||||
} from "@/lib/mediaTiming";
|
||||
import {
|
||||
destroyPixiApplication,
|
||||
destroyPixiContainer,
|
||||
initializePixiApplicationWithTimeout,
|
||||
} from "@/lib/pixiApplicationLifecycle";
|
||||
import {
|
||||
@@ -1997,16 +1998,12 @@ const VideoPlayback = forwardRef<VideoPlaybackRef, VideoPlaybackProps>(
|
||||
video.removeEventListener("seeking", handleSeeking);
|
||||
dispose();
|
||||
|
||||
if (videoSprite) {
|
||||
videoContainer.removeChild(videoSprite);
|
||||
videoSprite.destroy();
|
||||
}
|
||||
cameraContainer.removeChild(maskGraphics);
|
||||
maskGraphics.destroy();
|
||||
videoEffectsContainer.mask = null;
|
||||
videoContainer.mask = null;
|
||||
destroyPixiContainer(videoSprite);
|
||||
destroyPixiContainer(maskGraphics);
|
||||
maskGraphicsRef.current = null;
|
||||
videoTexture.destroy(false);
|
||||
if (!videoTexture.destroyed) videoTexture.destroy(false);
|
||||
|
||||
videoSpriteRef.current = null;
|
||||
};
|
||||
|
||||
@@ -34,7 +34,10 @@ import {
|
||||
PixiCursorOverlay,
|
||||
preloadCursorAssets,
|
||||
} from "@/components/video-editor/videoPlayback/cursorRenderer";
|
||||
import { computePaddedLayout } from "@/components/video-editor/videoPlayback/layoutUtils";
|
||||
import {
|
||||
computePaddedLayout,
|
||||
scalePreviewBorderRadius,
|
||||
} from "@/components/video-editor/videoPlayback/layoutUtils";
|
||||
import {
|
||||
createSpringState,
|
||||
getZoomSpringConfig,
|
||||
@@ -1622,13 +1625,12 @@ export class FrameRenderer {
|
||||
|
||||
this.videoContainer.position.set(0, 0);
|
||||
|
||||
const canvasScaleFactor = Math.min(
|
||||
width / BASE_PREVIEW_WIDTH,
|
||||
height / BASE_PREVIEW_HEIGHT,
|
||||
const scaledBorderRadius = scalePreviewBorderRadius(
|
||||
layout.croppedDisplayWidth,
|
||||
layout.croppedDisplayHeight,
|
||||
borderRadius,
|
||||
);
|
||||
|
||||
const scaledBorderRadius = borderRadius * canvasScaleFactor;
|
||||
|
||||
this.maskGraphics.clear();
|
||||
drawSquircleOnGraphics(this.maskGraphics, {
|
||||
x: layout.centerOffsetX,
|
||||
|
||||
@@ -2,10 +2,22 @@ import type { Application } from "pixi.js";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import {
|
||||
destroyPixiApplication,
|
||||
destroyPixiContainer,
|
||||
initializePixiApplication,
|
||||
initializePixiApplicationWithTimeout,
|
||||
} from "./pixiApplicationLifecycle";
|
||||
|
||||
function createContainer(destroyed = false) {
|
||||
const container = {
|
||||
destroyed,
|
||||
destroy: vi.fn(() => {
|
||||
container.destroyed = true;
|
||||
}),
|
||||
parent: { removeChild: vi.fn() },
|
||||
};
|
||||
return container;
|
||||
}
|
||||
|
||||
function createApplication(init: () => Promise<void> = async () => undefined) {
|
||||
return {
|
||||
init: vi.fn(init),
|
||||
@@ -16,6 +28,19 @@ function createApplication(init: () => Promise<void> = async () => undefined) {
|
||||
}
|
||||
|
||||
describe("Pixi application lifecycle", () => {
|
||||
it("safely ignores display objects already destroyed by their application", () => {
|
||||
const liveContainer = createContainer();
|
||||
destroyPixiContainer(liveContainer as never);
|
||||
destroyPixiContainer(liveContainer as never);
|
||||
expect(liveContainer.parent.removeChild).toHaveBeenCalledTimes(1);
|
||||
expect(liveContainer.destroy).toHaveBeenCalledTimes(1);
|
||||
|
||||
const destroyedContainer = createContainer(true);
|
||||
destroyPixiContainer(destroyedContainer as never);
|
||||
expect(destroyedContainer.parent.removeChild).not.toHaveBeenCalled();
|
||||
expect(destroyedContainer.destroy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("cleans a failed initialization without running uninitialized plugins", async () => {
|
||||
const initializationError = new Error("No available renderer");
|
||||
const app = createApplication(async () => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { Application } from "pixi.js";
|
||||
import type { Application, Container } from "pixi.js";
|
||||
|
||||
type PixiInitializationState = "initializing" | "initialized" | "failed";
|
||||
type PixiInitOptions = Parameters<Application["init"]>[0];
|
||||
@@ -108,3 +108,9 @@ export function destroyPixiApplication(app: Application | null, context: string)
|
||||
destroyContexts.set(app, context);
|
||||
if (initializationStates.get(app) !== "initializing") completeDestroy(app);
|
||||
}
|
||||
|
||||
export function destroyPixiContainer(container: Container | null): void {
|
||||
if (!container || container.destroyed) return;
|
||||
container.parent?.removeChild(container);
|
||||
container.destroy();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user