最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Having trouble getting a custom zoom button in React-Leaflet - Stack Overflow

programmeradmin0浏览0评论

I'm trying to build my own Zoom button with react-leaflet

I have the following code:

import React from 'react';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import { Map, TileLayer } from 'react-leaflet';
import Control from 'react-leaflet-control';
import FloatingActionButton from 'material-ui/FloatingActionButton';
import ZoomIn from 'material-ui/svg-icons/action/zoom-in';
import ZoomOut from 'material-ui/svg-icons/action/zoom-out';


class LeafletMap extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            animate: true,
            center: [
                -34.989610443115,
                -71.232476234436
            ],
            zoom: 13,
            zoomControl: false
        };
    }

    render() {
        return (
            <div>
                <Map
                    animate={this.state.animate} 
                    center={this.state.center} 
                    zoom={this.state.zoom} 
                    zoomControl={this.state.zoomControl}
                    >
                    <TileLayer
                        url={'http://{s}.tile.osm/{z}/{x}/{y}.png'}
                        attribution={'&copy; <a href=";>OpenStreetMap</a>'}
                    />
                    <Control position="topleft">
                        <MuiThemeProvider>
                            <div>
                                <div>&nbsp;</div>
                                <FloatingActionButton mini={true}>
                                    <ZoomIn onClick={ () => alert('Zoom In') } />
                                </FloatingActionButton>
                                <div>&nbsp;</div>
                                <FloatingActionButton mini={true}>
                                    <ZoomOut onClick={ () => alert('Zoom Out') }/>
                                </FloatingActionButton>
                            </div>
                        </MuiThemeProvider>
                    </Control>
                </Map>
            </div>
        );
    }
}
export default LeafletMap;

All this is displaying good way, but now I want to to put a funcion where I can able to do zoom in or out. I don't have an idea how to call leaflet's methods using react-leaflet library.
I've tried many ways to implement it but without success.

Do you have any idea how to implement it?

I'm trying to build my own Zoom button with react-leaflet

I have the following code:

import React from 'react';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import { Map, TileLayer } from 'react-leaflet';
import Control from 'react-leaflet-control';
import FloatingActionButton from 'material-ui/FloatingActionButton';
import ZoomIn from 'material-ui/svg-icons/action/zoom-in';
import ZoomOut from 'material-ui/svg-icons/action/zoom-out';


class LeafletMap extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            animate: true,
            center: [
                -34.989610443115,
                -71.232476234436
            ],
            zoom: 13,
            zoomControl: false
        };
    }

    render() {
        return (
            <div>
                <Map
                    animate={this.state.animate} 
                    center={this.state.center} 
                    zoom={this.state.zoom} 
                    zoomControl={this.state.zoomControl}
                    >
                    <TileLayer
                        url={'http://{s}.tile.osm/{z}/{x}/{y}.png'}
                        attribution={'&copy; <a href="http://osm/copyright">OpenStreetMap</a>'}
                    />
                    <Control position="topleft">
                        <MuiThemeProvider>
                            <div>
                                <div>&nbsp;</div>
                                <FloatingActionButton mini={true}>
                                    <ZoomIn onClick={ () => alert('Zoom In') } />
                                </FloatingActionButton>
                                <div>&nbsp;</div>
                                <FloatingActionButton mini={true}>
                                    <ZoomOut onClick={ () => alert('Zoom Out') }/>
                                </FloatingActionButton>
                            </div>
                        </MuiThemeProvider>
                    </Control>
                </Map>
            </div>
        );
    }
}
export default LeafletMap;

All this is displaying good way, but now I want to to put a funcion where I can able to do zoom in or out. I don't have an idea how to call leaflet's methods using react-leaflet library.
I've tried many ways to implement it but without success.

Do you have any idea how to implement it?

Share Improve this question edited Jan 13, 2021 at 13:08 Enlico 28.6k8 gold badges67 silver badges152 bronze badges asked Jul 24, 2016 at 0:15 Javier MuñozJavier Muñoz 7901 gold badge13 silver badges31 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 5

There are a few ways to handle map functions/actions.

  1. Pass via props

Many options are available via the Map's props(bounds, center, zoom). This way allows you to hold the zoom in your one state/store, instead of in leaflet.

const React = window.React;
const {
  Map, 
  TileLayer, 
  Marker, 
  Popup
} = window.ReactLeaflet;

class ZoomInState extends React.Component {
  constructor() {
    super();
    this.state = {
      lat: 51.505,
      lng: -0.09,
      zoom: 13,
    };
    this.zoomIn = () => this.setState({zoom: this.state.zoom+1})
    this.zoomOut = () => this.setState({zoom: this.state.zoom-1})
  }

  render() {
    const position = [this.state.lat, this.state.lng];
    return ( < Map center = {
        position
      }
      zoom = {
        this.state.zoom
      }

      >
      < TileLayer attribution = '&copy; <a href="http://osm/copyright">OpenStreetMap</a> contributors'
      url = 'http://{s}.tile.osm/{z}/{x}/{y}.png' / >
      < Marker position = {
        position
      } >
        < Popup >
          < span >
            <button onClick={this.zoomOut}>
              Zoom out
            </button >
            < button onClick = {this.zoomIn} >
              Zoom in
            < /button>
          < /span>
        </Popup >
      < /Marker>
      </Map >
    );
  }
}
export default ZoomInState
  1. Get map via refs

This way will not hold the zoom level in your ponent. Often this is a good practice, because it keeps a single source of truth. You can always get the zoom with map.getZoom()

const React = window.React;
const { Map, TileLayer, Marker, Popup } = window.ReactLeaflet;

class MapByRef extends React.Component {
  constructor() {
    super();
    this.state = {
      lat: 51.505,
      lng: -0.09,
      zoom: 13,
    };
  }

  bindMap(el) {
    this.map = el.leafletElement;
  }

  zoomIn() {
    this.map.zoomIn();
  }

  zoomOut() {
    this.map.zoomOut();
  }

  render() {
    const position = [this.state.lat, this.state.lng];
    return (
      <Map center={position} zoom={this.state.zoom} ref={::this.bindMap}>
        <TileLayer
          attribution='&copy; <a href="http://osm/copyright">OpenStreetMap</a> contributors'
          url='http://{s}.tile.osm/{z}/{x}/{y}.png'
        />
        <Marker position={position}>
          <Popup>
            <span>
              <button onClick={::this.zoomIn} >Zoom In</button>
              <button onClick={::this.zoomIn} >Zoom Out</button>
            </span>
          </Popup>
        </Marker>
      </Map>
    );
  }
}
export default MapByRef

3. Get from Context

This way is nice if you want to make many child ponents that need to interact with the map. It also keeps leaflet as the single source of truth.

const React = window.React;
const { Map, TileLayer, Marker, Popup } = window.ReactLeaflet;

class CustomMarker {

  zoomIn(){
    this.context.map.zoomIn()
  }
  zoomOut(){
    this.context.map.zoomOut()
  }

  render() {
    return (
      <Marker position={position}>
        <Popup>
          <button onCLick={::this.zoomIn}>Zoom In</button>
          <button onCLick={::this.zoomOut}>Zoom In</button>
        </Popup>
      </Marker>
    )
  }
}
export CustomMarker


class MapWithCustomChildren extends React.Component {
  constructor() {
    super();
    this.state = {
      lat: 51.505,
      lng: -0.09,
      zoom: 13,
    };
  }

  render() {
    const position = [this.state.lat, this.state.lng];
    return (
      <Map center={position} zoom={this.state.zoom}>
        <TileLayer
          attribution='&copy; <a href="http://osm/copyright">OpenStreetMap</a> contributors'
          url='http://{s}.tile.osm/{z}/{x}/{y}.png'
        />
        <CustomMarker />
      </Map>
    );
  }
}
export default MapWithCustomChildren
发布评论

评论列表(0)

  1. 暂无评论