this.props.hoverDistance;
_onDrag = (...args) => this.props.onDrag && this.props.onDrag(...args);
_onDragEnd = (...args) =>
this.props.onDragEnd && this.props.onDragEnd(...args);
_onMapTypeIdChange = (...args) =>
this.props.onMapTypeIdChange && this.props.onMapTypeIdChange(...args);
_onZoomAnimationStart = (...args) =>
this.props.onZoomAnimationStart && this.props.onZoomAnimationStart(...args);
_onZoomAnimationEnd = (...args) =>
this.props.onZoomAnimationEnd && this.props.onZoomAnimationEnd(...args);
_onTilesLoaded = () => this.props.onTilesLoaded && this.props.onTilesLoaded();
_onChildClick = (...args) => {
if (this.props.onChildClick) {
return this.props.onChildClick(...args);
}
return undefined;
};
_onChildMouseDown = (hoverKey, childProps) => {
this.childMouseDownArgs_ = [hoverKey, childProps];
if (this.props.onChildMouseDown) {
this.props.onChildMouseDown(hoverKey, childProps, { ...this.mouse_ });
}
};
// this method works only if this.props.onChildMouseDown was called
_onChildMouseUp = () => {
if (this.childMouseDownArgs_) {
if (this.props.onChildMouseUp) {
this.props.onChildMouseUp(...this.childMouseDownArgs_, {
...this.mouse_,
});
}
this.childMouseDownArgs_ = null;
this.childMouseUpTime_ = new Date().getTime();
}
};
// this method works only if this.props.onChildMouseDown was called
_onChildMouseMove = () => {
if (this.childMouseDownArgs_) {
if (this.props.onChildMouseMove) {
this.props.onChildMouseMove(...this.childMouseDownArgs_, {
...this.mouse_,
});
}
}
};
_onChildMouseEnter = (...args) => {
if (this.props.onChildMouseEnter) {
return this.props.onChildMouseEnter(...args);
}
return undefined;
};
_onChildMouseLeave = (...args) => {
if (this.props.onChildMouseLeave) {
return this.props.onChildMouseLeave(...args);
}
return undefined;
};
_setViewSize = () => {
if (!this.mounted_) return;
if (isFullScreen()) {
this.geoService_.setViewSize(window.innerWidth, window.innerHeight);
} else {
const mapDom = ReactDOM.findDOMNode(this.googleMapDom_);
this.geoService_.setViewSize(mapDom.clientWidth, mapDom.clientHeight);
}
this._onBoundsChanged();
};
_onWindowResize = () => {
this.resetSizeOnIdle_ = true;
};
_onMapMouseMove = (e) => {
if (!this.mouseInMap_) return;
const currTime = new Date().getTime();
const K_RECALC_CLIENT_RECT_MS = 50;
if (currTime - this.mouseMoveTime_ > K_RECALC_CLIENT_RECT_MS) {
this.boundingRect_ = e.currentTarget.getBoundingClientRect();
}
this.mouseMoveTime_ = currTime;
const mousePosX = e.clientX - this.boundingRect_.left;
const mousePosY = e.clientY - this.boundingRect_.top;
if (!this.mouse_) {
this.mouse_ = { x: 0, y: 0, lat: 0, lng: 0 };
}
this.mouse_.x = mousePosX;
this.mouse_.y = mousePosY;
const latLng = this.geoService_.fromContainerPixelToLatLng(this.mouse_);
this.mouse_.lat = latLng.lat;
this.mouse_.lng = latLng.lng;
this._onChildMouseMove();
if (currTime - this.dragTime_ < K_IDLE_TIMEOUT) {
this.fireMouseEventOnIdle_ = true;
} else {
this.markersDispatcher_.emit('kON_MOUSE_POSITION_CHANGE');
this.fireMouseEventOnIdle_ = false;
}
};
// K_IDLE_CLICK_TIMEOUT - looks like 300 is enough
_onClick = (...args) =>
this.props.onClick &&
!this.childMouseDownArgs_ &&
new Date().getTime() - this.childMouseUpTime_ > K_IDLE_CLICK_TIMEOUT &&
this.dragTime_ === 0 &&
this.props.onClick(...args);
_onMapClick = (event) => {
if (this.markersDispatcher_) {
// support touch events and recalculate mouse position on click
this._onMapMouseMove(event);
const currTime = new Date().getTime();
if (currTime - this.dragTime_ > K_IDLE_TIMEOUT) {
if (this.mouse_) {
this._onClick({
...this.mouse_,
event,
});
}
this.markersDispatcher_.emit('kON_CLICK', event);
}
}
};
// gmap can't prevent map drag if mousedown event already occured
// the only workaround I find is prevent mousedown native browser event
_onMapMouseDownNative = (event) => {
if (!this.mouseInMap_) return;
this._onMapMouseDown(event);
};
_onMapMouseDown = (event) => {
if (this.markersDispatcher_) {
const currTime = new Date().getTime();
if (currTime - this.dragTime_ > K_IDLE_TIMEOUT) {
// Hovered marker detected at mouse move could be deleted at mouse down time
// so it will be good to force hovered marker recalculation
this._onMapMouseMove(event);
this.markersDispatcher_.emit('kON_MDOWN', event);
}
}
};
_onMapMouseDownCapture = () => {
if (detectBrowser().isChrome) {
// to fix strange zoom in chrome
this.zoomControlClickTime_ = new Date().getTime();
}
};
_onKeyDownCapture = () => {
if (detectBrowser().isChrome) {
this.zoomControlClickTime_ = new Date().getTime();
}
};
_isCenterDefined = (center) =>
center &&
((isPlainObject(center) && isNumber(center.lat) && isNumber(center.lng)) ||
(center.length === 2 && isNumber(center[0]) && isNumber(center[1])));
_onBoundsChanged = (map, maps, callExtBoundsChange) => {
if (map) {
const gmC = map.getCenter();
this.geoService_.setView([gmC.lat(), gmC.lng()], map.getZoom(), 0);
}
if (
(this.props.onChange || this.props.onBoundsChange) &&
this.geoService_.canProject()
) {
const zoom = this.geoService_.getZoom();
const bounds = this.geoService_.getBounds();
const centerLatLng = this.geoService_.getCenter();
if (!isArraysEqualEps(bounds, this.prevBounds_, kEPS)) {
if (callExtBoundsChange !== false) {
const marginBounds = this.geoService_.getBounds(this.props.margin);
if (this.props.onBoundsChange) {
this.props.onBoundsChange(
this.centerIsObject_
? { ...centerLatLng }
: [centerLatLng.lat, centerLatLng.lng],
zoom,
bounds,
marginBounds
);
}
if (this.props.onChange) {
this.props.onChange({
center: { ...centerLatLng },
zoom,
bounds: {
nw: {
lat: bounds[0],
lng: bounds[1],
},
se: {
lat: bounds[2],
lng: bounds[3],
},
sw: {
lat: bounds[4],
lng: bounds[5],
},
ne: {
lat: bounds[6],
lng: bounds[7],
},
},
marginBounds: {
nw: {
lat: marginBounds[0],
lng: marginBounds[1],
},
se: {
lat: marginBounds[2],
lng: marginBounds[3],
},
sw: {
lat: marginBounds[4],
lng: marginBounds[5],
},
ne: {
lat: marginBounds[6],
lng: marginBounds[7],
},
},
size: this.geoService_.hasSize()
? {
width: this.geoService_.getWidth(),
height: this.geoService_.getHeight(),
}
: {
width: 0,
height: 0,
},
});
}
this.prevBounds_ = bounds;
}
}
}
};
_registerChild = (ref) => {
this.googleMapDom_ = ref;
};
render() {
const overlay = this.state.overlay;
const mapMarkerPrerender = !overlay ? (
) : null;
return (
{IS_REACT_16 && overlay && createPortal(this._renderPortal(), overlay)}
{/* render markers before map load done */}
{mapMarkerPrerender}
);
}
}
export default GoogleMap;