View / implement a smooth rebound effect when a max extent is given
This is done by applying the center constraint differently when we're in the middle of an interaction/animation or not. When the view is moving, the center constraint will restrain the given value in an "elastic" way, using a logarithmic function. This can be disabled using the `smoothCenterConstrain` view parameter.
This commit is contained in:
@@ -12,9 +12,11 @@ import {clamp} from './math.js';
|
||||
/**
|
||||
* @param {import("./extent.js").Extent} extent Extent.
|
||||
* @param {boolean} onlyCenter If true, the constraint will only apply to the view center.
|
||||
* @param {boolean} smooth If true, the view will be able to go slightly out of the given extent
|
||||
* (only during interaction and animation).
|
||||
* @return {Type} The constraint.
|
||||
*/
|
||||
export function createExtent(extent, onlyCenter) {
|
||||
export function createExtent(extent, onlyCenter, smooth) {
|
||||
return (
|
||||
/**
|
||||
* @param {import("./coordinate.js").Coordinate|undefined} center Center.
|
||||
@@ -27,11 +29,23 @@ export function createExtent(extent, onlyCenter) {
|
||||
if (center) {
|
||||
let viewWidth = onlyCenter ? 0 : size[0] * resolution;
|
||||
let viewHeight = onlyCenter ? 0 : size[1] * resolution;
|
||||
const minX = extent[0] + viewWidth / 2;
|
||||
const maxX = extent[2] - viewWidth / 2;
|
||||
const minY = extent[1] + viewHeight / 2;
|
||||
const maxY = extent[3] - viewHeight / 2;
|
||||
let x = clamp(center[0], minX, maxX);
|
||||
let y = clamp(center[1], minY, maxY);
|
||||
let ratio = 30 * resolution;
|
||||
|
||||
return [
|
||||
clamp(center[0], extent[0] + viewWidth / 2, extent[2] - viewWidth / 2),
|
||||
clamp(center[1], extent[1] + viewHeight / 2, extent[3] - viewHeight / 2)
|
||||
];
|
||||
// during an interaction, allow some overscroll
|
||||
if (opt_isMoving && smooth) {
|
||||
x += -ratio * Math.log(1 + Math.max(0, minX - center[0]) / ratio) +
|
||||
ratio * Math.log(1 + Math.max(0, center[0] - maxX) / ratio);
|
||||
y += -ratio * Math.log(1 + Math.max(0, minY - center[1]) / ratio) +
|
||||
ratio * Math.log(1 + Math.max(0, center[1] - maxY) / ratio);
|
||||
}
|
||||
|
||||
return [x, y];
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user