import React, { useEffect, useState } from 'react'
import 'leaflet/dist/leaflet.css'
import * as d3 from 'd3'
var L = null
const source = require('./data/states-us.geojson')
const AppCanvas = () => {
const [mapElement, setMap] = useState(null)
useEffect(() => {
L = require('leaflet')
// Map creation
if (!mapElement) {
const origin = [37.8, -96.9]
const initialZoom = 4
const map = L.map('map')
.setView(origin, initialZoom)
.addLayer(
new L.TileLayer(
'http://{s}.tile.stamen.com/toner-lite/{z}/{x}/{y}.png'
)
)
map.whenReady(() => {
// Create canvas element to the correct size
L.canvas().addTo(map)
const canvas = d3.select('#map').select('canvas')
const projection = d3.geoTransform({
point: function (x, y) {
const point = map.latLngToLayerPoint(new L.LatLng(y, x))
this.stream.point(point.x, point.y) // this : NO ARROW FUNCTION
},
})
const context = canvas.node().getContext('2d')
// Path generator
const path = d3
.geoPath()
.projection(projection)
.context(context)
d3.json(source).then((data) => {
context.beginPath()
path(data)
context.stroke()
})
setMap(map)
})
}
})
return (
<div>
<div
style={{
position: 'absolute',
top: 0,
bottom: 0,
left: 0,
right: 0,
zIndex: 0,
}}
id="map"
></div>
</div>
)
}
画布跟随地图,在每次平移/缩放结束后重新渲染。