Closed jonra1993 closed 3 years ago
Something like this
function MyMap(props) {
const mapRef = useRef(null);
const map = useRef(null);
// if dom element exist and map not created
if (myRef.current && !map.current) {
// create map
map.current = L.map(myRef.current ).setView([51.505, -0.09], 13)
L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}', {
attribution: 'Map data © <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
maxZoom: 18,
id: 'mapbox/streets-v11',
tileSize: 512,
zoomOffset: -1,
}).addTo(map.current)
// connect plugin
L.simpleMapScreenshoter().addTo(map.current)
}
return (
<div>
<div ref={mapRef} style={ height: '180px' }/>
</div>
);
}
Thanks, @grinat I have also created another version using material UI and react-leaflet maybe it can help other people
import React, { useState, useRef, useEffect } from 'react';
import {
makeStyles,
Dialog,
Button,
DialogTitle,
DialogContent,
DialogActions,
} from '@material-ui/core';
import PropTypes from 'prop-types';
import {
MapContainer,
TileLayer,
Marker,
Popup,
useMapEvents,
useMap
} from 'react-leaflet'
import 'leaflet/dist/leaflet.css'
import * as L from 'leaflet'
import { Control } from 'leaflet'
import { SimpleMapScreenshoter } from 'leaflet-simple-map-screenshoter'
import { createControlComponent, useLeafletContext } from '@react-leaflet/core'
import fileSaver from 'file-saver'
const useStyles = makeStyles((theme) => ({
root: {
marginLeft: 0,
marginRight: 0,
height: '100%',
width: '100%'
},
textField: {
width: '100%',
marginTop: theme.spacing(1),
marginBottom: theme.spacing(1),
fontFamily: 'AIGFutura-Medium',
font: '15px AIGFutura-Medium'
},
}));
export const VenueLocationIcon = L.icon({
iconUrl: require("src/assets/icons/venue_location_icon.svg"),
iconRetinaUrl: require("src/assets/icons/venue_location_icon.svg"),
iconAnchor: null,
shadowUrl: null,
shadowSize: null,
shadowAnchor: null,
iconSize: [40, 40],
className: "leaflet-venue-icon",
});
const Circle = (props) => {
const context = useLeafletContext()
useEffect(() => {
const container = context.layerContainer || context.map;
const circle = new L.circle(props.center, { radius: props.radius })
container.addLayer(circle);
return () => {
container.removeLayer(circle)
}
})
return null
}
const SimpleMap = ({refInput}) => {
const mapSimple = useMap()
const simpleMapScreenshoter = L.simpleMapScreenshoter({ hidden: true}).addTo(mapSimple);
const { current } = refInput;
const takeScreenshot = async () => {
simpleMapScreenshoter.takeScreen('blob')
.then(image => {
//console.log('image', image);
fileSaver.saveAs(image, 'map.png')
//saveAs(blob, 'screen.png')
})
.catch(e => {
console.log(e.toString())
})
}
useEffect(() => {
current.addEventListener('click', takeScreenshot)
return () => {
current.removeEventListener('click', ()=>{})
}
}, [refInput])
return (
null
)
}
const GeoMap = ({ open, handleClose, guessPosition }) => {
const classes = useStyles();
const buttonRef = useRef(null)
const LocationMarker = () => {
const map = useMapEvents({
click: () => {
guessPosition !== null && map.flyTo(guessPosition, map.getZoom())
}
})
return guessPosition === null ? null : (
<Marker position={guessPosition} icon={VenueLocationIcon}>
<Popup>Ubicación del invitado</Popup>
</Marker>
)
}
return (
<Dialog
fullWidth={true}
maxWidth={'lg'}
open={open}
onClose={handleClose}
aria-labelledby="max-width-dialog-title"
scroll={'paper'}
>
<DialogTitle id="max-width-dialog-title">Mapa</DialogTitle>
<DialogContent className={classes.root} >
<MapContainer
id='myMap'
style={{
height: '37vw',
}}
center={guessPosition}
zoom={20}
scrollWheelZoom={true}
>
<TileLayer
attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<LocationMarker />
<Circle center={guessPosition} radius={30} />
<SimpleMap refInput={buttonRef} />
</MapContainer>
</DialogContent>
<DialogActions>
<Button ref={buttonRef} >
Snapshot
</Button>
<Button onClick={handleClose} >
Close
</Button>
</DialogActions>
</Dialog >
)
}
GeoMap.propTypes = {
open: PropTypes.bool,
guessPosition: PropTypes.array.isRequired,
handleClose: PropTypes.func,
}
GeoMap.defaultProps = {
open: false,
guessPosition: [-0.29067, -78.5454],
handleClose: () => { },
};
export default GeoMap
Hi, thanks for creating this library and make it public. I want to know if you can suggest any way to implement this library using React functional with hooks.