Merge pull request #28 from ibs0d/revert-27-codex/enhance-zoom-behavior-in-livecameraview

Revert "Add cursor-relative shift-wheel zoom and refactor live zoom utilities"
This commit is contained in:
ibs0d 2026-03-09 10:15:56 +11:00 committed by GitHub
commit 5e722c2174
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 32 additions and 124 deletions

View File

@ -88,11 +88,7 @@ import {
MdPhotoCamera,
} from "react-icons/md";
import { Link, useNavigate } from "react-router-dom";
import {
TransformWrapper,
TransformComponent,
ReactZoomPanPinchRef,
} from "react-zoom-pan-pinch";
import { TransformWrapper, TransformComponent } from "react-zoom-pan-pinch";
import useSWR from "swr";
import { cn } from "@/lib/utils";
import { useSessionPersistence } from "@/hooks/use-session-persistence";
@ -128,11 +124,7 @@ import {
import ActivityIndicator from "@/components/indicators/activity-indicator";
import {
createLiveZoomWrapperProps,
getCursorRelativeZoomTransform,
getLiveZoomTransformStyles,
LIVE_ZOOM_MAX_SCALE,
LIVE_ZOOM_MIN_SCALE,
LIVE_ZOOM_SHIFT_WHEEL_STEP,
} from "@/views/live/liveZoom";
type LiveCameraViewProps = {
@ -154,7 +146,6 @@ export default function LiveCameraView({
const { isPortrait } = useMobileOrientation();
const mainRef = useRef<HTMLDivElement | null>(null);
const containerRef = useRef<HTMLDivElement>(null);
const zoomRef = useRef<ReactZoomPanPinchRef | null>(null);
const [{ width: windowWidth, height: windowHeight }] =
useResizeObserver(window);
@ -449,47 +440,8 @@ export default function LiveCameraView({
[config, webRTC],
);
const handlePlayerWheel = useCallback(
(e: React.WheelEvent<HTMLDivElement>) => {
if (!e.shiftKey || !zoomRef.current) {
return;
}
const transformState = zoomRef.current.instance.transformState;
const zoomStep =
e.deltaY < 0 ? LIVE_ZOOM_SHIFT_WHEEL_STEP : -LIVE_ZOOM_SHIFT_WHEEL_STEP;
const nextScale = Math.min(
LIVE_ZOOM_MAX_SCALE,
Math.max(LIVE_ZOOM_MIN_SCALE, transformState.scale + zoomStep),
);
if (nextScale === transformState.scale) {
return;
}
e.preventDefault();
const rect = e.currentTarget.getBoundingClientRect();
const nextTransform = getCursorRelativeZoomTransform(
transformState,
{
x: e.clientX - rect.left,
y: e.clientY - rect.top,
},
nextScale,
);
zoomRef.current.setTransform(
nextTransform.positionX,
nextTransform.positionY,
nextTransform.scale,
);
},
[],
);
return (
<TransformWrapper ref={zoomRef} {...createLiveZoomWrapperProps(debug)}>
<TransformWrapper {...createLiveZoomWrapperProps(debug)}>
<Toaster position="top-center" closeButton={true} />
<div
ref={mainRef}
@ -669,12 +621,7 @@ export default function LiveCameraView({
</div>
{!debug ? (
<div id="player-container" className="size-full" ref={containerRef}>
<TransformComponent
{...getLiveZoomTransformStyles("player")}
wrapperProps={{
onWheel: handlePlayerWheel,
}}
>
<TransformComponent {...getLiveZoomTransformStyles("player")}>
<div
className={`flex flex-col items-center justify-center ${growClassName}`}
ref={clickOverlayRef}

View File

@ -5,7 +5,7 @@ export type LiveZoomMode = "player" | "debug";
export type LiveZoomWrapperProps = Pick<
ReactZoomPanPinchProps,
"minScale" | "maxScale" | "wheel" | "disabled"
"minScale" | "wheel" | "disabled"
>;
export type LiveZoomTransformStyles = {
@ -19,76 +19,37 @@ export const LIVE_ZOOM_WHEEL_CONFIG: NonNullable<
smoothStep: 0.005,
};
export const LIVE_ZOOM_SHIFT_WHEEL_STEP = 0.1;
export const LIVE_ZOOM_MIN_SCALE = 1;
export const LIVE_ZOOM_MAX_SCALE = 5;
type LiveZoomTransformState = {
positionX: number;
positionY: number;
scale: number;
};
type LiveZoomPoint = {
x: number;
y: number;
};
export function getCursorRelativeZoomTransform(
transformState: LiveZoomTransformState,
cursorPoint: LiveZoomPoint,
nextScale: number,
): LiveZoomTransformState {
const scaleRatio = nextScale / transformState.scale;
return {
scale: nextScale,
positionX:
cursorPoint.x - (cursorPoint.x - transformState.positionX) * scaleRatio,
positionY:
cursorPoint.y - (cursorPoint.y - transformState.positionY) * scaleRatio,
const LIVE_ZOOM_TRANSFORM_STYLES: Record<LiveZoomMode, LiveZoomTransformStyles> =
{
player: {
wrapperStyle: {
width: "100%",
height: "100%",
},
contentStyle: {
position: "relative",
width: "100%",
height: "100%",
padding: "8px",
},
},
debug: {
wrapperStyle: {
width: "100%",
height: "100%",
},
contentStyle: {
position: "relative",
width: "100%",
height: "100%",
},
},
};
}
const LIVE_ZOOM_TRANSFORM_STYLES: Record<
LiveZoomMode,
LiveZoomTransformStyles
> = {
player: {
wrapperStyle: {
width: "100%",
height: "100%",
},
contentStyle: {
position: "relative",
width: "100%",
height: "100%",
padding: "8px",
},
},
debug: {
wrapperStyle: {
width: "100%",
height: "100%",
},
contentStyle: {
position: "relative",
width: "100%",
height: "100%",
},
},
};
export function createLiveZoomWrapperProps(
disabled: boolean,
): LiveZoomWrapperProps {
export function createLiveZoomWrapperProps(disabled: boolean): LiveZoomWrapperProps {
return {
minScale: LIVE_ZOOM_MIN_SCALE,
maxScale: LIVE_ZOOM_MAX_SCALE,
wheel: {
...LIVE_ZOOM_WHEEL_CONFIG,
disabled: true,
},
minScale: 1,
wheel: LIVE_ZOOM_WHEEL_CONFIG,
disabled,
};
}