导航交互
导航交互在 OpenLayers 中提供核心地图导航功能,使用户能够通过鼠标、触摸和键盘输入来平移、缩放和旋转地图。这些交互基于用户手势修改 View 状态(中心点、缩放、旋转),并受视图约束影响。
关于底层事件处理系统和条件函数的信息,请参阅 事件处理和条件。关于要素创建和编辑交互的信息,请参阅 要素编辑交互。
核心导航交互类
导航交互系统围绕几个处理不同类型用户输入的专门交互类构建:
基于鼠标的交互
MouseWheelZoom Interaction
- 主要类:
MouseWheelZoomsrc/ol/interaction/MouseWheelZoom.js49 - 用途: 处理鼠标滚轮滚动以进行缩放操作
- 关键特性: 支持触控板(平滑)和滚轮(离散)模式,可配置锚点,带超时的增量累积
DragPan Interaction
- 主要类:
DragPansrc/ol/interaction/DragPan.js35 - 用途: 通过用鼠标或触摸拖动来启用地图平移
- 关键特性: 动量滚动支持,多指针质心计算,坐标转换
DragRotate Interaction
- 主要类:
DragRotatesrc/ol/interaction/DragRotate.js31 - 用途: 允许在按住修饰键的同时通过拖动来旋转地图
- 关键特性: 仅鼠标交互,可配置条件(默认:Alt+Shift),从地图中心计算角度
基于触摸的交互
PinchZoom Interaction
- 主要类:
PinchZoomsrc/ol/interaction/PinchZoom.js20 - 用途: 处理两指捏合手势以进行缩放
- 关键特性: 基于距离的缩放,以手势质心为锚点,在交互期间绕过分辨率约束
PinchRotate Interaction
- 主要类:
PinchRotatesrc/ol/interaction/PinchRotate.js23 - 用途: 使用两指旋转手势启用地图旋转
- 关键特性: 激活的角度阈值,旋转约束检查,锚点计算
组合交互
DragRotateAndZoom Interaction
- 主要类:
DragRotateAndZoomsrc/ol/interaction/DragRotateAndZoom.js27 - 用途: 在单个拖动手势中结合旋转和缩放操作
- 关键特性: 仅鼠标,Shift 键激活,同时计算角度和幅度
DragZoom Interaction
- 主要类:
DragZoomsrc/ol/interaction/DragZoom.js32 - 用途: 通过拖动选择矩形启用缩放框功能
- 关键特性: 扩展
DragBox,可配置为放大或缩小,动画过渡
导航交互架构
事件条件和激活控制
导航交互使用条件函数来确定何时应该响应用户输入。这些条件检查修饰键、输入设备类型和交互上下文。
主要条件函数
| 条件函数 | 用途 | 默认使用者 |
|---|---|---|
| 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;2
3
4
条件组合
可以使用逻辑运算符组合条件:
all(condition1, condition2, ...)- 所有条件都必须通过- 传递给构造函数的多个条件使用
all()自动组合
视图状态修改流程
导航交互通过结构化流程修改 View 状态,该流程尊重约束并支持平滑动画。
交互状态管理
开始/结束交互模式 大多数交互遵循三阶段生命周期:
- 开始:
view.beginInteraction()- 设置交互提示,可能取消现有动画 - 更新: 在交互期间使用
adjust*Internal()方法直接修改状态 - 结束:
view.endInteraction()- 应用最终约束,触发吸附动画
DragPan 示例 src/ol/interaction/DragPan.js93-98:
if (!this.panning_) {
this.panning_ = true;
map.getView().beginInteraction();
}2
3
4
PinchZoom 示例 src/ol/interaction/PinchZoom.js106-111:
const direction = this.lastScaleDelta_ > 1 ? 1 : -1;
view.endInteraction(this.duration_, direction);2
交互期间的约束绕过
在活动交互期间,许多约束被绕过以允许平滑操作:
- 分辨率约束允许中间缩放级别 src/ol/resolutionconstraint.js101-110
- 中心点约束允许临时过滚 src/ol/centerconstraint.js57-66
- 旋转约束被放宽以实现平滑旋转
配置和自定义
通用配置选项
所有导航交互都支持标准配置模式:
| 选项 | 用途 | 默认值 | 使用者 |
|---|---|---|---|
| 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
}2
3
4
5
6
7
DragPan 配置 src/ol/interaction/DragPan.js21-28:
{
condition: all(noModifierKeys, primaryAction), // Activation condition
kinetic: undefined, // Kinetic scrolling object
onFocusOnly: false // Focus requirement
}2
3
4
5
触摸交互配置:
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:
- DragPan - 主要导航方法
- MouseWheelZoom - 桌面缩放控制
- PinchZoom - 触摸缩放控制
- PinchRotate - 触摸旋转控制
- 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);
}2
3
4
5
6