为 forge 查看器创建自定义工具,仅在控制+拖动事件时触发框选择工具

问题描述 投票:0回答:1

我正在努力实现以下目标:

  • 按住控制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
但我从未得到所需的最终结果。

javascript autodesk-forge autodesk-viewer autodesk
1个回答
0
投票

这有点棘手。 但你正走在正确的道路上。

本质上,您有一个自定义控制器,它充当其他两个控制器(Box 和 Multi)的代理,并且您正在执行自定义操作并使用 Box 和 Multi API 来触发您想要的 UX 行为。

我不完全确定缺少哪个事件,但是您可以查看 Box 和 Multi 扩展的未放大源代码,以找出答案。

这有帮助吗?

© www.soinside.com 2019 - 2024. All rights reserved.