我正在努力实现以下目标:
按住控制AND单击应允许多选(累积选择)
按住 Control 然后拖动鼠标应触发框选择工具
我面临的问题是,如果我想允许默认实现(累积选择),当鼠标未被拖动时,我必须在按下控制键后停止事件的传播。
因为用户会在开始拖动鼠标之前按下 Control 键,所以我目前没有看到任何仅在拖动开始后才启用框选择的方法。这有可能吗?我是不是看错了方向?还是我已经走进了死胡同?
我的实现:
/**
* Custom forge viewer tool to restrict box-selection to ctrl key + mouse drag action
* @param viewer Reference to the forge viewer instance
* @see {@link https://aps.autodesk.com/blog/custom-tools-forge-viewer|Forge Documentation}
*/
export const getCustomBoxSelectionTool = (viewer) => {
if (!viewer?.toolController) return null;
let isDragging = false;
const boxSelectionTool: NonNullable<CustomToolType> = {
active: false,
getName: () => 'custom-box-selection,
getNames: () => ['custom-box-selection'],
activate: async () => {
boxSelectionTool.active = true;
},
deactivate: () => {
boxSelectionTool.active = false;
},
getPriority: () => 1, // Set priority in the tool chain
handleKeyDown: (event, _key) => {
if (!event.ctrlKey) return false;
if (isDragging) {
viewer.toolController.activateTool('box-selection');
return false; // Allow propagation
} else {
// Prevent default box-selection behaviour
viewer.toolController.deactivateTool('box-selection');
// !! This prevents the event propagating to the mousemove event (as dragging would happen after pressing control)
return true; // Stop propagation
}
},
handleKeyUp: (event, _key) => {
if (event.ctrlKey) {
viewer.toolController.deactivateTool('box-selection');
}
return false; // Allow propagation
},
handleButtonDown: (_event, button) => {
// Check for left click (0 = left, 1 = middle, 2 = right)
if (button === 0) {
isDragging = true;
}
return false; // Allow propagation
},
handleButtonUp: (_event, button) => {
// Check for left click (0 = left, 1 = middle, 2 = right)
if (button === 0) {
isDragging = false;
}
viewer.toolController.deactivateTool('box-selection');
return false; // Allow propagation
},
handleMouseMove: event => {
if (event.ctrlKey && isDragging) {
viewer.toolController.activateTool('box-selection');
}
return false; // Allow propagation
}
};
return boxSelectionTool;
};
由于在
handleKeyDown
函数中停止传播,流永远不会进入 handleMouseMove
函数。我尝试过使用不同的处理程序组合,包括 handleSingleClick
但我从未得到所需的最终结果。
这有点棘手。 但你正走在正确的道路上。
本质上,您有一个自定义控制器,它充当其他两个控制器(Box 和 Multi)的代理,并且您正在执行自定义操作并使用 Box 和 Multi API 来触发您想要的 UX 行为。
我不完全确定缺少哪个事件,但是您可以查看 Box 和 Multi 扩展的未放大源代码,以找出答案。
这有帮助吗?