mirror of
https://github.com/webadderallorg/Recordly.git
synced 2026-09-24 14:55:37 +00:00
fix(hud): keep controls visible when recording starts
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { useCallback, useEffect, useRef, useState, type PointerEvent, type RefObject } from "react";
|
||||
import { mergeHudInteractiveBounds, shouldRestoreHudMousePassthroughAfterDrag } from "../hudMousePassthrough";
|
||||
import { clampHudOffsetToViewport } from "../hudViewportBounds";
|
||||
|
||||
const DEFAULT_RECORDING_HUD_OFFSET = { x: 0, y: 0 };
|
||||
|
||||
@@ -41,6 +42,47 @@ export function useHudBarDrag({
|
||||
}
|
||||
}, [recordingHudOffset]);
|
||||
|
||||
const keepHudBarInsideViewport = useCallback(() => {
|
||||
if (isHudDraggingRef.current || !hudBarRef.current) {
|
||||
return;
|
||||
}
|
||||
|
||||
const bounds = hudBarRef.current.getBoundingClientRect();
|
||||
const nextOffset = clampHudOffsetToViewport(
|
||||
recordingHudOffsetRef.current,
|
||||
bounds,
|
||||
{ width: window.innerWidth, height: window.innerHeight },
|
||||
);
|
||||
if (
|
||||
nextOffset.x === recordingHudOffsetRef.current.x &&
|
||||
nextOffset.y === recordingHudOffsetRef.current.y
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
recordingHudOffsetRef.current = nextOffset;
|
||||
if (hudBarTransformRef.current) {
|
||||
hudBarTransformRef.current.style.transform = `translate3d(${nextOffset.x}px, ${nextOffset.y}px, 0)`;
|
||||
}
|
||||
setRecordingHudOffset(nextOffset);
|
||||
}, [hudBarRef]);
|
||||
|
||||
useEffect(() => {
|
||||
const resizeObserver =
|
||||
typeof ResizeObserver === "undefined"
|
||||
? null
|
||||
: new ResizeObserver(keepHudBarInsideViewport);
|
||||
if (hudBarRef.current) {
|
||||
resizeObserver?.observe(hudBarRef.current);
|
||||
}
|
||||
window.addEventListener("resize", keepHudBarInsideViewport);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("resize", keepHudBarInsideViewport);
|
||||
resizeObserver?.disconnect();
|
||||
};
|
||||
}, [hudBarRef, keepHudBarInsideViewport]);
|
||||
|
||||
const handleHudBarPointerDown = useCallback((event: PointerEvent<HTMLDivElement>) => {
|
||||
if (event.button !== 0) {
|
||||
return;
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { clampHudOffsetToViewport } from "./hudViewportBounds";
|
||||
|
||||
describe("clampHudOffsetToViewport", () => {
|
||||
it("moves a dragged HUD back onscreen after the recording window becomes compact", () => {
|
||||
expect(
|
||||
clampHudOffsetToViewport(
|
||||
{ x: -463, y: -710 },
|
||||
{ left: -244, top: -656, right: 179, bottom: -586 },
|
||||
{ width: 860, height: 160 },
|
||||
),
|
||||
).toEqual({ x: -219, y: -54 });
|
||||
});
|
||||
|
||||
it("leaves an already visible HUD unchanged", () => {
|
||||
expect(
|
||||
clampHudOffsetToViewport(
|
||||
{ x: 12, y: -8 },
|
||||
{ left: 218, top: 54, right: 641, bottom: 124 },
|
||||
{ width: 860, height: 160 },
|
||||
),
|
||||
).toEqual({ x: 12, y: -8 });
|
||||
});
|
||||
|
||||
it("clamps the right and bottom edges after a viewport shrink", () => {
|
||||
expect(
|
||||
clampHudOffsetToViewport(
|
||||
{ x: 500, y: 200 },
|
||||
{ left: 700, top: 140, right: 1120, bottom: 210 },
|
||||
{ width: 860, height: 160 },
|
||||
),
|
||||
).toEqual({ x: 240, y: 150 });
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,39 @@
|
||||
export interface HudOffset {
|
||||
x: number;
|
||||
y: number;
|
||||
}
|
||||
|
||||
export interface HudViewportBounds {
|
||||
left: number;
|
||||
top: number;
|
||||
right: number;
|
||||
bottom: number;
|
||||
}
|
||||
|
||||
export interface HudViewportSize {
|
||||
width: number;
|
||||
height: number;
|
||||
}
|
||||
|
||||
function clampOffsetAxis(offset: number, start: number, end: number, viewportSize: number) {
|
||||
if (start < 0) {
|
||||
return offset - start;
|
||||
}
|
||||
|
||||
if (end > viewportSize) {
|
||||
return offset + viewportSize - end;
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
export function clampHudOffsetToViewport(
|
||||
offset: HudOffset,
|
||||
bounds: HudViewportBounds,
|
||||
viewport: HudViewportSize,
|
||||
): HudOffset {
|
||||
return {
|
||||
x: clampOffsetAxis(offset.x, bounds.left, bounds.right, viewport.width),
|
||||
y: clampOffsetAxis(offset.y, bounds.top, bounds.bottom, viewport.height),
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user