我正在尝试在
中更改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。我也尝试将选项传递给它。但似乎没有任何效果。
答案 0 :(得分:2)
对于使用InfoBox且造型有问题的任何人,以下内容对我有用:
<强> JS 强>
<InfoBox key={i}
defaultPosition={new google.maps.LatLng(marker.lat, marker.lng)}
options={{
pane: "overlayLayer",
pixelOffset: new google.maps.Size(-140, -60),
alignBottom: true,
boxStyle: {
boxShadow: `3px 3px 10px rgba(0,0,0,0.6)`
},
closeBoxURL : ""
}}
>
<div className="google_map_infobox">
{marker.txt}
</div>
</InfoBox>
<强> CSS 强>
.google_map_infobox
{
background: #fff;
padding: 1em;
text-align: center;
font-size: 1.1rem;
box-shadow: 3px 3px 10px rgba(0,0,0,0.6);
border: 1px solid #666;
}
这会创建一个框,该框位于标记的中心,并且有一个框阴影,没有关闭按钮等。boxStyle
选项是我在谷歌搜索中偶然发现的。
我还使用CSS做了一些盒子样式。也许我可以在boxStyle属性中完成所有操作,但我宁愿在CSS中保留尽可能多的内容。 box-shadow是唯一不能通过CSS工作的东西。
希望这可以帮助使用react-google-maps
的人。
答案 1 :(得分:1)
我建议您为谷歌地图创建自己的组件,并使用&#34; plain&#34;创建自定义信息窗口。 JavaScript的。通过这种方式,您可以直接使用所有谷歌地图&#34; native&#34;属性等,并且不需要使用任何超级复杂和有限的组件库:))
示例google maps wrapper for react(只是简单示例):
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;
&#13;
然后你就可以使用它:
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;
&#13;
示例信息窗口:
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;
&#13;