簡體   English   中英

如何更改 react-google-maps 中 GroundOverlay 的不透明度?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM