Skip to content

导航交互

导航交互在 OpenLayers 中提供核心地图导航功能,使用户能够通过鼠标、触摸和键盘输入来平移、缩放和旋转地图。这些交互基于用户手势修改 View 状态(中心点、缩放、旋转),并受视图约束影响。

关于底层事件处理系统和条件函数的信息,请参阅 事件处理和条件。关于要素创建和编辑交互的信息,请参阅 要素编辑交互

核心导航交互类

导航交互系统围绕几个处理不同类型用户输入的专门交互类构建:

基于鼠标的交互

MouseWheelZoom Interaction

  • 主要类: MouseWheelZoom src/ol/interaction/MouseWheelZoom.js49
  • 用途: 处理鼠标滚轮滚动以进行缩放操作
  • 关键特性: 支持触控板(平滑)和滚轮(离散)模式,可配置锚点,带超时的增量累积

DragPan Interaction

  • 主要类: DragPan src/ol/interaction/DragPan.js35
  • 用途: 通过用鼠标或触摸拖动来启用地图平移
  • 关键特性: 动量滚动支持,多指针质心计算,坐标转换

DragRotate Interaction

  • 主要类: DragRotate src/ol/interaction/DragRotate.js31
  • 用途: 允许在按住修饰键的同时通过拖动来旋转地图
  • 关键特性: 仅鼠标交互,可配置条件(默认:Alt+Shift),从地图中心计算角度

基于触摸的交互

PinchZoom Interaction

  • 主要类: PinchZoom src/ol/interaction/PinchZoom.js20
  • 用途: 处理两指捏合手势以进行缩放
  • 关键特性: 基于距离的缩放,以手势质心为锚点,在交互期间绕过分辨率约束

PinchRotate Interaction

  • 主要类: PinchRotate src/ol/interaction/PinchRotate.js23
  • 用途: 使用两指旋转手势启用地图旋转
  • 关键特性: 激活的角度阈值,旋转约束检查,锚点计算

组合交互

DragRotateAndZoom Interaction

DragZoom Interaction

  • 主要类: DragZoom src/ol/interaction/DragZoom.js32
  • 用途: 通过拖动选择矩形启用缩放框功能
  • 关键特性: 扩展 DragBox,可配置为放大或缩小,动画过渡

导航交互架构

SVG
100%

事件条件和激活控制

导航交互使用条件函数来确定何时应该响应用户输入。这些条件检查修饰键、输入设备类型和交互上下文。

主要条件函数

条件函数用途默认使用者
noModifierKeys未按下修饰键DragPan
shiftKeyOnly仅按下 Shift 键DragZoom、DragRotateAndZoom
altShiftKeysOnly按下 Alt 和 Shift 键DragRotate
mouseOnly仅鼠标设备输入DragRotate、DragRotateAndZoom
primaryAction主指针/左鼠标按钮DragPan
always始终活动MouseWheelZoom(默认)

焦点管理

几个交互支持 onFocusOnly 配置以在地图具有焦点的限制激活:

// Example: DragPan with focus requirement
this.condition_ = options.onFocusOnly
  ? all(focusWithTabindex, condition)
  : condition;

条件组合

可以使用逻辑运算符组合条件:

  • all(condition1, condition2, ...) - 所有条件都必须通过
  • 传递给构造函数的多个条件使用 all() 自动组合

视图状态修改流程

导航交互通过结构化流程修改 View 状态,该流程尊重约束并支持平滑动画。

SVG
100%

交互状态管理

开始/结束交互模式 大多数交互遵循三阶段生命周期:

  1. 开始: view.beginInteraction() - 设置交互提示,可能取消现有动画
  2. 更新: 在交互期间使用 adjust*Internal() 方法直接修改状态
  3. 结束: view.endInteraction() - 应用最终约束,触发吸附动画

DragPan 示例 src/ol/interaction/DragPan.js93-98:

if (!this.panning_) {
  this.panning_ = true;
  map.getView().beginInteraction();
}

PinchZoom 示例 src/ol/interaction/PinchZoom.js106-111:

const direction = this.lastScaleDelta_ > 1 ? 1 : -1;
view.endInteraction(this.duration_, direction);

交互期间的约束绕过

在活动交互期间,许多约束被绕过以允许平滑操作:

配置和自定义

通用配置选项

所有导航交互都支持标准配置模式:

选项用途默认值使用者
condition激活条件函数因交互而异全部
duration动画持续时间(毫秒)250-400大多数
onFocusOnly需要地图焦点false鼠标交互

特定于交互的选项

MouseWheelZoom 配置 src/ol/interaction/MouseWheelZoom.js14-30:

{
  maxDelta: 1,           // Maximum zoom delta per wheel event
  duration: 250,         // Animation duration
  timeout: 80,           // Accumulation timeout
  useAnchor: true,       // Zoom to mouse position
  constrainResolution: false  // Force discrete zoom levels
}

DragPan 配置 src/ol/interaction/DragPan.js21-28:

{
  condition: all(noModifierKeys, primaryAction),  // Activation condition
  kinetic: undefined,    // Kinetic scrolling object
  onFocusOnly: false     // Focus requirement
}

触摸交互配置:

  • PinchZoom: duration(默认 400ms)
  • PinchRotate: duration(250ms)、threshold(0.3 弧度)

运行时配置

一些交互提供用于运行时配置更改的方法:

MouseWheelZoom 锚点控制 src/ol/interaction/MouseWheelZoom.js312-317:

interaction.setMouseAnchor(false);  // Disable anchor-based zooming

默认导航设置

OpenLayers 通过 defaults() 函数提供一组默认的导航交互。虽然未在提供的文件中显示具体实现,但测试文件表明标准组合:

标准默认交互

基于测试导入和使用模式 test/browser/spec/ol/Map.test.js16-22:

  1. DragPan - 主要导航方法
  2. MouseWheelZoom - 桌面缩放控制
  3. PinchZoom - 触摸缩放控制
  4. PinchRotate - 触摸旋转控制
  5. DoubleClickZoom - 快速缩放功能

与地图集成

导航交互自动:

  • 添加到地图的交互集合
  • 通过 setMap() 连接到地图的事件系统
  • 通过 map.getView() 提供对 View 的访问
  • 受制于地图的视口和坐标系

地图集成示例 test/browser/spec/ol/Map.test.js115-124:

const map = new Map({});
const interactions = map.getInteractions();
// Default interactions are automatically added
for (let i = 0; i < interactions.getLength(); ++i) {
  expect(interactions.item(i).getMap()).to.be(map);
}