React-Leaflet 在 mouseover/mouseout 上设置单个椭圆的 fillOpacity
React-Leaflet Set fillOpacity of single ellipse on mouseover/mouseout
我有一张用 React-Leaflet that displays Ellipses created with Leaflet.ellipse and React-Leaflet Core API 创建的地图。
我正在将鼠标事件处理程序传递给椭圆的 eventHandlers 道具。当我将鼠标悬停在椭圆上时,fillOpacity
从 0.0 更改为 0.5,然后在鼠标移开时从 0.5 更改为 0.0。
问题是当事件被触发时,每个椭圆的 fillOpacity
都会改变,而不仅仅是悬停在上面的椭圆。我怎样才能做到只有悬停在上面的特定椭圆才会改变其 fillOpacity
?
地图组件
const Map = () => {
const [map, setMap] = useState(null);
const [fillOpacity, setFillOpacity] = useState(0)
const onMouseEvent = (event, type) => {
switch (type) {
case 'over':
setFillOpacity(0.5)
break
case 'out':
setFillOpacity(0.0)
break
default:
break
}
}
return (
<>
<MapContainer
center={[38, -82]}
zoom={4}
zoomControl={false}
style={{ height: "100vh", width: "100%", padding: 0 }}
whenCreated={map => setMap(map)}
>
<LayersControl position="topright">
<LayersControl.BaseLayer checked name="Map">
<TileLayer
attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
url={maps.base}
/>
</LayersControl.BaseLayer>
<LayersControl.Overlay checked name="Ellipses">
<FeatureGroup>
<>{CITIES.map((city, index) => {
return (
<Ellipse
key={index}
center={city.center}
radii={city.radii}
tilt={city.tilt}
pathOptions={{
fillOpacity,
opacity: 1,
weight: 2,
}}
eventHandlers={{
mouseover: (event, type) => onMouseEvent(event, 'over'),
mouseout: (event, type) => onMouseEvent(event, 'out'),
}}
>
<Popup>
<Typography variant='subtitle1'>{city.city}</Typography>
</Popup>
</Ellipse>
)
})}</>
</FeatureGroup>
</LayersControl.Overlay>
</LayersControl>
</MapContainer>
</>
);
};
椭圆组件
import { createPathComponent } from '@react-leaflet/core'
import L from 'leaflet'
import 'leaflet-ellipse'
const Ellipse = createPathComponent(createEllipse, updateEllipse)
function createEllipse(props, context) {
const { center, radii, tilt, options } = props
const instance = new L.Ellipse(center, radii, tilt, options)
return {
instance,
context: { ...context, overlayContainer: instance },
}
}
function updateEllipse(instance, props, prevProps) {
if (
props.center !== prevProps.center ||
props.radii !== prevProps.radii ||
props.tilt !== prevProps.tilt ||
props.options !== prevProps.options
) {
instance.setStyle(props.options)
instance.setLatLng(props.center)
instance.setRadius(props.radii)
instance.setTilt(props.tilt)
}
}
export default Ellipse
问题是您对所有省略号使用了相同的状态变量。这里:
{CITIES.map((city, index) => {
return (
<Ellipse
key={index}
pathOptions={{
fillOpacity. // <---- problem here
}}
>
...
</Ellipse>
)
})}
所以 所有 省略号都从 fillOpacity
状态变量中获取它们的不透明度。当您将鼠标悬停在其中的 任何 上时,状态变量会发生变化,并且它们都会响应。您最好 而不是 将不透明度作为状态变量来处理。只需将其设置为常量 0,并在事件处理程序中深入研究鼠标悬停的 target
,然后调用 setStyle
:
const onMouseEvent = (event, type) => {
switch (type) {
case 'over':
event.target.setStyle({ fillOpacity: 0.5 })
break
case 'out':
event.target.setStyle({ fillOpacity: 0.0 })
break
default:
break
}
}
所以现在每个椭圆直接通过传单方法管理自己的不透明度,而不是通过应用过于广泛的反应状态变量来继承它们的不透明度。
Working demo
我有一张用 React-Leaflet that displays Ellipses created with Leaflet.ellipse and React-Leaflet Core API 创建的地图。
我正在将鼠标事件处理程序传递给椭圆的 eventHandlers 道具。当我将鼠标悬停在椭圆上时,fillOpacity
从 0.0 更改为 0.5,然后在鼠标移开时从 0.5 更改为 0.0。
问题是当事件被触发时,每个椭圆的 fillOpacity
都会改变,而不仅仅是悬停在上面的椭圆。我怎样才能做到只有悬停在上面的特定椭圆才会改变其 fillOpacity
?
地图组件
const Map = () => {
const [map, setMap] = useState(null);
const [fillOpacity, setFillOpacity] = useState(0)
const onMouseEvent = (event, type) => {
switch (type) {
case 'over':
setFillOpacity(0.5)
break
case 'out':
setFillOpacity(0.0)
break
default:
break
}
}
return (
<>
<MapContainer
center={[38, -82]}
zoom={4}
zoomControl={false}
style={{ height: "100vh", width: "100%", padding: 0 }}
whenCreated={map => setMap(map)}
>
<LayersControl position="topright">
<LayersControl.BaseLayer checked name="Map">
<TileLayer
attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
url={maps.base}
/>
</LayersControl.BaseLayer>
<LayersControl.Overlay checked name="Ellipses">
<FeatureGroup>
<>{CITIES.map((city, index) => {
return (
<Ellipse
key={index}
center={city.center}
radii={city.radii}
tilt={city.tilt}
pathOptions={{
fillOpacity,
opacity: 1,
weight: 2,
}}
eventHandlers={{
mouseover: (event, type) => onMouseEvent(event, 'over'),
mouseout: (event, type) => onMouseEvent(event, 'out'),
}}
>
<Popup>
<Typography variant='subtitle1'>{city.city}</Typography>
</Popup>
</Ellipse>
)
})}</>
</FeatureGroup>
</LayersControl.Overlay>
</LayersControl>
</MapContainer>
</>
);
};
椭圆组件
import { createPathComponent } from '@react-leaflet/core'
import L from 'leaflet'
import 'leaflet-ellipse'
const Ellipse = createPathComponent(createEllipse, updateEllipse)
function createEllipse(props, context) {
const { center, radii, tilt, options } = props
const instance = new L.Ellipse(center, radii, tilt, options)
return {
instance,
context: { ...context, overlayContainer: instance },
}
}
function updateEllipse(instance, props, prevProps) {
if (
props.center !== prevProps.center ||
props.radii !== prevProps.radii ||
props.tilt !== prevProps.tilt ||
props.options !== prevProps.options
) {
instance.setStyle(props.options)
instance.setLatLng(props.center)
instance.setRadius(props.radii)
instance.setTilt(props.tilt)
}
}
export default Ellipse
问题是您对所有省略号使用了相同的状态变量。这里:
{CITIES.map((city, index) => {
return (
<Ellipse
key={index}
pathOptions={{
fillOpacity. // <---- problem here
}}
>
...
</Ellipse>
)
})}
所以 所有 省略号都从 fillOpacity
状态变量中获取它们的不透明度。当您将鼠标悬停在其中的 任何 上时,状态变量会发生变化,并且它们都会响应。您最好 而不是 将不透明度作为状态变量来处理。只需将其设置为常量 0,并在事件处理程序中深入研究鼠标悬停的 target
,然后调用 setStyle
:
const onMouseEvent = (event, type) => {
switch (type) {
case 'over':
event.target.setStyle({ fillOpacity: 0.5 })
break
case 'out':
event.target.setStyle({ fillOpacity: 0.0 })
break
default:
break
}
}
所以现在每个椭圆直接通过传单方法管理自己的不透明度,而不是通过应用过于广泛的反应状态变量来继承它们的不透明度。