修复角度调整弹窗拖拽误触底层画布
This commit is contained in:
parent
2793582fd1
commit
67c18dd820
@ -39,6 +39,22 @@ export function AngleEditDialog({
|
||||
});
|
||||
// 预览 Tab 状态:如果生成了结果,默认显示结果;否则显示原图
|
||||
const [activeTab, setActiveTab] = useState<"original" | "result">("original");
|
||||
const stopDialogEventPropagation = useCallback((event: React.SyntheticEvent) => {
|
||||
event.stopPropagation();
|
||||
}, []);
|
||||
|
||||
const stopDialogEventCapture = useCallback((event: React.SyntheticEvent) => {
|
||||
event.stopPropagation();
|
||||
}, []);
|
||||
|
||||
const stopDialogWheelPropagation = useCallback((event: React.WheelEvent) => {
|
||||
event.stopPropagation();
|
||||
}, []);
|
||||
|
||||
const stopDialogWheelCapture = useCallback((event: React.WheelEvent) => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}, []);
|
||||
|
||||
// 当对话框关闭时重置状态
|
||||
useEffect(() => {
|
||||
@ -173,6 +189,17 @@ export function AngleEditDialog({
|
||||
<Dialog open={open} onOpenChange={handleOpenChange}>
|
||||
<DialogContent
|
||||
className="max-w-4xl p-0 gap-0 overflow-hidden border-none shadow-2xl bg-background/95 backdrop-blur-xl"
|
||||
onPointerDownCapture={stopDialogEventCapture}
|
||||
onPointerMoveCapture={stopDialogEventCapture}
|
||||
onPointerUpCapture={stopDialogEventCapture}
|
||||
onMouseDown={stopDialogEventPropagation}
|
||||
onMouseMove={stopDialogEventPropagation}
|
||||
onMouseUp={stopDialogEventPropagation}
|
||||
onTouchStart={stopDialogEventPropagation}
|
||||
onTouchMove={stopDialogEventPropagation}
|
||||
onTouchEnd={stopDialogEventPropagation}
|
||||
onWheelCapture={stopDialogWheelCapture}
|
||||
onWheel={stopDialogWheelPropagation}
|
||||
onInteractOutside={(e) => {
|
||||
// 阻止点击遮罩层关闭对话框(防止意外触发导航)
|
||||
if (isProcessing) {
|
||||
@ -347,4 +374,3 @@ export function AngleEditDialog({
|
||||
}
|
||||
|
||||
export default AngleEditDialog;
|
||||
|
||||
|
||||
@ -171,15 +171,22 @@ export function CanvasWorkspace() {
|
||||
return !!target.closest("[data-canvas-node-id]");
|
||||
}, []);
|
||||
|
||||
const isEventFromCanvasContainer = useCallback((target: EventTarget | null) => {
|
||||
if (!(target instanceof Node) || !containerRef.current) return false;
|
||||
return containerRef.current.contains(target);
|
||||
}, []);
|
||||
|
||||
// 处理画布点击(取消选择)
|
||||
const handleCanvasClick = useCallback((e: React.MouseEvent) => {
|
||||
if (!isEventFromCanvasContainer(e.target)) return;
|
||||
if (!isPointOnNodeElement(e.target) && !isMarqueeSelecting) {
|
||||
clearSelection();
|
||||
}
|
||||
}, [clearSelection, isMarqueeSelecting, isPointOnNodeElement]);
|
||||
}, [clearSelection, isEventFromCanvasContainer, isMarqueeSelecting, isPointOnNodeElement]);
|
||||
|
||||
// 处理画布平移开始
|
||||
const handleMouseDown = useCallback((e: React.MouseEvent) => {
|
||||
if (!isEventFromCanvasContainer(e.target)) return;
|
||||
if (tool === 'pan' || e.button === 1 || (e.button === 0 && e.altKey)) {
|
||||
setIsPanning(true);
|
||||
setPanStart({ x: e.clientX - viewport.x, y: e.clientY - viewport.y });
|
||||
@ -193,10 +200,11 @@ export function CanvasWorkspace() {
|
||||
setMarqueeStart(start);
|
||||
setMarqueeEnd(start);
|
||||
}
|
||||
}, [isPointOnNodeElement, toCanvasPosition, tool, viewport]);
|
||||
}, [isEventFromCanvasContainer, isPointOnNodeElement, toCanvasPosition, tool, viewport]);
|
||||
|
||||
// 处理画布平移
|
||||
const handleMouseMove = useCallback((e: React.MouseEvent) => {
|
||||
if (!isEventFromCanvasContainer(e.target)) return;
|
||||
dragPointerRef.current = toCanvasPosition(e.clientX, e.clientY);
|
||||
if (isPanning) {
|
||||
setViewport({
|
||||
@ -209,10 +217,11 @@ export function CanvasWorkspace() {
|
||||
if (isMarqueeSelecting) {
|
||||
setMarqueeEnd(toCanvasPosition(e.clientX, e.clientY));
|
||||
}
|
||||
}, [isMarqueeSelecting, isPanning, panStart, setViewport, toCanvasPosition]);
|
||||
}, [isEventFromCanvasContainer, isMarqueeSelecting, isPanning, panStart, setViewport, toCanvasPosition]);
|
||||
|
||||
// 处理画布平移结束
|
||||
const handleMouseUp = useCallback(() => {
|
||||
const handleMouseUp = useCallback((e?: React.MouseEvent) => {
|
||||
if (e && !isEventFromCanvasContainer(e.target)) return;
|
||||
setIsPanning(false);
|
||||
|
||||
if (isMarqueeSelecting && marqueeStart && marqueeEnd) {
|
||||
@ -247,7 +256,7 @@ export function CanvasWorkspace() {
|
||||
setIsMarqueeSelecting(false);
|
||||
setMarqueeStart(null);
|
||||
setMarqueeEnd(null);
|
||||
}, [clearSelection, isMarqueeSelecting, marqueeEnd, marqueeStart, nodes, selectNodes, viewport.x, viewport.y, viewport.zoom]);
|
||||
}, [clearSelection, isEventFromCanvasContainer, isMarqueeSelecting, marqueeEnd, marqueeStart, nodes, selectNodes, viewport.x, viewport.y, viewport.zoom]);
|
||||
|
||||
// 新增图片后自动居中展示
|
||||
const centerNodeInView = useCallback((nodeId: string) => {
|
||||
@ -284,6 +293,7 @@ export function CanvasWorkspace() {
|
||||
|
||||
// 处理滚轮缩放
|
||||
const handleWheel = useCallback((e: React.WheelEvent) => {
|
||||
if (!isEventFromCanvasContainer(e.target)) return;
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
@ -308,7 +318,7 @@ export function CanvasWorkspace() {
|
||||
const newX = mouseX - (mouseX - viewport.x) * scaleChange;
|
||||
const newY = mouseY - (mouseY - viewport.y) * scaleChange;
|
||||
setViewport({ x: newX, y: newY, zoom: newZoom });
|
||||
}, [isMacPlatform, setViewport, viewport.x, viewport.y, viewport.zoom]);
|
||||
}, [isEventFromCanvasContainer, isMacPlatform, setViewport, viewport.x, viewport.y, viewport.zoom]);
|
||||
|
||||
const getImageDimensionsFromFile = useCallback((file: File): Promise<{
|
||||
width: number;
|
||||
|
||||
@ -421,6 +421,8 @@ export function QwenCameraWidget({
|
||||
}, []);
|
||||
|
||||
const handlePointerDown = useCallback((event: React.MouseEvent | React.TouchEvent) => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
if (!canvasRef.current || !cameraRef.current) return;
|
||||
|
||||
const clientX = "touches" in event ? event.touches[0].clientX : event.clientX;
|
||||
@ -446,7 +448,9 @@ export function QwenCameraWidget({
|
||||
}, [getMousePos]);
|
||||
|
||||
const handlePointerMove = useCallback((event: React.MouseEvent | React.TouchEvent) => {
|
||||
event.stopPropagation();
|
||||
if (!canvasRef.current || !cameraRef.current || !isDraggingRef.current) return;
|
||||
event.preventDefault();
|
||||
|
||||
const clientX = "touches" in event ? event.touches[0].clientX : event.clientX;
|
||||
const clientY = "touches" in event ? event.touches[0].clientY : event.clientY;
|
||||
@ -496,7 +500,11 @@ export function QwenCameraWidget({
|
||||
}
|
||||
}, [getMousePos, onStateChange]);
|
||||
|
||||
const handlePointerUp = useCallback(() => {
|
||||
const handlePointerUp = useCallback((event?: React.MouseEvent | React.TouchEvent) => {
|
||||
if (event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
isDraggingRef.current = false;
|
||||
dragTargetRef.current = null;
|
||||
if (canvasRef.current) {
|
||||
@ -504,6 +512,11 @@ export function QwenCameraWidget({
|
||||
}
|
||||
}, []);
|
||||
|
||||
const handleWheel = useCallback((event: React.WheelEvent) => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}, []);
|
||||
|
||||
// 下拉选择器变化处理
|
||||
const handleAzimuthChange = useCallback((value: string) => {
|
||||
const val = Number(value);
|
||||
@ -582,7 +595,7 @@ export function QwenCameraWidget({
|
||||
<div className="relative flex-1 min-h-0 bg-muted/20 rounded-lg overflow-hidden border">
|
||||
<canvas
|
||||
ref={canvasRef}
|
||||
className="w-full h-full block cursor-grab active:cursor-grabbing"
|
||||
className="w-full h-full block cursor-grab active:cursor-grabbing touch-none select-none"
|
||||
onMouseDown={handlePointerDown}
|
||||
onMouseMove={handlePointerMove}
|
||||
onMouseUp={handlePointerUp}
|
||||
@ -590,6 +603,8 @@ export function QwenCameraWidget({
|
||||
onTouchStart={handlePointerDown}
|
||||
onTouchMove={handlePointerMove}
|
||||
onTouchEnd={handlePointerUp}
|
||||
onTouchCancel={handlePointerUp}
|
||||
onWheel={handleWheel}
|
||||
/>
|
||||
|
||||
{/* 提示词浮层 - 放在底部 */}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user