Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Customizing react-leaflet marker icons by using font awesome

It is more theoretical question, rather than a problem.

How to use font awesome icons as react-leaflet map marker icons?

I would like to have such an icon selector control to assign(customize) each marker icon I have got on my map. By the way I am using JSX components of Map and Marker.

Is it possible to achieve this?

Anybody have a sample pen about this? I have really googled it strongly but couldn't find any plugin but a fontawesome plugin that is working only with Leaflet 1.0.

So any idea appreciated.

Thanks in advance.

like image 970
Uncle Bent Avatar asked Aug 29 '18 16:08

Uncle Bent


People also ask

How do I use font awesome icons in leaflet?

You can use font-awesome icons instead of built-in marker icons like this: const fontAwesomeIcon = L. divIcon({ html: '<i class="fa fa-map-marker fa-4x"></i>', iconSize: [20, 20], className: 'myDivIcon' }); L.

How do I change the leaflet marker icon in react?

If you have the leaflet and react-leaflet npm modules installed, this should work for you. Click on the marker and you will see the popup with a "Change Marker Color" button. That should do the trick.

Is react leaflet free?

Leaflet and its React counterpart, React Leaflet, are a fantastic open source and free mapping alternative to Google Maps and MapBox, no API key required!


2 Answers

For some reasons code is not getting formatted. See code on code sandbox

Here is how you can use font-awesome icons as markers.

  1. Add font-awesome CDN to your index.html

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

  1. Use divIcon along with renderToStaticMarkup from react-dom/server to generate icon for marker. And pass this divIcon to Marker as a icon prop.

    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);
    
  2. Override divIcon default style by adding the following class to your css file

    .leaflet-div-icon {
        background: transparent;
        border: none;
    }  
    
    • Here is a working example of the same:
      https://codesandbox.io/s/4ry180jl34
like image 149
Murli Prajapati Avatar answered Oct 12 '22 21:10

Murli Prajapati


For those who already use the React components of Fontawesome (FontAwesomeIcon), there is a solution that does not require importing via CDN again. It uses the same principles of Murli's answers, but instead of adding <i className=" fa fa-map-marker-alt fa-3x" />, you can convert the FontAwesomeIcon component to html and pass that into the html attribute of the divIcon. It would look like this (adapted the example of the accepted answer):

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);
like image 5
Sam Avatar answered Oct 12 '22 22:10

Sam