You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

react-leaflet Marker组件图标路径及createIcon函数错误解决

解决React-Leaflet Marker图标错误:文件不存在与createIcon is not a function

我来帮你搞定这两个问题,核心是对Leaflet Marker的icon属性要求理解有误,咱们一步步来解决:

错误原因解析

  1. 文件不存在错误:Leaflet默认会加载自带的Marker图标资源,要是项目没正确配置这些资源的路径,就会触发这个错误。你手动放了SVG文件,但没告诉Leaflet怎么正确使用它,所以问题没解决。
  2. TypeError: options.icon.createIcon is not a function:这是关键问题——Marker的icon属性必须接收一个Leaflet的L.Icon实例,而不是直接传入导入的SVG文件对象。直接传SVG文件的话,Leaflet无法识别它的结构,自然找不到createIcon方法。

解决方案

方法1:正确配置自定义SVG图标

你需要用L.icon()方法把SVG文件包装成Leaflet能识别的Icon实例:

  1. 创建自定义Icon实例
import icon from './marker.svg';

// 根据你的SVG实际尺寸调整参数
const customMarkerIcon = L.icon({
  iconUrl: icon, // 导入的SVG路径
  iconSize: [20, 20], // 图标的宽高
  iconAnchor: [10, 10], // 图标锚点(对应Marker的位置点)
  popupAnchor: [0, -10] // 弹窗相对于图标的偏移位置(按需设置)
});
  1. 在Marker组件中使用这个实例
    把原来的icon={icon}替换成icon={customMarkerIcon}
<Marker 
  key={text['id']} 
  position={text['coordinates']} 
  draggable={false} 
  opacity={0.01} 
  icon={customMarkerIcon} // 这里用包装后的Icon实例
>
  {/* Tooltip内容保持不变 */}
</Marker>

方法2:用透明DivIcon替代(更适合你的场景)

你设置了Marker的opacity=0.01,本质是要一个几乎不可见的Marker来承载Tooltip,完全可以不用SVG文件,直接创建透明的DivIcon:

  1. 创建透明Icon
const transparentIcon = L.divIcon({
  className: 'transparent-marker',
  iconSize: [0, 0] // 让图标尺寸为0,完全不占空间
});
  1. 配合CSS确保完全透明(可选)
    style.css中添加:
.transparent-marker {
  opacity: 0;
}
  1. 在Marker中使用这个Icon
    同样替换icon属性为transparentIcon即可,彻底避开图标文件路径的问题。

修改后的完整组件代码

这里给出方法1的完整代码示例:

import React, { Component } from 'react';
import { Marker, Tooltip, Polygon } from 'react-leaflet';
import L from 'leaflet';
import './style.css';
import icon from './marker.svg';

// 创建自定义Marker图标实例
const customMarkerIcon = L.icon({
  iconUrl: icon,
  iconSize: [20, 20],
  iconAnchor: [10, 10],
  popupAnchor: [0, -10]
});

/**
 * @class ./widgets/SeatMap/components/LeafletMap/components/CategoryControl/components/ShapeLayer
 */
class ShapeLayer extends Component {
  /**
   * @type {object}
   */
  shapes = {};

  /**
   * Constructor.
   *
   * @param {object} props
   */
  constructor (props) {
    super(props);
    this.shapes = props.shapes;
  }

  /**
   * @returns {JSX.Element}
   */
  render() {
    return (
      <div className={'ShapeLayer'}>
        { this.shapes['texts'].map(text => {
          return (
            <Marker 
              key={text['id']} 
              position={text['coordinates']} 
              draggable={false} 
              opacity={0.01} 
              icon={customMarkerIcon}
            >
              <Tooltip direction={"center"} permanent className={'shape-tooltip'}>
                <span>{text['text']}</span>
              </Tooltip>
            </Marker>
          );
        }) }
        { this.shapes['polygons'].map(polygon => {
          return (
            <Polygon 
              key={polygon['id']} 
              positions={polygon['coordinates']} 
              fillColor={"white"} 
              color={'gray'} 
            />
          );
        }) }
      </div>
    )
  }
}

export default ShapeLayer;

内容的提问来源于stack exchange,提问作者Stevan Tosic

火山引擎 最新活动