繁体   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