wuhan-gl/CANVAS_DRIVER_GUIDE.md

5.8 KiB
Raw Blame History

Canvas 场景下使用 Driver.js 的指南

概述

Driver.js 可以用于 Canvas 场景,但有一些限制和特殊处理方式。

Driver.js 在 Canvas 中的限制

  1. 无法直接高亮 Canvas 内部元素Driver.js 只能高亮 DOM 元素,而 Canvas 内部绘制的内容(如设备图标、点标记等)不是 DOM 元素,无法直接高亮。

  2. 可以高亮 Canvas 元素本身:可以高亮整个 <canvas> 标签,但无法精确定位到 Canvas 内部的某个绘制内容。

解决方案

方案 1高亮整个 Canvas最简单

直接高亮 Canvas 元素本身,适用于引导用户了解 Canvas 区域的功能。

{
  element: '.main-canvas', // 或 '.canvas-wrapper'
  popover: {
    title: '平面图区域',
    description: '这是平面图显示区域,您可以在这里查看设备位置和状态。',
    side: 'top',
    align: 'center'
  }
}

方案 2使用占位元素推荐用于精确引导

如果需要在 Canvas 内部某个特定位置进行引导,可以创建一个临时的占位 DOM 元素:

// 创建占位元素
const createPlaceholder = (x, y, width, height) => {
  const placeholder = document.createElement('div');
  placeholder.className = 'canvas-placeholder';
  placeholder.style.position = 'absolute';
  placeholder.style.left = `${x}px`;
  placeholder.style.top = `${y}px`;
  placeholder.style.width = `${width}px`;
  placeholder.style.height = `${height}px`;
  placeholder.style.pointerEvents = 'none'; // 不阻挡 Canvas 交互
  placeholder.style.zIndex = '1000';
  document.body.appendChild(placeholder);
  return placeholder;
};

// 在引导步骤中使用
{
  element: '.canvas-placeholder',
  popover: {
    title: '设备图标',
    description: '这是设备图标的位置,在编辑模式下可以拖拽移动。',
    side: 'top',
    align: 'center'
  }
}

方案 3使用自定义高亮高级

结合 Canvas 坐标计算和自定义高亮层:

// 计算 Canvas 内部元素的屏幕坐标
const getCanvasElementScreenPos = (canvasElement, canvasX, canvasY, scale, offsetX, offsetY) => {
  const rect = canvasElement.getBoundingClientRect();
  const screenX = rect.left + (canvasX * scale + offsetX);
  const screenY = rect.top + (canvasY * scale + offsetY);
  return { screenX, screenY };
};

// 创建自定义高亮层
const createCustomHighlight = (x, y, width, height) => {
  const highlight = document.createElement('div');
  highlight.className = 'custom-canvas-highlight';
  highlight.style.position = 'fixed';
  highlight.style.left = `${x}px`;
  highlight.style.top = `${y}px`;
  highlight.style.width = `${width}px`;
  highlight.style.height = `${height}px`;
  highlight.style.border = '3px solid #4dabf7';
  highlight.style.borderRadius = '8px';
  highlight.style.boxShadow = '0 0 20px rgba(77, 171, 247, 0.5)';
  highlight.style.pointerEvents = 'none';
  highlight.style.zIndex = '9999';
  document.body.appendChild(highlight);
  return highlight;
};

实际应用示例

示例 1引导 Canvas 区域

{
  element: '.canvas-wrapper',
  popover: {
    title: '平面图区域',
    description: '这是主要的平面图显示区域,所有设备都会在这里显示。',
    side: 'top',
    align: 'center'
  }
}

示例 2引导 Canvas 中的特定设备(需要坐标计算)

// 假设要引导一个设备,其 Canvas 坐标为 (pointX, pointY)
const guideDevice = (pointX, pointY) => {
  nextTick(() => {
    if (!canvasRef.value) return;
    
    // 计算设备在屏幕上的位置
    const rect = canvasRef.value.getBoundingClientRect();
    const screenX = rect.left + (pointX * BL.value * scale.value + offsetX.value);
    const screenY = rect.top + (pointY * BL.value * scale.value + offsetY.value);
    
    // 创建占位元素
    const placeholder = document.createElement('div');
    placeholder.className = 'device-placeholder';
    placeholder.style.position = 'fixed';
    placeholder.style.left = `${screenX - 20}px`;
    placeholder.style.top = `${screenY - 20}px`;
    placeholder.style.width = '40px';
    placeholder.style.height = '40px';
    placeholder.style.pointerEvents = 'none';
    placeholder.style.zIndex = '9999';
    document.body.appendChild(placeholder);
    
    // 使用 driver.js 高亮占位元素
    driverObj.highlight({
      element: '.device-placeholder',
      popover: {
        title: '设备图标',
        description: '这是设备图标,在编辑模式下可以拖拽移动。',
        side: 'bottom',
        align: 'center'
      }
    });
    
    // 引导结束后移除占位元素
    setTimeout(() => {
      placeholder.remove();
    }, 5000);
  });
};

当前项目中的最佳实践

在当前项目中,由于主要功能按钮(筛选、分区、编辑)都是 DOM 元素Driver.js 可以正常工作。对于 Canvas 内部的引导,建议:

  1. 引导 Canvas 容器:高亮整个 Canvas 区域,说明整体功能
  2. 引导相关操作按钮:通过引导操作按钮(如编辑按钮)来间接引导 Canvas 功能
  3. 结合文字说明:在引导提示中详细说明 Canvas 的操作方式

注意事项

  1. 坐标转换Canvas 内部坐标需要转换为屏幕坐标才能创建占位元素
  2. 缩放和偏移:需要考虑 Canvas 的缩放scale和偏移offsetX, offsetY
  3. 动态更新:如果 Canvas 内容会移动或变化,占位元素的位置也需要动态更新
  4. 性能考虑:占位元素应该及时清理,避免内存泄漏

总结

Driver.js 可以用于 Canvas 场景,但需要根据具体需求选择合适的方案:

  • 简单场景:直接高亮 Canvas 元素
  • 精确引导:使用占位元素或自定义高亮
  • 当前项目:已有 DOM 按钮的引导已经足够,无需额外处理 Canvas 内部元素