Skip to content

Commit

Permalink
Make zoom via wheel more responsive at the ends of the zoom range.
Browse files Browse the repository at this point in the history
Prior to this, zooming via the wheel until the map was fully zoomed in
or zoomed out and then reversing the wheel could have a substantial lag
before the zoom would reverse.  While some debouncing is fine, this
sometimes felt unresponsive.  This ignores wheel events once the end of
the range is reached rather than adding more time to the transition.
  • Loading branch information
manthey committed Apr 10, 2019
1 parent 0de397f commit 85919e1
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 60 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Change Log

## Unreleased

### Improvements
- More response zooming via mouse wheel (#993)

## Version 0.19.3

### Features
Expand Down
72 changes: 36 additions & 36 deletions src/map.js
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ var map = function (arg) {
var oldCenter = m_this.center(undefined, undefined);
m_gcs = arg;
reset_minimum_zoom();
var newZoom = fix_zoom(m_zoom);
var newZoom = m_this._fix_zoom(m_zoom);
if (newZoom !== m_zoom) {
m_this.zoom(newZoom);
}
Expand Down Expand Up @@ -417,7 +417,7 @@ var map = function (arg) {

/* The ignoreDiscreteZoom flag is intended to allow non-integer zoom values
* during animation. */
val = fix_zoom(val, ignoreDiscreteZoom);
val = m_this._fix_zoom(val, ignoreDiscreteZoom);
if (val === m_zoom) {
return m_this;
}
Expand Down Expand Up @@ -683,7 +683,7 @@ var map = function (arg) {
m_height = arg.height || m_height;

reset_minimum_zoom();
var newZoom = fix_zoom(m_zoom);
var newZoom = m_this._fix_zoom(m_zoom);
if (newZoom !== m_zoom) {
m_this.zoom(newZoom);
}
Expand Down Expand Up @@ -1144,7 +1144,7 @@ var map = function (arg) {
},
end: {
center: opts.center,
zoom: fix_zoom(opts.zoom),
zoom: m_this._fix_zoom(opts.zoom),
rotation: fix_rotation(opts.rotation, undefined, true)
},
ease: opts.ease,
Expand Down Expand Up @@ -1205,7 +1205,7 @@ var map = function (arg) {
if (time >= m_transition.end.time || next) {
if (!next) {
if (m_transition.end.center) {
var needZoom = m_zoom !== fix_zoom(m_transition.end.zoom);
var needZoom = m_zoom !== m_this._fix_zoom(m_transition.end.zoom);
m_this.center(m_transition.end.center, null, needZoom, needZoom);
}
m_this.zoom(m_transition.end.zoom, m_transition.zoomOrigin);
Expand Down Expand Up @@ -1236,7 +1236,7 @@ var map = function (arg) {
if (m_transition.zCoord) {
p[2] = z2zoom(p[2]);
}
if (fix_zoom(p[2], true) === m_zoom) {
if (m_this._fix_zoom(p[2], true) === m_zoom) {
m_this.center({
x: p[0],
y: p[1]
Expand Down Expand Up @@ -1408,7 +1408,7 @@ var map = function (arg) {
}

// calculate the zoom to fit the bounds
zoom = fix_zoom(calculate_zoom(bounds, rotation));
zoom = m_this._fix_zoom(calculate_zoom(bounds, rotation));

// clamp bounds if necessary
bounds = fix_bounds(bounds, rotation);
Expand Down Expand Up @@ -1453,7 +1453,7 @@ var map = function (arg) {

gcs = (gcs === null ? m_gcs : (gcs === undefined ? m_ingcs : gcs));
// preprocess the arguments
zoom = fix_zoom(zoom, ignoreDiscreteZoom);
zoom = m_this._fix_zoom(zoom, ignoreDiscreteZoom);
units = m_this.unitsPerPixel(zoom);
center = m_this.gcsToWorld(center, null);

Expand Down Expand Up @@ -1846,6 +1846,33 @@ var map = function (arg) {
return m_animationQueue[0];
};

/**
* Return the nearest valid zoom level to the requested zoom.
* @param {number} zoom A zoom level to adjust to current settings
* @param {boolean} ignoreDiscreteZoom If `true`, ignore the `discreteZoom`
* option when determining the new view.
* @returns {number} The zoom level clamped to the allowed zoom range and
* with other settings applied.
* @private
*/
this._fix_zoom = function (zoom, ignoreDiscreteZoom) {
zoom = Math.round(zoom * 1e6) / 1e6;
zoom = Math.max(
Math.min(
m_validZoomRange.max,
zoom
),
m_validZoomRange.min
);
if (m_discreteZoom && !ignoreDiscreteZoom) {
zoom = Math.round(zoom);
if (zoom < m_validZoomRange.min) {
zoom = Math.ceil(m_validZoomRange.min);
}
}
return zoom;
};

/**
* Draw a layer image to a canvas context. The layer's opacity and transform
* are applied. This is used as part of making a screenshot.
Expand Down Expand Up @@ -2036,33 +2063,6 @@ var map = function (arg) {
}
}

/**
* Return the nearest valid zoom level to the requested zoom.
* @param {number} zoom A zoom level to adjust to current settings
* @param {boolean} ignoreDiscreteZoom If `true`, ignore the `discreteZoom`
* option when determining the new view.
* @returns {number} The zoom level clamped to the allowed zoom range and
* with other settings applied.
* @private
*/
function fix_zoom(zoom, ignoreDiscreteZoom) {
zoom = Math.round(zoom * 1e6) / 1e6;
zoom = Math.max(
Math.min(
m_validZoomRange.max,
zoom
),
m_validZoomRange.min
);
if (m_discreteZoom && !ignoreDiscreteZoom) {
zoom = Math.round(zoom);
if (zoom < m_validZoomRange.min) {
zoom = Math.ceil(m_validZoomRange.min);
}
}
return zoom;
}

/**
* Return a valid rotation angle.
*
Expand Down Expand Up @@ -2312,7 +2312,7 @@ var map = function (arg) {

// Fix the zoom level (minimum and initial)
this.zoomRange(arg, true);
m_zoom = fix_zoom(m_zoom);
m_zoom = this._fix_zoom(m_zoom);
m_rotation = fix_rotation(m_rotation);
// Now update to the correct center and zoom level
this.center($.extend({}, arg.center || m_center), undefined);
Expand Down
53 changes: 29 additions & 24 deletions src/mapInteractor.js
Original file line number Diff line number Diff line change
Expand Up @@ -1603,31 +1603,36 @@ var mapInteractor = function (args) {
zoom = startZoom + (targetZoom > startZoom ? 1 : -1);
}
}
map.transitionCancel('debounced_zoom.' + geo_action.zoom);
map.transition({
zoom: zoom,
zoomOrigin: origin,
duration: m_options.zoomAnimation.duration,
ease: m_options.zoomAnimation.ease,
done: function (status) {
status = status || {};
var zoomRE = new RegExp('\\.' + geo_action.zoom + '$');
if (!status.next && (!status.cancel ||
('' + status.source).search(zoomRE) < 0)) {
targetZoom = undefined;
zoom = Math.round(map._fix_zoom(zoom) * 1e6) / 1e6;
if (zoom !== map.zoom()) {
map.transitionCancel('debounced_zoom.' + geo_action.zoom);
map.transition({
zoom: zoom,
zoomOrigin: origin,
duration: m_options.zoomAnimation.duration,
ease: m_options.zoomAnimation.ease,
done: function (status) {
status = status || {};
var zoomRE = new RegExp('\\.' + geo_action.zoom + '$');
if (!status.next && (!status.cancel ||
('' + status.source).search(zoomRE) < 0)) {
targetZoom = undefined;
}
/* If we were animating the zoom, if the zoom is continuous, just
* stop where we are. If using discrete zoom, we need to make
* sure we end up discrete. However, we don't want to do that if
* the next action is further zooming. */
if (m_options.discreteZoom && status.cancel &&
status.transition && status.transition.end &&
('' + status.source).search(zoomRE) < 0) {
map.zoom(status.transition.end.zoom,
status.transition.end.zoomOrigin);
}
}
/* If we were animating the zoom, if the zoom is continuous, just
* stop where we are. If using discrete zoom, we need to make
* sure we end up discrete. However, we don't want to do that if
* the next action is further zooming. */
if (m_options.discreteZoom && status.cancel &&
status.transition && status.transition.end &&
('' + status.source).search(zoomRE) < 0) {
map.zoom(status.transition.end.zoom,
status.transition.end.zoomOrigin);
}
}
});
});
} else {
targetZoom = undefined;
}
} else {
zoom = deltaZ + map.zoom();
if (m_options.discreteZoom) {
Expand Down

0 comments on commit 85919e1

Please sign in to comment.