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