使用Font Awesome自定义React-Leaflet标记图标

14

这更像是一个理论问题,而不是一个实险问题。

如何将font awesome icons用作react-leaflet地图标记图标

我想要这样一个图标选择器控件,以便为我在地图上获得的每个标记图标分配(自定义)它们。顺便说一下,我正在使用Map和Marker的JSX组件。

是否有可能实现这一点?

有没有人有关于此的示例笔记?我已经进行了强烈的搜索,但找不到任何插件,只有一个仅与Leaflet 1.0配合使用的fontawesome插件。

所以,任何想法都是受欢迎的。

谢谢提前。

3个回答

21

由于某些原因,代码未能格式化。请查看Code Sandbox上的代码。

以下是如何使用font-awesome图标作为标记的方法。

  1. 将font-awesome CDN添加到您的index.html中。

<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.3.1/css/all.css" integrity="sha384-mzrmE5qonljUremFsqc01SB46JvROS7bZs3IO2EmfFsd15uHvIt+Y8vEf7N7fWAU" crossorigin="anonymous">

  1. 使用react-dom/server中的divIconrenderToStaticMarkup生成标记的图标。然后将此divIcon作为icon属性传递给Marker

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { renderToStaticMarkup } from 'react-dom/server';
import { divIcon } from 'leaflet';
import { Map, TileLayer, Marker, Popup } from 'react-leaflet';

import './styles.css';

class App extends Component {
  state = {
    lat: 51.505,
    lng: -0.091,
    zoom: 13,
  };

render() {
    const position = [this.state.lat, this.state.lng];
    const iconMarkup = renderToStaticMarkup(<i className=" fa fa-map-marker-alt fa-3x" />);
    const customMarkerIcon = divIcon({
      html: iconMarkup,
    });

    return (
      <Map center={position} zoom={this.state.zoom}>
        <TileLayer
          attribution="&amp;copy <a href=&quot;http://osm.org/copyright&quot;>OpenStreetMap</a> contributors"
          url="https://{s}.tile.osm.org/{z}/{x}/{y}.png"
        />
        <Marker position={position} icon={customMarkerIcon}>
          <Popup>
            A pretty CSS3 popup. <br /> Easily customizable.
          </Popup>
        </Marker>
      </Map>
    );
  }
}

const rootElement = document.getElementById('root');
ReactDOM.render(<App />, rootElement);
  • 通过将以下类添加到您的CSS文件中,覆盖divIcon的默认样式

    .leaflet-div-icon {
        background: transparent;
        border: none;
    }  
    

  • 谢谢Murli。你帮我省了好几个小时!非常棒的答案 :) - Uncle Bent
    还有一个小问题:为什么当Map被div标签包围时会消失?你有任何想法或解决方法吗? - Uncle Bent
    @H.SerhanEkinci,你需要为div提供高度和宽度。 - Murli Prajapati
    有其他的解决方案或建议吗? - Uncle Bent
    运行得非常好,我很感激。 - Uncle Bent
    显示剩余2条评论

    5
    对于那些已经使用Fontawesome(FontAwesomeIcon)的React组件的人来说,有一种解决方案不需要再通过CDN导入。它使用Murli答案的相同原则,但是您可以将FontAwesomeIcon组件转换为HTML并将其传递到divIcon的HTML属性中,而不是添加。它看起来像这样(适应所接受答案的示例):
    import React, { Component } from 'react';
    import ReactDOM from 'react-dom';
    import ReactDOMServer from 'react-dom/server';
    import Leaflet from 'leaflet'
    import { Map, TileLayer, Marker, Popup } from 'react-leaflet';
    import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
    
    import './styles.css';
    
    // FontAwesome requirements
    import { faUserAstronaut } from '@fortawesome/free-solid-svg-icons'
    library.add(faUserAstronaut)
    
    class App extends Component {
      state = {
        lat: 51.505,
        lng: -0.091,
        zoom: 13,
      };
    
      render() {
        const position = [this.state.lat, this.state.lng];
        const iconHTML = ReactDOMServer.renderToString(<FontAwesomeIcon icon='user-astronaut' />)
        const customMarkerIcon = new Leaflet.DivIcon({
          html: iconHTML,
        });
    
        return (
          <Map center={position} zoom={this.state.zoom}>
            <TileLayer
              attribution="&amp;copy <a href=&quot;http://osm.org/copyright&quot;>OpenStreetMap</a> contributors"
              url="https://{s}.tile.osm.org/{z}/{x}/{y}.png"
            />
            <Marker position={position} icon={customMarkerIcon}>
              <Popup>
                A pretty CSS3 popup. <br /> Easily customizable.
              </Popup>
            </Marker>
          </Map>
        );
      }
    }
    
    const rootElement = document.getElementById('root');
    ReactDOM.render(<App />, rootElement);
    

    2
    这对我有用,谢谢!请注意,默认情况下,图标后面会有一个白色方块和黑色边框,这可能不是您想要的。这里是如何删除它的方法。 - Nick K9

    -1
    创建 divIcon 并将其插入到 icon 属性中:

    // marker-icons.js
    import L from 'leaflet';
    
    const factory = new L.divIcon({
      className: '',
      iconAnchor: [12, 25],
      labelAnchor: [-6, 0],
      popupAnchor: [0, -15],
      iconSize: [25, 41],
      html: `<span class="fa fa-industry"></span>`
    });
    
    export default { factory };

    在组件文件中使用图标:

    // component.js
    import { factory } from './marker-icons';
    
    <MapContainer center={[12.23432, 87.234]} zoom={6} scrollWheelZoom={false}>
        <TileLayer attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors' url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"/>
        <Marker position={45.4534, 23.43]} icon={factory}>
            <Popup>Help text</Popup>
        </Marker>
    </MapContainer>


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