以react-google-maps
示例和GroundOverlay
组件为例(参见https://github.com/khpeek/beomaps/blob/master/src/App.js),我想制作一个可更改覆盖图不透明度的滑块。
例如,当前,如果渲染此组件,则会得到一个固定的0.5
不透明度的叠加层:
/* global google */
import React from "react"
import { compose } from "recompose"
import {
withScriptjs,
withGoogleMap,
GoogleMap,
GroundOverlay } from "react-google-maps"
export const MapWithGroundOverlay = compose(
withScriptjs,
withGoogleMap
)(props =>
<GoogleMap
defaultZoom={12}
defaultCenter={{lat: 40.740, lng: -74.18}}
>
<GroundOverlay
defaultUrl="https://www.lib.utexas.edu/maps/historical/newark_nj_1922.jpg"
defaultBounds={new google.maps.LatLngBounds(
new google.maps.LatLng(40.712216, -74.22655),
new google.maps.LatLng(40.773941, -74.12544)
)}
defaultOpacity={.5}
/>
</GoogleMap>
);
看起来像这样:
但是,我正在努力查看如何使用滑块“动态”更改不透明度。最终,我相信我将不得不在
setOpacity
类的实例上调用google.maps.GroundOverlay
方法(参见https://developers.google.com/maps/documentation/javascript/reference/image-overlay#GroundOverlay)。但是,如果我查看<GroundOverlay>
组件的源代码(参见https://github.com/tomchentw/react-google-maps/blob/ca5c5c6f5346fb3ee0037893fbca488a408c9938/lib/components/GroundOverlay.js#L59),var GroundOverlay = (exports.GroundOverlay = (function(_React$PureComponent) {
;(0, _inherits3.default)(GroundOverlay, _React$PureComponent)
/*
* @see https://developers.google.com/maps/documentation/javascript/3.exp/reference#GroundOverlay
*/
function GroundOverlay(props, context) {
;(0, _classCallCheck3.default)(this, GroundOverlay)
var _this = (0, _possibleConstructorReturn3.default)(
this,
(
GroundOverlay.__proto__ || (0, _getPrototypeOf2.default)(GroundOverlay)
).call(this, props, context)
)
;(0, _warning2.default)(
!props.url || !props.bounds,
"\nFor GroundOveray, url and bounds are passed in to constructor and are immutable\n after iinstantiated. This is the behavior of Google Maps JavaScript API v3 (\n See https://developers.google.com/maps/documentation/javascript/reference#GroundOverlay)\n Hence, use the corresponding two props provided by `react-google-maps`.\n They're prefixed with _default_ (defaultUrl, defaultBounds).\n\n In some cases, you'll need the GroundOverlay component to reflect the changes\n of url and bounds. You can leverage the React's key property to remount the\n component. Typically, just `key={url}` would serve your need.\n See https://github.com/tomchentw/react-google-maps/issues/655\n"
)
var groundOverlay = new google.maps.GroundOverlay(
props.defaultUrl || props.url,
props.defaultBounds || props.bounds
)
;(0, _MapChildHelper.construct)(
GroundOverlay.propTypes,
updaterMap,
_this.props,
groundOverlay
)
groundOverlay.setMap(_this.context[_constants.MAP])
_this.state = (0, _defineProperty3.default)(
{},
_constants.GROUND_LAYER,
groundOverlay
)
return _this
}
;(0, _createClass3.default)(GroundOverlay, [
{
key: "componentDidMount",
value: function componentDidMount() {
;(0, _MapChildHelper.componentDidMount)(
this,
this.state[_constants.GROUND_LAYER],
eventMap
)
},
},
{
key: "componentDidUpdate",
value: function componentDidUpdate(prevProps) {
;(0, _MapChildHelper.componentDidUpdate)(
this,
this.state[_constants.GROUND_LAYER],
eventMap,
updaterMap,
prevProps
)
},
},
{
key: "componentWillUnmount",
value: function componentWillUnmount() {
;(0, _MapChildHelper.componentWillUnmount)(this)
var GroundOverlay = this.state[_constants.GROUND_LAYER]
if (GroundOverlay) {
GroundOverlay.setMap(null)
}
},
},
{
key: "render",
value: function render() {
return false
},
/**
* Gets the `LatLngBounds` of this overlay.
* @type LatLngBoundsLatLngBounds
* @public
*/
},
{
key: "getBounds",
value: function getBounds() {
return this.state[_constants.GROUND_LAYER].getBounds()
},
/**
* Returns the opacity of this ground overlay.
* @type number
* @public
*/
},
{
key: "getOpacity",
value: function getOpacity() {
return this.state[_constants.GROUND_LAYER].getOpacity()
},
/**
* Gets the url of the projected image.
* @type string
* @public
*/
},
{
key: "getUrl",
value: function getUrl() {
return this.state[_constants.GROUND_LAYER].getUrl()
},
},
])
return GroundOverlay
})(
_react2.default.PureComponent
)) /*
那么似乎只有一个
getOpacity()
方法,却没有setOpacity()
一个。另外,groundOverlay
变量是function GroundOverlay(props, context)
的局部变量,因此我看不到如何访问其setOpacity
方法。关于如何解决这个问题的任何想法?
更新资料
我注意到
GroundOverlay
组件接受确定其不透明度的opacity
道具。使用此方法,我尝试创建同时包含AdjustableGroundoverlay
和<GroundOverlay>
的组件<button>
来更改GroundOverlay
的不透明度:import React from "react"
import { MapWithGroundOverlay } from "./MapWithGroundOverlay"
export class AdjustableGroundoverlay extends React.PureComponent {
constructor(props, context) {
super(props, context)
this.state = {opacity: 0.5}
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState(state => ({
opacity: 1.0
}));
}
render() {
return (
<div>
<MapWithGroundOverlay
googleMapURL={`https://maps.googleapis.com/maps/api/js?key=${process.env.REACT_APP_GOOGLE_MAPS_API_KEY}&v=3.exp&libraries=geometry,drawing,places`}
loadingElement={<div style={{ height: `100%` }} />}
containerElement={<div style={{ height: `600px` }} />}
mapElement={<div style={{ height: `100%` }} />}
opacity={this.state.opacity}
/>
<button onClick={this.handleClick}>
{`Opacity: ${this.state.opacity}`}
</button>
</div>
);
}
}
但是,我注意到,当我单击按钮时,尽管其标签从
Opacity: 0.5
更改为Opacity: 1
,但是叠加层的实际不透明度并没有改变:据我从https://reactjs.org/docs/handling-events.html理解,在
setState()
上调用AdjustableGroundoverlay
应该使它再次调用其render()
方法,从而将新的this.state.opacity
作为道具传递给GroundOverlay
并更改其不透明度。我不明白为什么这行不通? 最佳答案
在react-google-maps
库中,实例化组件后,default
属性(例如defaultOpacity
)是不变的,因此为了使GroundOverlay
组件反映更改,需要使用opacity
代替。
现在轮到更改了,而不是访问基础google.maps.GroundOverlay
object,我建议通过React way来使用state。因为在您的示例中使用了recompose
library,所以可以引入opacity
状态,并且可以更改其值的处理程序如下所示:
withStateHandlers(
() => ({
opacity: 0.1
}),
{
incrementOpacity: ({ opacity }) => () => ({
opacity: opacity >= 1.0 ? 0.0 : opacity + 0.1
})
}
)
有关
withStateHandlers
的详细信息,请参见official documentation这是一个以动态方式反映不透明度变化的示例(出于演示目的,使用按钮代替了滑块):
export const MapWithGroundOverlay = compose(
withScriptjs,
withGoogleMap,
withStateHandlers(
() => ({
opacity: 0.1
}),
{
incrementOpacity: ({ opacity }) => () => ({
opacity: opacity >= 1.0 ? 0.0 : opacity + 0.1
})
}
)
)(props => (
<div>
<button onClick={props.incrementOpacity}>Increment opacity</button>
<GoogleMap defaultZoom={12} defaultCenter={{ lat: 40.74, lng: -74.18 }}>
<GroundOverlay
defaultUrl="https://www.lib.utexas.edu/maps/historical/newark_nj_1922.jpg"
defaultBounds={
new google.maps.LatLngBounds(
new google.maps.LatLng(40.712216, -74.22655),
new google.maps.LatLng(40.773941, -74.12544)
)
}
defaultOpacity={props.opacity}
/>
</GoogleMap>
</div>
));
Here is a demo
关于javascript - 如何更改react-google-maps中GroundOverlay的不透明度?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55980161/