fix(zoom): address PR review — preview selected zoom + keyboard a11y
- VideoPlayback: while holding Preview, render the SELECTED zoom at full strength regardless of the playhead, instead of whatever findDominantRegion returns at currentTime (which is none/another zoom when the playhead is outside the selection). Uses getZoomScale/getRotation3D for the region's configured scale and 3D preset. - SettingsPanel: require both onZoomPreviewStart && onZoomPreviewEnd to render the button (full lifecycle), and add keyboard support — Space/Enter keydown (repeat-guarded) starts preview, keyup/blur ends it.
This commit is contained in:
@@ -944,13 +944,26 @@ export function SettingsPanel({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{zoomEnabled && (onZoomPreviewStart || onZoomPreviewEnd) && (
|
{zoomEnabled && onZoomPreviewStart && onZoomPreviewEnd && (
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
onPointerDown={() => onZoomPreviewStart?.()}
|
onPointerDown={() => onZoomPreviewStart()}
|
||||||
onPointerUp={() => onZoomPreviewEnd?.()}
|
onPointerUp={() => onZoomPreviewEnd()}
|
||||||
onPointerLeave={() => onZoomPreviewEnd?.()}
|
onPointerLeave={() => onZoomPreviewEnd()}
|
||||||
onPointerCancel={() => onZoomPreviewEnd?.()}
|
onPointerCancel={() => onZoomPreviewEnd()}
|
||||||
|
onKeyDown={(e) => {
|
||||||
|
if ((e.key === " " || e.key === "Enter") && !e.repeat) {
|
||||||
|
e.preventDefault();
|
||||||
|
onZoomPreviewStart();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onKeyUp={(e) => {
|
||||||
|
if (e.key === " " || e.key === "Enter") {
|
||||||
|
e.preventDefault();
|
||||||
|
onZoomPreviewEnd();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onBlur={() => onZoomPreviewEnd()}
|
||||||
className="h-7 w-full select-none rounded-md border border-white/[0.08] bg-white/[0.04] text-[10px] font-semibold text-slate-300 transition-all duration-150 ease-out hover:bg-white/[0.08] hover:text-slate-100 active:border-[#34B27B]/50 active:bg-[#34B27B] active:text-white cursor-pointer"
|
className="h-7 w-full select-none rounded-md border border-white/[0.08] bg-white/[0.04] text-[10px] font-semibold text-slate-300 transition-all duration-150 ease-out hover:bg-white/[0.08] hover:text-slate-100 active:border-[#34B27B]/50 active:bg-[#34B27B] active:text-white cursor-pointer"
|
||||||
>
|
>
|
||||||
{t("zoom.previewHold")}
|
{t("zoom.previewHold")}
|
||||||
|
|||||||
@@ -59,6 +59,8 @@ import {
|
|||||||
DEFAULT_CURSOR_SIZE,
|
DEFAULT_CURSOR_SIZE,
|
||||||
DEFAULT_CURSOR_SMOOTHING,
|
DEFAULT_CURSOR_SMOOTHING,
|
||||||
DEFAULT_ROTATION_3D,
|
DEFAULT_ROTATION_3D,
|
||||||
|
getRotation3D,
|
||||||
|
getZoomScale,
|
||||||
isRotation3DIdentity,
|
isRotation3DIdentity,
|
||||||
lerpRotation3D,
|
lerpRotation3D,
|
||||||
rotation3DPerspective,
|
rotation3DPerspective,
|
||||||
@@ -1301,7 +1303,7 @@ const VideoPlayback = forwardRef<VideoPlaybackRef, VideoPlaybackProps>(
|
|||||||
let lastTransformIsIdentity = true;
|
let lastTransformIsIdentity = true;
|
||||||
let lastPerspectiveValue = 0;
|
let lastPerspectiveValue = 0;
|
||||||
const ticker = () => {
|
const ticker = () => {
|
||||||
const { region, strength, blendedScale, rotation3D, transition } = findDominantRegion(
|
let { region, strength, blendedScale, rotation3D, transition } = findDominantRegion(
|
||||||
zoomRegionsRef.current,
|
zoomRegionsRef.current,
|
||||||
currentTimeRef.current,
|
currentTimeRef.current,
|
||||||
{
|
{
|
||||||
@@ -1310,6 +1312,21 @@ const VideoPlayback = forwardRef<VideoPlaybackRef, VideoPlaybackProps>(
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// While holding Preview, show the SELECTED zoom (what the settings panel
|
||||||
|
// is editing) at full strength, independent of the playhead — otherwise
|
||||||
|
// the preview reflects whatever region sits at currentTime, which may be
|
||||||
|
// none or a different zoom when the playhead isn't inside the selection.
|
||||||
|
if (isPreviewingZoomRef.current && selectedZoomIdRef.current) {
|
||||||
|
const sel = zoomRegionsRef.current.find((r) => r.id === selectedZoomIdRef.current);
|
||||||
|
if (sel) {
|
||||||
|
region = sel;
|
||||||
|
strength = 1;
|
||||||
|
blendedScale = getZoomScale(sel);
|
||||||
|
rotation3D = getRotation3D(sel);
|
||||||
|
transition = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const defaultFocus = DEFAULT_FOCUS;
|
const defaultFocus = DEFAULT_FOCUS;
|
||||||
let targetScaleFactor = 1;
|
let targetScaleFactor = 1;
|
||||||
let targetFocus = defaultFocus;
|
let targetFocus = defaultFocus;
|
||||||
|
|||||||
Reference in New Issue
Block a user