Jinuss's blog Jinuss's blog
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript高级程序设计》
    • 《Vue》
    • 《React》
    • 《Git》
    • JS设计模式总结
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • 学习
  • 实用技巧
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

东流

前端可视化
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript高级程序设计》
    • 《Vue》
    • 《React》
    • 《Git》
    • JS设计模式总结
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • 学习
  • 实用技巧
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 核心基类

  • Control控件篇

    • Control基类介绍
    • 默认Controls控件渲染过程
      • 概述
      • 源码分析
        • defaults方法
        • 默认控件的渲染
        • 赋值
        • 注册监听、初始化
      • 总结
    • Zoom缩放控件源码分析
    • Rotate旋转控件源码分析
    • ZoomToExtent控件源码分析
    • ZoomSlider滑块缩放控件源码分析
    • ScaleLine比例尺控件源码分析
    • Attribution属性控件源码分析
    • FullScreen全屏控件源码分析
    • OverviewMap鹰眼控件源码分析
    • MousePosition鼠标位置控件源码分析
  • Geom几何图形篇

  • Layer图层篇

  • Renderer篇

  • Feature篇

  • style样式篇

  • 《Openlayers源码》笔记
  • Control控件篇
东流
2024-12-09
目录

默认Controls控件渲染过程

# 概述

Openlayers 中默认的三类控件是Zoom、Rotate和Attribution

# 源码分析

# defaults方法

Openlayers 默认控件的集成封装在defaults方法中,该方法会返回一个Collection的实例,Collection是一个基于数组封装了一些方法,主要涉及到数组项的添加会注册触发一些事件。关于Collection类可以参考源码分析之 Openlayers 中的 Collection 类 (opens new window)

defaults方法实现如下:

export function defaults(options) {
  options = options ? options : {};

  const controls = new Collection();

  const zoomControl = options.zoom !== undefined ? options.zoom : true;
  if (zoomControl) {
    controls.push(new Zoom(options.zoomOptions));
  }

  const rotateControl = options.rotate !== undefined ? options.rotate : true;
  if (rotateControl) {
    controls.push(new Rotate(options.rotateOptions));
  }

  const attributionControl =
    options.attribution !== undefined ? options.attribution : true;
  if (attributionControl) {
    controls.push(new Attribution(options.attributionOptions));
  }

  return controls;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 默认控件的渲染

Openlayers 中的默认控件机制和默认键盘事件机制大同小异,关于 Openlayers 中的默认键盘事件可以参考源码分析之 Openlayers 中默认键盘事件触发机制 (opens new window)

# 赋值

在Map.js中方法中有如下代码:

class Map extends BaseObject {
  constructor(options) {
    const optionsInternal = createOptionsInternal(options);
    this.controls = optionsInternal.controls || defaultControls();
  }
}

function createOptionsInternal(options) {
  let controls;
  if (options.controls !== undefined) {
    if (Array.isArray(options.controls)) {
      controls = new Collection(options.controls.slice());
    } else {
      assert(
        typeof (/** @type {?} */ (options.controls).getArray) === "function",
        "Expected `controls` to be an array or an `ol/Collection.js`"
      );
      controls = options.controls;
    }
  }

  return {
    controls: controls,
  };
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

同Interactions一样,在createOptionsInternal方法中会判断参数options中是否配置了控件,若配置了控件,则判断其类型是否是一个数组,若是数组,则将其转为Collection实例,否则判断其是否存在getArray方法,默认情况下,createOptionsInternal方法的返回值中controls为undefined;因此在Map类中this.controls的值为defaultControls()方法的返回值,即包含Zoom、Rotate和Attribution控件的Collection实例。

# 注册监听、初始化

默认控件的注册、监听、移除 、添加方法都是在Map类中实现的,首先看下代码

class Map extends BaseObject {
  constructor(options) {
    this.controls.addEventListener(CollectionEventType.ADD, (event) => {
      event.element.setMap(this);
    });

    this.controls.addEventListener(CollectionEventType.REMOVE, (event) => {
      event.element.setMap(null);
    });
  }

  this.controls.forEach(
    (control) => {
      control.setMap(this);
    },
  );

  //获取this.controls
  getControls() {
    return this.controls;
  }

  //添加controls
  addControl(control) {
    this.getControls().push(control);
  }

  //移除controls
  removeControl(control) {
    return this.getControls().remove(control);
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
  • 监听和触发

在Map类的构造函数中注册了this.controls的添加和移除的监听事件。通过前面,我们知道this.controls是一个Collection类的实例,而Collection类是继承于BaseObject类,因此this.controls可以通过addEventListener注册监听事件;而调用Collection实例的remove方法会dispatchEvent(new CollectionEvent('remove'))派发remove类型的监听事件;调用Collection实例的push方法会dispatchEvent(new CollectionEvent('add'))派发add类型的监听事件。也就是说addControls方法会执行(event) => {event.element.setMap(this);};,removeControls方法会执行(event) => {event.element.setMap(null);}

  • 初始化渲染

在Map类的构造函数中会调用this.controls.forEach方法,该方法会遍历默认控件的实例,此时就会进行控件的实例化将控件元素添加到DOM中,然后调用执行控件的setMap,在中提过,因为 Openlayers 中控件都是基于Control类实现,而Control类中的setMap就是设置this.map_,如此控件的交互对象也就有了。

# 总结

本文介绍了 Openlayers 中默认控件的原理,可以加深对 Openlayers 中注册监听和派发事件核心机制的理解。

编辑 (opens new window)
上次更新: 2024/12/11, 10:30:03
Control基类介绍
Zoom缩放控件源码分析

← Control基类介绍 Zoom缩放控件源码分析→

最近更新
01
GeoJSON
05-08
02
Circle
04-15
03
CircleMarker
04-15
更多文章>
Theme by Vdoing | Copyright © 2024-2025 东流 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式