mirror of
https://github.com/google-map-react/google-map-react.git
synced 2025-12-08 18:26:32 +00:00
Fix zoom animation for v3.32 (#559)
* Use the experimental version, to get the new zoom animation. * Don't use bounds for rendering in 3.32 * Revert the project() and unproject() methods. Instead, add a new method fromLatLngToContainerPixel() to geo service. * No need of setting .exp, that is by default * Comments explaining the significance of API v3.32 * Add _VERSION to const
This commit is contained in:
parent
aec0c08aae
commit
7877008e17
@ -34,6 +34,9 @@ const K_GOOGLE_TILE_SIZE = 256;
|
||||
const K_IDLE_TIMEOUT = 100;
|
||||
const K_IDLE_CLICK_TIMEOUT = 300;
|
||||
const DEFAULT_MIN_ZOOM = 3;
|
||||
// Starting with version 3.32, the maps API calls `draw()` each frame during
|
||||
// a zoom animation.
|
||||
const DRAW_CALLED_DURING_ANIMATION_VERSION = 32;
|
||||
|
||||
function defaultOptions_(/* maps */) {
|
||||
return {
|
||||
@ -566,6 +569,11 @@ export default class GoogleMap extends Component {
|
||||
|
||||
this._setLayers(this.props.layerTypes);
|
||||
|
||||
// Parse `google.maps.version` to capture the major version number.
|
||||
const versionMatch = maps.version.match(/^3\.(\d+)\./);
|
||||
// The major version is the first (and only) captured group.
|
||||
const mapsVersion = versionMatch && Number(versionMatch[1]);
|
||||
|
||||
// render in overlay
|
||||
const this_ = this;
|
||||
const overlay = Object.assign(new maps.OverlayView(), {
|
||||
@ -588,6 +596,10 @@ export default class GoogleMap extends Component {
|
||||
|
||||
const panes = this.getPanes();
|
||||
panes.overlayMouseTarget.appendChild(div);
|
||||
this_.geoService_.setMapCanvasProjection(
|
||||
maps,
|
||||
overlay.getProjection()
|
||||
);
|
||||
|
||||
ReactDOM.unstable_renderSubtreeIntoContainer(
|
||||
this_,
|
||||
@ -618,11 +630,8 @@ export default class GoogleMap extends Component {
|
||||
draw() {
|
||||
const div = overlay.div;
|
||||
const overlayProjection = overlay.getProjection();
|
||||
const bounds = map.getBounds();
|
||||
const ne = bounds.getNorthEast();
|
||||
const sw = bounds.getSouthWest();
|
||||
const ptx = overlayProjection.fromLatLngToDivPixel(
|
||||
new maps.LatLng(ne.lat(), sw.lng())
|
||||
overlayProjection.fromContainerPixelToLatLng({ x: 0, y: 0 })
|
||||
);
|
||||
|
||||
// need round for safari still can't find what need for firefox
|
||||
@ -661,25 +670,29 @@ export default class GoogleMap extends Component {
|
||||
this_._onZoomAnimationStart();
|
||||
}
|
||||
|
||||
const TIMEOUT_ZOOM = 300;
|
||||
// If draw() is not called each frame during a zoom animation,
|
||||
// simulate it.
|
||||
if (mapsVersion < DRAW_CALLED_DURING_ANIMATION_VERSION) {
|
||||
const TIMEOUT_ZOOM = 300;
|
||||
|
||||
if (
|
||||
new Date().getTime() - this.zoomControlClickTime_ < TIMEOUT_ZOOM
|
||||
) {
|
||||
// there is strange Google Map Api behavior in chrome when zoom animation of map
|
||||
// is started only on second raf call, if was click on zoom control
|
||||
// or +- keys pressed, so i wait for two rafs before change state
|
||||
if (
|
||||
new Date().getTime() - this.zoomControlClickTime_ < TIMEOUT_ZOOM
|
||||
) {
|
||||
// there is strange Google Map Api behavior in chrome when zoom animation of map
|
||||
// is started only on second raf call, if was click on zoom control
|
||||
// or +- keys pressed, so i wait for two rafs before change state
|
||||
|
||||
// this does not fully prevent animation jump
|
||||
// but reduce it's occurence probability
|
||||
raf(() =>
|
||||
raf(() => {
|
||||
this_.updateCounter_++;
|
||||
this_._onBoundsChanged(map, maps);
|
||||
}));
|
||||
} else {
|
||||
this_.updateCounter_++;
|
||||
this_._onBoundsChanged(map, maps);
|
||||
// this does not fully prevent animation jump
|
||||
// but reduce it's occurence probability
|
||||
raf(() =>
|
||||
raf(() => {
|
||||
this_.updateCounter_++;
|
||||
this_._onBoundsChanged(map, maps);
|
||||
}));
|
||||
} else {
|
||||
this_.updateCounter_++;
|
||||
this_._onBoundsChanged(map, maps);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -720,11 +733,8 @@ export default class GoogleMap extends Component {
|
||||
const div = overlay.div;
|
||||
const overlayProjection = overlay.getProjection();
|
||||
if (div && overlayProjection) {
|
||||
const bounds = map.getBounds();
|
||||
const ne = bounds.getNorthEast();
|
||||
const sw = bounds.getSouthWest();
|
||||
const ptx = overlayProjection.fromLatLngToDivPixel(
|
||||
new maps.LatLng(ne.lat(), sw.lng())
|
||||
overlayProjection.fromContainerPixelToLatLng({ x: 0, y: 0 })
|
||||
);
|
||||
// need round for safari still can't find what need for firefox
|
||||
const ptxRounded = detectBrowser().isSafari
|
||||
|
||||
@ -265,10 +265,9 @@ export default class GoogleMapMarkers extends Component {
|
||||
? child.props.latLng
|
||||
: { lat: child.props.lat, lng: child.props.lng };
|
||||
|
||||
const pt = this.props.geoService.project(
|
||||
latLng,
|
||||
this.props.projectFromLeftTop
|
||||
);
|
||||
const pt = this.props.projectFromLeftTop
|
||||
? this.props.geoService.fromLatLngToContainerPixel(latLng)
|
||||
: this.props.geoService.project(latLng);
|
||||
|
||||
const stylePtPos = {
|
||||
left: pt.x,
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
import isEmpty from '../utils/isEmpty';
|
||||
|
||||
const BASE_URL = 'https://maps';
|
||||
const DEFAULT_URL = `${BASE_URL}.googleapis.com`;
|
||||
const API_PATH = '/maps/api/js?callback=_$_google_map_initialize_$_';
|
||||
@ -67,18 +65,11 @@ export default (bootstrapURLKeys, heatmapLibrary) => {
|
||||
}
|
||||
}
|
||||
|
||||
let params = Object.keys(bootstrapURLKeys).reduce(
|
||||
const params = Object.keys(bootstrapURLKeys).reduce(
|
||||
(r, key) => `${r}&${key}=${bootstrapURLKeys[key]}`,
|
||||
''
|
||||
);
|
||||
|
||||
// if no version is defined, we want to get the release version
|
||||
// and not the experimental version, to do so, we set v=3.31
|
||||
// src: https://developers.google.com/maps/documentation/javascript/versions
|
||||
if (isEmpty(bootstrapURLKeys.v)) {
|
||||
params += '&v=3.31';
|
||||
}
|
||||
|
||||
const baseUrl = getUrl(bootstrapURLKeys.region);
|
||||
const libraries = heatmapLibrary ? '&libraries=visualization' : '';
|
||||
|
||||
|
||||
@ -24,6 +24,11 @@ export default class Geo {
|
||||
this.hasSize_ = true;
|
||||
}
|
||||
|
||||
setMapCanvasProjection(maps, mapCanvasProjection) {
|
||||
this.maps_ = maps;
|
||||
this.mapCanvasProjection_ = mapCanvasProjection;
|
||||
}
|
||||
|
||||
canProject() {
|
||||
return this.hasSize_ && this.hasView_;
|
||||
}
|
||||
@ -62,6 +67,15 @@ export default class Geo {
|
||||
return this.transform_.locationPoint(LatLng.convert(ptLatLng));
|
||||
}
|
||||
|
||||
fromLatLngToContainerPixel(ptLatLng) {
|
||||
if (this.mapCanvasProjection_) {
|
||||
const latLng = new this.maps_.LatLng(ptLatLng.lat, ptLatLng.lng);
|
||||
return this.mapCanvasProjection_.fromLatLngToContainerPixel(latLng);
|
||||
}
|
||||
|
||||
return this.project(ptLatLng, true);
|
||||
}
|
||||
|
||||
getWidth() {
|
||||
return this.transform_.width;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user