feat(canvas): 框选 - 新增工具栏「框选」工具,空白处拖动框选后自动回到移动与选择 (#78)

Co-authored-by: sikongyue <3155157671@qq.com>
This commit is contained in:
爱笑的毛毛虫andsikongyue authored and GitHub committed 2026-08-02 14:40:20 +08:00
1 parent f5c6c3a80f
commit 0317ac5bc7
6 files changed
+24 -7

No files matched your search

@@ -12,6 +12,7 @@ type InfiniteCanvasProps = {
onViewportChange: (viewport: ViewportTransform) => void;
onViewportPreviewChange?: (viewport: ViewportTransform) => void;
onCanvasMouseDown?: (event: React.PointerEvent<HTMLDivElement>) => void;
boxSelectEnabled?: boolean;
onCanvasDoubleClick?: (event: React.MouseEvent<HTMLDivElement>) => void;
onCanvasDeselect?: () => void;
onContextMenu?: (event: React.MouseEvent) => void;
@@ -38,7 +39,7 @@ type PinchState = {
initialScale: number;
};
export function InfiniteCanvas({ containerRef, viewport, backgroundMode = "dots", onViewportChange, onViewportPreviewChange, onCanvasMouseDown, onCanvasDoubleClick, onCanvasDeselect, onContextMenu, onDrop, onFileDragEnter, onFileDragLeave, onFileDragOver, graphicsLayer, children }: InfiniteCanvasProps) {
export function InfiniteCanvas({ containerRef, viewport, backgroundMode = "dots", onViewportChange, onViewportPreviewChange, onCanvasMouseDown, boxSelectEnabled = false, onCanvasDoubleClick, onCanvasDeselect, onContextMenu, onDrop, onFileDragEnter, onFileDragLeave, onFileDragOver, graphicsLayer, children }: InfiniteCanvasProps) {
const theme = canvasThemes[useThemeStore((state) => state.theme)];
const panState = useRef({
isPanning: false,
@@ -196,7 +197,7 @@ export function InfiniteCanvas({ containerRef, viewport, backgroundMode = "dots"
const isTouch = event.pointerType === "touch";
const hasSelectionModifier = event.shiftKey || event.ctrlKey || event.metaKey || event.altKey;
if (event.button === 0 && !isSpacePressed && !isTouch && isBackgroundClick && hasSelectionModifier) {
if (event.button === 0 && !isSpacePressed && !isTouch && isBackgroundClick && (hasSelectionModifier || boxSelectEnabled)) {
event.preventDefault();
event.currentTarget.setPointerCapture(event.pointerId);
onCanvasMouseDown?.(event);
@@ -368,7 +369,7 @@ export function InfiniteCanvas({ containerRef, viewport, backgroundMode = "dots"
return (
<div
ref={containerRef}
className={`relative h-full w-full select-none overflow-hidden touch-none ${isPanning ? "cursor-grabbing" : "cursor-grab"}`}
className={`relative h-full w-full select-none overflow-hidden touch-none ${isPanning ? "cursor-grabbing" : boxSelectEnabled ? "cursor-crosshair" : "cursor-grab"}`}
style={{
background: theme.canvas.background,
overscrollBehavior: "none",