fix: 优化右键拖动布局
This commit is contained in:
@@ -10,7 +10,7 @@ import {
|
|||||||
type CSSProperties,
|
type CSSProperties,
|
||||||
type MutableRefObject,
|
type MutableRefObject,
|
||||||
} from "react";
|
} from "react";
|
||||||
import { Euler, Matrix4, PerspectiveCamera as ThreePerspectiveCamera, Quaternion, Spherical, Vector3 } from "three";
|
import { Euler, Matrix4, MOUSE, PerspectiveCamera as ThreePerspectiveCamera, Quaternion, Spherical, Vector3 } from "three";
|
||||||
import type { Object3D } from "three";
|
import type { Object3D } from "three";
|
||||||
import type { OrbitControls as OrbitControlsImpl } from "three-stdlib";
|
import type { OrbitControls as OrbitControlsImpl } from "three-stdlib";
|
||||||
import { clearViewportCaptureHandler, setViewportCaptureHandler } from "../io/captureBridge";
|
import { clearViewportCaptureHandler, setViewportCaptureHandler } from "../io/captureBridge";
|
||||||
@@ -640,6 +640,40 @@ function ViewportWheelGuard({ enabled }: { enabled: boolean }) {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 兜底:拦截画布上的浏览器右键上下文菜单(平移已改用中键,这里主要防误触右键弹系统菜单)。
|
||||||
|
* 以捕获阶段 + 非 passive 挂在 canvas 原生 dom 上;对右键 pointerdown 也 preventDefault,
|
||||||
|
* 顺手挡掉部分浏览器仍会冒出来的右键拖拽默认行为。 */
|
||||||
|
function ViewportContextMenuGuard() {
|
||||||
|
const { gl } = useThree();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const canvas = gl.domElement;
|
||||||
|
if (typeof canvas?.addEventListener !== "function") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const handleContextMenu = (event: Event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
};
|
||||||
|
// 右键按下时先拦掉浏览器默认行为,避免 Edge 把右键拖拽识别成手势
|
||||||
|
const handlePointerDown = (event: PointerEvent) => {
|
||||||
|
if (event.button === 2) {
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// 捕获阶段、非 passive:确保先于任何浏览器默认/手势逻辑执行
|
||||||
|
canvas.addEventListener("contextmenu", handleContextMenu, { capture: true, passive: false });
|
||||||
|
canvas.addEventListener("pointerdown", handlePointerDown, { capture: true, passive: false });
|
||||||
|
canvas.addEventListener("dragstart", handleContextMenu, { capture: true, passive: false });
|
||||||
|
return () => {
|
||||||
|
canvas.removeEventListener("contextmenu", handleContextMenu, { capture: true });
|
||||||
|
canvas.removeEventListener("pointerdown", handlePointerDown, { capture: true });
|
||||||
|
canvas.removeEventListener("dragstart", handleContextMenu, { capture: true });
|
||||||
|
};
|
||||||
|
}, [gl]);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/** 把渲染三件套注册给视频导出逻辑(逐帧离线渲染用),模式仿 CanvasCaptureBridge */
|
/** 把渲染三件套注册给视频导出逻辑(逐帧离线渲染用),模式仿 CanvasCaptureBridge */
|
||||||
function VideoExportBridge() {
|
function VideoExportBridge() {
|
||||||
const { camera, gl, scene } = useThree();
|
const { camera, gl, scene } = useThree();
|
||||||
@@ -914,8 +948,8 @@ export function DirectorCanvas() {
|
|||||||
<div
|
<div
|
||||||
className={`director-canvas${trajectoryPlacementObjectId ? " is-placing-trajectory" : ""}`}
|
className={`director-canvas${trajectoryPlacementObjectId ? " is-placing-trajectory" : ""}`}
|
||||||
data-testid="director-canvas"
|
data-testid="director-canvas"
|
||||||
// 屏蔽在画布上右键(右键平移)弹出的浏览器上下文菜单 / 手势:
|
// 兜底:拦截画布上的浏览器右键上下文菜单(与平移无关——平移已改中键)。
|
||||||
// 相机视角下没有 OrbitControls 接管右键,右键拖拽会直接触发浏览器手势,这里统一拦截。
|
// 相机视角下没有 OrbitControls 接管,右键仍可能弹出系统菜单,这里统一拦掉。
|
||||||
onContextMenu={(event) => event.preventDefault()}
|
onContextMenu={(event) => event.preventDefault()}
|
||||||
>
|
>
|
||||||
<Canvas
|
<Canvas
|
||||||
@@ -971,6 +1005,11 @@ export function DirectorCanvas() {
|
|||||||
enabled
|
enabled
|
||||||
makeDefault
|
makeDefault
|
||||||
target={DEFAULT_DIRECTOR_VIEW_SNAPSHOT.target}
|
target={DEFAULT_DIRECTOR_VIEW_SNAPSHOT.target}
|
||||||
|
// 按键映射:左键旋转 / 中键平移 / 滚轮推拉。
|
||||||
|
// 故意不把"平移"绑到右键——Edge 自 121 版起把「按住右键拖拽」作为浏览器级鼠标手势
|
||||||
|
// (前进/后退/切标签),页面层 preventDefault 无法拦截(微软官方确认无 JS 方案)。
|
||||||
|
// 平移改用中键,触摸板用户用双指拖拽即可,右键不再触发手势。
|
||||||
|
mouseButtons={{ LEFT: MOUSE.ROTATE, MIDDLE: MOUSE.PAN, RIGHT: undefined }}
|
||||||
// 滚轮推拉距离:three 默认 1 偏慢,这里整体调快(见常量注释)
|
// 滚轮推拉距离:three 默认 1 偏慢,这里整体调快(见常量注释)
|
||||||
zoomSpeed={VIEWPORT_WHEEL_ZOOM_SPEED}
|
zoomSpeed={VIEWPORT_WHEEL_ZOOM_SPEED}
|
||||||
onChange={(event) => {
|
onChange={(event) => {
|
||||||
@@ -1024,6 +1063,7 @@ export function DirectorCanvas() {
|
|||||||
viewMode={viewMode}
|
viewMode={viewMode}
|
||||||
/>
|
/>
|
||||||
<ViewportWheelGuard enabled={viewMode === "camera"} />
|
<ViewportWheelGuard enabled={viewMode === "camera"} />
|
||||||
|
<ViewportContextMenuGuard />
|
||||||
<PlaybackFrameDriver />
|
<PlaybackFrameDriver />
|
||||||
<VideoExportBridge />
|
<VideoExportBridge />
|
||||||
<PlaybackTransformSync />
|
<PlaybackTransformSync />
|
||||||
|
|||||||
Reference in New Issue
Block a user