源码分析之Leaflet中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);
}
源码详解
核心配置项
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, // 自定义类名
}
核心方法实现
- 初始化方法
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元素,处理不同分辨率的资源,设置正确的位置和样式,确保图标在地图上正确显示。通过选项配置,用户可以灵活地定制图标的各种属性,如大小、锚点位置、弹出窗口的位置偏移等。