React.js-Google Maps-样式信息窗口

韦克索尼

我正在尝试更改InfoWindow中的样式

这是我使用的代码:

<InfoWindow options={{maxWidth: 900}} position={self.state.position} ref="infoWindow" onCloseclick={self.onLineWindowClose}>
    <div className="berlin" style={{height: '120px',width: '260px', fontFamily: 'Roboto'}}>
        <div style={{height: '20px'}}>
            <div style={{float: 'left', padding: '3px 0 0 6px'}}>From: </div>
            <div style={{float: 'left', padding: "3px", color: '#3497d9'}}>{self.state.startLocation.City}</div>
        </div>
        <div style={{height: '20px', clear: 'both'}}>
            <div style={{float: 'left', padding: '3px 0 0 6px'}}>To: </div>
            <div style={{float: 'left', padding: "3px", color: '#3497d9'}}>{self.state.endLocation.City}</div>
        </div>
        <LineList relationInfo={this.state.relationDetails} />
    </div>
</InfoWindow>

问题很简单。如何更改外观?我尝试设置className。我也尝试将选项传递给它。但是似乎没有任何作用。

哈代

我建议为Google地图创建自己的组件,并使用“纯文本” javascript创建自定义信息窗口。这样,您可以直接使用所有Google Maps的“本机”属性等,而无需使用任何超级复杂且有限的组件库:)

用于响应的google maps包装器示例(仅是简单示例):

import React, { Component, PropTypes } from 'react';

class GoogleMap extends Component {

  componentDidMount() {
    this.map = new google.maps.Map(this.refs.map, {
      scrollwheel: true,
      zoom: 13,
      draggable: true,
      mapTypeControl: false,
      streetViewControl: false,
      zoomControlOptions: {
        position: google.maps.ControlPosition.TOP_LEFT,
        style: google.maps.ZoomControlStyle.LARGE,
      },
      center: new google.maps.LatLng(60.16985569999999, 24.938379),
    });

    this.props.onGetMap(this.map);
  }

  render() {
    const mapStyle = {
      height: '100%',
      width: '100%',
    };

    return (
      <div ref="map" style={mapStyle}></div>
    );
  }
}

GoogleMap.propTypes = {
  onGetMap: PropTypes.func.isRequired,
};

export default GoogleMap;

然后,您可以像这样使用它:

import React, { Component, PropTypes } from 'react';
import GoogleMap from 'components/GoogleMap';

class Some extends Component {

  constructor(props, context) {
    super(props, context);
    this.onMapReady = this.onMapReady.bind(this);
    this.state = {
      map: null,
      markers: [],
    };
  }

  onMapReady(map) {
    this.setState({
      map,
    });
    // Here add some markers etc..
  }

  render() {
    return (
      <div className="some">
        <GoogleMap onGetMap={this.onMapReady} />
      </div>
    );
  }
}

export default Some;

信息窗口示例:

class BubbleOverlay extends google.maps.OverlayView {

  constructor(options) {
    // Initialize all properties.
    super(options);
    this.options = {};

    this.options.map = options.map;
    this.options.location = options.location;
    this.options.borderColor = options.borderColor || '#666666';
    this.options.borderWidth = options.borderWidth || 1;
    this.options.backgroundColor = options.backgroundColor || '#fff';
    this.options.arrowSize = options.arrowSize || 15;
    this.options.contentHeight = options.contentHeight || 200;
    this.options.contentWidth = options.contentWidth || 200;
    this.options.zIndex = options.zIndex || 1000;
    this.options.onClose = options.onClose;
    // Explicitly call setMap on this overlay.
    this.setMap(options.map);
  }

  /**
   * Convert number to pixels
   * @param  {number} num Number to convert
   * @return {string}     Number in pixels
   */
  px(num) {
    if (num) {
      // 0 doesn't need to be wrapped
      return `${num}px`;
    }
    return num;
  }

/**
 * onAdd is called when the map's panes are ready and the overlay has been
 * added to the map.
 */
  onAdd() {
    if (!this.bubble) {
      this.createDOMElements();
    }

    // Add the element to the "overlayLayer" pane.
    const panes = this.getPanes();
    if (panes) {
      panes.overlayMouseTarget.appendChild(this.bubble);
    }
  }

  createContent() {
    const content = document.createElement('div');
    content.style.borderStyle = 'solid';
    content.style.borderWidth = '1px';
    content.style.borderColor = this.options.borderColor;
    content.style.backgroundColor = this.options.backgroundColor;
    content.style.zIndex = this.options.zIndex;
    content.style.width = this.px(this.options.contentWidth);
    content.style.height = this.px(this.options.contentHeight);
    content.style.position = 'relative';
    content.className = 'bubble-overlay-content';

    return content;
  }

  createCloseBtn() {
    const btn = document.createElement('div');
    btn.className = 'bubble-overlay-btn-close';

    const iconClose = document.createElement('span');
    iconClose.className = 'glyphicon glyphicon-remove';
    btn.appendChild(iconClose);

    return btn;
  }

  createArrow() {
    const arrowSize = this.options.arrowSize;
    const borderWidth = this.options.borderWidth;
    const borderColor = this.options.borderColor;
    const backgroundColor = this.options.backgroundColor;


    const arrowOuterSizePx = this.px(arrowSize);
    const arrowInnerSizePx = this.px(Math.max(0, arrowSize - borderWidth));

    const arrow = document.createElement('div');
    arrow.style.position = 'relative';
    arrow.style.marginTop = this.px(-borderWidth);

    const arrowInner = document.createElement('div');
    const arrowOuter = document.createElement('div');

    arrowOuter.style.position = arrowInner.style.position = 'absolute';
    arrowOuter.style.left = arrowInner.style.left = '50%';
    arrowOuter.style.height = arrowInner.style.height = '0';
    arrowOuter.style.width = arrowInner.style.width = '0';
    arrowOuter.style.marginLeft = this.px(-arrowSize);
    arrowOuter.style.borderWidth = arrowOuterSizePx;
    arrowOuter.style.borderStyle = arrowInner.style.borderStyle = 'solid';
    arrowOuter.style.borderBottomWidth = 0;
    arrowOuter.style.display = '';

    arrowOuter.style.borderColor = `${borderColor} transparent transparent`;
    arrowInner.style.borderColor = `${backgroundColor} transparent transparent`;

    arrowOuter.style.zIndex = this.options.zIndex + 1;
    arrowInner.style.zIndex = this.options.zIndex + 1;

    arrowOuter.style.borderTopWidth = arrowOuterSizePx;
    arrowInner.style.borderTopWidth = arrowInnerSizePx;

    arrowOuter.style.borderLeftWidth = arrowOuterSizePx;
    arrowInner.style.borderLeftWidth = arrowInnerSizePx;

    arrowOuter.style.borderRightWidth = arrowOuterSizePx;
    arrowInner.style.borderRightWidth = arrowInnerSizePx;

    arrowOuter.style.marginLeft = this.px(-(arrowSize));
    arrowInner.style.marginLeft = this.px(-(arrowSize - borderWidth));

    arrow.appendChild(arrowOuter);
    arrow.appendChild(arrowInner);

    return arrow;
  }

/**
 * Create dom elements
 */
  createDOMElements() {
    const bubble = this.bubble = document.createElement('div');
    bubble.style.position = 'absolute';
    bubble.style.zIndex = this.options.zIndex - 1;
    bubble.style.boxShadow = '0px 0px 15px rgba(0,0,0,0.4)';

    const content = this.content = this.createContent();
    const arrow = this.arrow = this.createArrow();
    const closeBtn = this.closeBtn = this.createCloseBtn();

    closeBtn.style.zIndex = this.options.zIndex + 1000;
    closeBtn.onclick = this.options.onClose;
    bubble.appendChild(content);
    bubble.appendChild(arrow);
    bubble.appendChild(closeBtn);
  }


  /* Pan the map to fit the InfoBox.
   */
  panMap() {
    // if we go beyond map, pan map
    const map = this.options.map;
    const bounds = map.getBounds();
    if (!bounds) return;

    // The position of the infowindow
    const position = this.options.location;

    // The dimension of the infowindow
    const iwWidth = this.options.contentWidth;
    const iwHeight = this.options.contentHeight;

    // The offset position of the infowindow
    const iwOffsetX = Math.round(this.options.contentWidth / 2);
    const iwOffsetY = Math.round(this.options.contentHeight + this.options.arrowSize + 10);

    // Padding on the infowindow
    const padX = 40;
    const padY = 40;

    // The degrees per pixel
    const mapDiv = map.getDiv();
    const mapWidth = mapDiv.offsetWidth;
    const mapHeight = mapDiv.offsetHeight;
    const boundsSpan = bounds.toSpan();
    const longSpan = boundsSpan.lng();
    const latSpan = boundsSpan.lat();
    const degPixelX = longSpan / mapWidth;
    const degPixelY = latSpan / mapHeight;

    // The bounds of the map
    const mapWestLng = bounds.getSouthWest().lng();
    const mapEastLng = bounds.getNorthEast().lng();
    const mapNorthLat = bounds.getNorthEast().lat();
    const mapSouthLat = bounds.getSouthWest().lat();

    // The bounds of the infowindow
    const iwWestLng = position.lng() + (iwOffsetX - padX) * degPixelX;
    const iwEastLng = position.lng() + (iwOffsetX + iwWidth + padX) * degPixelX;
    const iwNorthLat = position.lat() - (iwOffsetY - padY) * degPixelY;
    const iwSouthLat = position.lat() - (iwOffsetY + iwHeight + padY) * degPixelY;

    // calculate center shift
    const shiftLng =
        (iwWestLng < mapWestLng ? mapWestLng - iwWestLng : 0) +
        (iwEastLng > mapEastLng ? mapEastLng - iwEastLng : 0);
    const shiftLat =
        (iwNorthLat > mapNorthLat ? mapNorthLat - iwNorthLat : 0) +
        (iwSouthLat < mapSouthLat ? mapSouthLat - iwSouthLat : 0);

    // The center of the map
    const center = map.getCenter();

    // The new map center
    const centerX = center.lng() - shiftLng;
    const centerY = center.lat() - shiftLat;

    // center the map to the new shifted center
    map.setCenter(new google.maps.LatLng(centerY, centerX));
  }

  draw() {
    // Resize the image's div to fit the indicated dimensions.
    const bubble = this.bubble;

    // Position the overlay
    const point = this.getProjection().fromLatLngToDivPixel(this.options.location);

    if (point) {
      bubble.style.left = this.px(point.x - Math.round(this.options.contentWidth / 2));
      bubble.style.top = this.px(point.y - Math.round(this.options.contentHeight + this.options.arrowSize + 10));
    }
  }

  // The onRemove() method will be called automatically from the API if
  // we ever set the overlay's map property to 'null'.
  onRemove() {
    this.bubble.parentNode.removeChild(this.bubble);
    this.bubble = null;
  }
}

export default BubbleOverlay;

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Google Maps API信息窗口

来自分类Dev

异步Google Maps信息窗口

来自分类Dev

我只想打开1个信息窗口-Google Maps API JS

来自分类Dev

在Google Maps的“信息”窗口内单击按钮

来自分类Dev

Angular Google Maps信息窗口HTML

来自分类Dev

在Google Maps的信息窗口中添加图像?

来自分类Dev

Google Maps中的信息窗口无法加载

来自分类Dev

信息窗口的Google Maps外部链接

来自分类Dev

多个Google Maps折线和信息窗口

来自分类Dev

Google Maps信息窗口显示/隐藏操作

来自分类Dev

angularjs-google-maps 信息窗口位置

来自分类Dev

使用 React 导入 Google Maps API JS 文件

来自分类Dev

Google Maps Angular Js

来自分类Dev

鼠标悬停时未显示Google Maps信息窗口

来自分类Dev

如何在iOS右侧显示Google Maps信息窗口

来自分类Dev

标记信息窗口中的Android Google Maps HTML

来自分类Dev

iOS自定义信息窗口Google Maps SDK 1.7.2

来自分类Dev

通过ClusterManager Google Maps Android显示的隐藏信息窗口

来自分类Dev

Google Maps Android的自定义信息窗口

来自分类Dev

Google Maps:缩放时,选择信息窗口文本

来自分类Dev

显示信息窗口后阻止Google Maps移动

来自分类Dev

Google Maps信息窗口不适用于标记单击

来自分类Dev

Google Maps上的多个标记和信息窗口(使用MySQL)

来自分类Dev

Google Maps Api-信息窗口中的多个项目

来自分类Dev

Google Maps v3适合多个信息窗口的内容

来自分类Dev

从数据库填充Google Maps信息窗口

来自分类Dev

自定义Google Maps JavaScript API 3信息窗口

来自分类Dev

在Google Maps信息窗口中将2 DIV彼此对齐

来自分类Dev

在Google Maps标记的信息窗口中显示链接