Reactjs - 谷歌地图 - 样式InfoWindow [英] Reactjs - google maps - Style InfoWindow

查看:174
本文介绍了Reactjs - 谷歌地图 - 样式InfoWindow的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



这是我使用的代码:

 < InfoWindow options = {{maxWidth:900}} position = {self.state.position} ref =infoWindowonCloseclick = {self.onLineWindowClose}> 
< div className =berlinstyle = {{height:'120px',width:'260px',fontFamily:'Roboto'}}>
< div style = {{height:'20px'}}>
< div style = {{float:'left',padding:'3px 0 0 6px'}}>发件人:< / 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'}}>收件人:< / div>
< div style = {{float:'left',padding:3px,color:'#3497d9'}}> {self.state.endLocation.City}< / div>
< / div>
< LineList relationInfo = {this.state.relationDetails} />
< / div>
< / InfoWindow>

问题很简单。我如何改变它的外观?我试着设置className。我也尝试将选项传递给它。但似乎没有任何工作。 我推荐创建自己的谷歌地图组件,并创建自定义infowindow与普通JavaScript 。这样你就可以直接使用所有谷歌地图的原生属性等,不需要使用任何超级复杂和有限的组件库:)

谷歌地图示例包装反应(只是简单的例子):



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%',};返回(< div ref =mapstyle = {mapStyle}>< / div>); }} GoogleMap.propTypes = {onGetMap:PropTypes.func.isRequired,};导出默认的GoogleMap;

然后你可以像这样使用它:

 从'react'导入React,{Component,PropTypes};从'components / GoogleMap'中导入GoogleMap; class Some extends components {constructor(props,context){super(props,context); this.onMapReady = this.onMapReady.bind(this); this.state = {map:null,markers:[],}; } onMapReady(map){this.setState({map,}); //这里添加一些标记等。} render(){return(< div className =some>< GoogleMap onGetMap = {this.onMapReady} />< / div>); }} export default Some;  



示例信息窗口



class BubbleOverlay extends google.maps.OverlayView {constructor(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; //在这个覆盖层上显式调用setMap。 this.setMap(options.map); } / ** *将数字转换为像素* @param {number} num要转换的数字* @return {string}以像素为单位的数字* / px(num){if(num){// 0不需要被包装返回`$ {num} px`; } return num; } / ** * onAdd在地图的窗格准备就绪并且叠加层已添加到地图中时调用。 * / onAdd(){if(!this.bubble){this.createDOMElements(); } //将元素添加到overlayLayer窗格。 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';返回内容; } 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);返回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 ='绝对'; 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);返回箭头; } / ** *创建DOM元素* / createDOMElements(){const bubble = this.bubble = document.createElement('div'); bubble.style.position ='绝对'; 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(内容); bubble.appendChild(箭头); bubble.appendChild(为closeBtn); } / *平移地图以适合信息框。 * / panMap(){//如果我们超越地图,pan map const map = this.options.map; const bounds = map.getBounds();如果(!bounds)返回; // infowindow const位置的位置= this.options.location; // infowindow const的维数iwWidth = this.options.contentWidth; const iwHeight = this.options.contentHeight; // infowindow const的偏移位置iwOffsetX = Math.round(this.options.contentWidth / 2); const iwOffsetY = Math.round(this.options.contentHeight + this.options.arrowSize + 10); //填充infowindow const padX = 40; const padY = 40; //每像素的度数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; //地图的边界const mapWestLng = bounds.getSouthWest()。lng(); const mapEastLng = bounds.getNorthEast()。lng(); const mapNorthLat = bounds.getNorthEast()。lat(); const mapSouthLat = bounds.getSouthWest()。lat(); // 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; //计算中心偏移const shiftLng =(iwWestLng mapEastLng?mapEastLng-iwEastLng:0); const shiftLat =(iwNorthLat> mapNorthLat?mapNorthLat - iwNorthLat:0)+(iwSouthLat< mapSouthLat?mapSouthLat - iwSouthLat:0); //地图的中心const center = map.getCenter(); //新地图中心const centerX = center.lng() - shiftLng; const centerY = center.lat() - shiftLat; //将地图集中到新移动的中心map.setCenter(new google.maps.LatLng(centerY,centerX)); } draw(){//调整图片div的大小以适应指定的尺寸。 const bubble = this.bubble; //定位覆盖常量点= this.getProjection()。fromLatLngToDivPixel(this.options.location);如果(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)); }} //如果我们将overlay的map属性设置为'null',onRemove()方法将从API自动调用。 onRemove(){this.bubble.parentNode.removeChild(this.bubble); this.bubble = null; }}导出默认的BubbleOverlay;


I am trying to change style of the InfoWindow in the

This is the code that I use:

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

Question is simple. How do I change its appearance? I tried setting the className. I also tried to pass options to it. But nothing seems to work.

解决方案

I recommend to create your own component for google maps and create custom infowindow with "plain" javascript. This way you can use straight all google maps "native" properties etc. and don't need to play with any super complicated and limited component libraries :)

Example google maps wrapper for react (just quick example):

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;

Then you can use it like:

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;

Example info window:

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;

这篇关于Reactjs - 谷歌地图 - 样式InfoWindow的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆