 Icon
Icon
  # 概述
在Leaflet中,Icon类用于创建图标对象,可以用于标记点的图标。Icon类继承自Class类,提供了一些方法用于创建图标对象。
# 源码分析
# 源码实现
Icon类源码实现如下:
export var Icon = Class.extend({
  options: {
    popupAnchor: [0, 0],// 弹出框的锚点
    tooltipAnchor: [0, 0],// 弹出框和提示框的锚点
    crossOrigin: false, // 跨域处理
  },
  initialize: function (options) {
    setOptions(this, options);
  },
  createIcon: function (oldIcon) {
    return this._createIcon("icon", oldIcon);
  },
  createShadow: function (oldIcon) {
    return this._createIcon("shadow", oldIcon);
  },
  _createIcon: function (name, oldIcon) {
    var src = this._getIconUrl(name);
    if (!src) {
      if (name == "icon") {
        throw new Error("iconUrl not set in Icon options (see the docs.)");
      }
      return null;
    }
    var img = this._createImg(
      src,
      oldIcon && oldIcon.tagName === "IMG" ? oldIcon : null
    );
    this._setIconStyles(img, name);
    if (this.options.crossOrigin || this.options.crossOrigin === "") {
      img.crossOrigin =
        this.options.crossOrigin === true ? "" : this.options.crossOrigin;
    }
    return img;
  },
  _setIconStyles: function (img, name) {
    var options = this.options;
    var sizeOption = options[name + "Size"];
    if (typeof sizeOption === "number") {
      sizeOption = [sizeOption, sizeOption];
    }
    var size = point(sizeOption),
      anchor = point(
        (name === "shadow" && options.shadowAnchor) ||
          options.iconAnchor ||
          (size && size.divideBy(2, true))
      );
    img.className = "leaflet-marker-" + name + " " + (options.className || "");
    if (anchor) {
      img.style.marginLeft = -anchor.x + "px";
      img.style.marginTop = -anchor.y + "px";
    }
    if (size) {
      img.style.width = size.x + "px";
      img.style.height = size.y + "px";
    }
  },
  _createImg: function (src, el) {
    el = el || document.createElement("img");
    el.src = src;
    return el;
  },
  _getIconUrl: function (name) {
    return (
      (Browser.retina && this.options[name + "RetinaUrl"]) ||
      this.options[name + "Url"]
    );
  },
});
export function icon(options) {
  return new Icon(options);
}
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# 源码详解
# 核心配置项
Icon类的配置项实际上比上述还要多,如下所示:
options= {
  iconUrl: null,        // 必须的图标路径
  iconRetinaUrl: null,  // Retina屏专用路径
  iconSize: null,       // 图标尺寸(像素)
  iconAnchor: null,     // 图标锚点位置
  popupAnchor: [0,0],   // 弹出框锚点偏移
  shadowUrl: null,      // 阴影图片路径
  crossOrigin: false    // 跨域处理
  shadowRetinaUrl: null,// Retina屏专用路径
  shadowSize: null,     // 阴影尺寸
  shadowAnchor: null,   // 阴影锚点位置
  className: null,      // 自定义类名
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 核心方法实现
- 初始化方法
Icon类继承于Class基类,因此其初始化方法为initialize。在初始化方法中,会调用setOptions方法来设置options属性,合并配置项。
- 图标创建流程
Icon类提供了两个方法:createIcon和createShadow,用于创建图标和阴影。这两个方法都会调用_createIcon方法,该方法根据传入的name参数来确定创建的是图标还是阴影。
在_createIcon方法中,首先会根据参数name获取图片的路径,若图标的默认路径不存在则抛出异常。然后会调用_createImg创建图片的DOM元素设置src属性,再就是调用_setIconStyle方法设置图标的样式包括大小以及偏移值,偏移值主要是通过参数进行计算,最后根据参数crossOrigin设置图标的跨域属性。
- 动态URL选择
- 自动检测Retina屏幕
- 优先使用Retina专用高清图片
- 样式定位算法
样式定位算法,主要是通过CSS margin精确控制锚点的样式,因为图标的锚点默认在左上角,通过负的margin可以将图标的中心或者指定锚点位置对准地图上的坐标点,该方法也叫做负边距定位法。
# 总结
Icon类的主要职责是根据提供的选项创建和管理图标及其阴影的DOM元素,处理不同分辨率的资源,设置正确的位置和样式,确保图标在地图上正确显示。通过选项配置,用户可以灵活地定制图标的各种属性,如大小、锚点位置、弹出窗口的位置偏移等。
编辑  (opens new window)
  上次更新: 2025/04/23, 09:39:50
