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)
  • 框架

  • core模块

  • dom模块

  • control

  • geometry

  • geo

  • layer

    • marker

      • Marker
      • Marker.Drag
      • Icon
        • 概述
        • 源码分析
          • 源码实现
          • 源码详解
          • 核心配置项
          • 核心方法实现
        • 总结
      • Icon.Default
      • DivIcon
    • tile

    • vector

    • Layer
    • LayerGroup
    • FeatureGroup
    • DivOverlay
    • Popup
    • Tooltip
    • ImageOverlay
    • SVGOverlay
    • VideoOverlay
    • GeoJSON
  • Map

  • 《Leaflet源码》笔记
  • layer
  • marker
东流
2025-04-11
目录

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

# 源码详解

# 核心配置项

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

# 核心方法实现

  1. 初始化方法

Icon类继承于Class基类,因此其初始化方法为initialize。在初始化方法中,会调用setOptions方法来设置options属性,合并配置项。

  1. 图标创建流程

Icon类提供了两个方法:createIcon和createShadow,用于创建图标和阴影。这两个方法都会调用_createIcon方法,该方法根据传入的name参数来确定创建的是图标还是阴影。

在_createIcon方法中,首先会根据参数name获取图片的路径,若图标的默认路径不存在则抛出异常。然后会调用_createImg创建图片的DOM元素设置src属性,再就是调用_setIconStyle方法设置图标的样式包括大小以及偏移值,偏移值主要是通过参数进行计算,最后根据参数crossOrigin设置图标的跨域属性。

  1. 动态URL选择
  • 自动检测Retina屏幕
  • 优先使用Retina专用高清图片
  1. 样式定位算法

样式定位算法,主要是通过CSS margin精确控制锚点的样式,因为图标的锚点默认在左上角,通过负的margin可以将图标的中心或者指定锚点位置对准地图上的坐标点,该方法也叫做负边距定位法。

# 总结

Icon类的主要职责是根据提供的选项创建和管理图标及其阴影的DOM元素,处理不同分辨率的资源,设置正确的位置和样式,确保图标在地图上正确显示。通过选项配置,用户可以灵活地定制图标的各种属性,如大小、锚点位置、弹出窗口的位置偏移等。

编辑 (opens new window)
上次更新: 2025/04/23, 09:39:50
Marker.Drag
Icon.Default

← Marker.Drag Icon.Default→

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