[英]How to change the opacity of a GroundOverlay in react-google-maps?
使用帶有GroundOverlay
組件的react-google-maps
示例(參見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>
);
看起來像這樣:
但是,我很難看到如何使用滑塊“動態”更改不透明度。 最終,我相信我必須在google.maps.GroundOverlay
類的實例上調用setOpacity
方法(參見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
道具。 使用這個,我嘗試創建一個包含<GroundOverlay>
和一個<button>
(現在)的組件AdjustableGroundoverlay
來改變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了解到的,在AdjustableGroundoverlay
上調用setState()
應該會導致它再次調用它的render()
方法,從而將新的this.state.opacity
作為支持GroundOverlay
並更改其不透明度。 我不明白為什么這不起作用?
在react-google-maps
庫中, default
屬性(例如defaultOpacity
)在組件實例化后是不可變的,因此為了讓GroundOverlay
組件反映更改,需要使用opacity
來代替。
現在輪到更改,而不是訪問底層google.maps.GroundOverlay
對象,我建議通過state使用React 方式。 由於在您的示例中使用了recompose
庫,因此可以引入opacity
狀態,並且更改其值的處理程序可能如下所示:
withStateHandlers(
() => ({
opacity: 0.1
}),
{
incrementOpacity: ({ opacity }) => () => ({
opacity: opacity >= 1.0 ? 0.0 : opacity + 0.1
})
}
)
有關
withStateHandlers
詳細信息,請參閱官方文檔
這是一個“動態”反映不透明度變化的示例(出於演示目的,使用按鈕而不是滑塊):
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>
));
我withStateHandlers
像上面的答案那樣使用withStateHandlers
,而是將MapWithGroundOverlay
組件中的defaultOpacity
MapWithGroundOverlay
更改為opacity
:
/* 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)
)}
opacity={props.opacity}
/>
</GoogleMap>
);
現在,使用上面更新中發布的AjustableGroundoverlay
組件,單擊按鈕時不透明度會發生變化:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.