使用react-leaflet创建自定义标记图标时无法显示

3
我试图在使用react-leafletmarkers时,使用一个自定义图标
按照这里找到的指示:https://leafletjs.com/examples/custom-icons/和这里:https://roblahoda.com/blog/leaflet-react-custom-icons/ 我添加了以下代码行:
import Leaflet from 'leaflet'
import "leaflet/dist/leaflet.css"

import React from 'react'
import {
  TileLayer,
  LayersControl,
  LayerGroup,
  useMap,
  useMapEvents,
  GeoJSON,
  Marker,
  Popup,
} from 'react-leaflet'

export const newicon = new Leaflet.Icon({
  iconUrl: ("../../..assets/marker.svg"),
  iconAnchor: [5, 55],
  popupAnchor: [10, -44],
  iconSize: [25, 55],
})

对于Marker,我指定了newicon

    <Marker position={getMarkerPosition(state_name)} icon={newicon}>

(base) raphy@pc:~/Raphy-Template/src/assets$ ls -lah
    total 56K
    -rw-rw-r--  1 raphy raphy 5.0K Jan 31 11:40 marker.png

但是新图标的渲染效果不太好:

enter image description here

更新1)
使用require
export const newicon = new Leaflet.Icon({
  iconUrl: require("../../../assets/marker.svg"),
  iconAnchor: [5, 55],
  popupAnchor: [10, -44],
  iconSize: [25, 55],
})

我遇到了这个错误: 模块未找到:错误:无法解析“../../../assets/marker.svg” 使用import而不是require,我没有收到任何错误消息,但图标仍然没有显示出来:
export const newicon = new Leaflet.Icon({
  // @ts-ignore
  iconUrl: import("../../../assets/svg/push_pin_black_36dp.svg"),

  iconAnchor: [5, 55],
  popupAnchor: [10, -44],
  iconSize: [25, 55],
})


(base) raphy@pc:~/Raphy-Template/dist/assets/svg$ ls -lah
    -rw-rw-r-- 1 raphy raphy  390 Jan 31 19:05 
push_pin_black_36dp.svg
    (base) raphy@pc:~/Raphy-Template/dist/assets/svg$ 

其他信息:

我已经将代码放在这个CodeSandbox仓库中:https://codesandbox.io/s/damp-tdd-i917u?file=/src/App.js

"react": "^17.0.2"
"react-leaflet": "^3.2.5"
node: v16.13.0
O.S.: Ubuntu 20.04 Desktop

如何使“自定义图标”显示?
1个回答

2
请记住,您的React应用程序项目是在文件系统中构建并移动到另一个位置。特别地,像您的图标图片/SVG这样的资源可能没有捆绑,或者相对于您的脚本放置在不同的位置。
在您提到的关于带有自定义图标的React Leaflet的博客中,请注意指定图像资源路径的方式:它使用 `require("some/path")`,Webpack将其理解为指令来捆绑指定的资源并提供生成的构建路径。
所以在您的情况下,您只需要这样做:
export const newicon = new Leaflet.Icon({
  iconUrl: require("../../../assets/marker.svg") // require the path to the asset
})

话虽如此,看起来某些构建引擎配置将require('path/to/some/svg')转换为类似于React组件的对象(很可能是为了能够像使用React组件一样使用SVG,请参见https://create-react-app.dev/docs/adding-images-fonts-and-files/#adding-svgs),并在该对象的Url属性中提供构建后的URL。
export const newicon = new Leaflet.Icon({
  iconUrl: require("../../../assets/marker.svg").Url // require the path to the asset
})

另一个选项是在文件开头使用更标准的import。在这种情况下,与您在CodeSandbox中提供的相同的构建引擎配置一起使用,它会按预期提供结果URL(实际上是内联的Base64数据):

import iconUrl from "./svg/push_pin_black_36dp.svg";

export const newicon = new Leaflet.Icon({
  iconUrl
});

演示: https://codesandbox.io/s/quiet-shape-6ise9?file=/src/App.js

这是一个演示链接,展示了一个名为“App.js”的文件。

嗨@ghybs!感谢您的帮助!!使用require时,我遇到了这个错误Module not found: Error: Can't resolve '../../../assets/marker.svg'。我已经更新了我的帖子。我需要修改/添加一些内容才能使用require吗?require是唯一使其工作的方法吗?我问你这个问题,因为在Electron应用程序的renderer进程中,我无法使用它。 - Raphael10
最有可能的解释是您在React项目源代码的文件结构中路径不正确,但如果没有任何详细信息,我只能进行盲猜。您也可以使用import,但这在这里不应该改变任何内容。 - ghybs
使用 import 而不是 require,我没有收到任何错误信息,但图标仍然没有显示。 - Raphael10
正如上述所说,如果没有你项目文件结构的更多细节,我无法提供任何有用的帮助。最好分享一个实时重现的例子,例如使用CodeSandbox或StackBlitz。 - ghybs
我已将代码放在这个 CodeSandbox 存储库中:https://codesandbox.io/s/damp-tdd-i917u?file=/src/App.js - Raphael10

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接