View / refactor how zoom and resolution are computed
This commit aims to simplify the computation of zoom and resolution in the View class. Previously zoom levels and resolution computations were mixed in different places, ie resolution constraints, initial values, etc. Now the View class only has the `getZoomForResolution` and `getResolutionForZoom` methods to convert from one system to another. Other than that, most computations use the resolution system internally. The `constrainResolution` method also does not exist anymore, and is replaced by `getValidResolution` and `getValidZoomLevel` public methods.
This commit is contained in:
@@ -4,10 +4,11 @@
|
||||
import {linearFindNearest} from './array.js';
|
||||
import {clamp} from './math.js';
|
||||
import {getHeight, getWidth} from './extent';
|
||||
import {clamp} from './math';
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {function((number|undefined), number, number, import("./size.js").Size, boolean=): (number|undefined)} Type
|
||||
* @typedef {function((number|undefined), number, import("./size.js").Size, boolean=): (number|undefined)} Type
|
||||
*/
|
||||
|
||||
|
||||
@@ -20,13 +21,12 @@ export function createSnapToResolutions(resolutions, opt_maxExtent) {
|
||||
return (
|
||||
/**
|
||||
* @param {number|undefined} resolution Resolution.
|
||||
* @param {number} delta Delta.
|
||||
* @param {number} direction Direction.
|
||||
* @param {import("./size.js").Size} size Viewport size.
|
||||
* @param {boolean=} opt_isMoving True if an interaction or animation is in progress.
|
||||
* @return {number|undefined} Resolution.
|
||||
*/
|
||||
function(resolution, delta, direction, size, opt_isMoving) {
|
||||
function(resolution, direction, size, opt_isMoving) {
|
||||
if (resolution !== undefined) {
|
||||
let cappedRes = resolution;
|
||||
|
||||
@@ -39,19 +39,13 @@ export function createSnapToResolutions(resolutions, opt_maxExtent) {
|
||||
|
||||
// during interacting or animating, allow intermediary values
|
||||
if (opt_isMoving) {
|
||||
// TODO: actually take delta and direction into account
|
||||
return Math.min(resolution, cappedRes);
|
||||
const maxResolution = resolutions[0];
|
||||
const minResolution = resolutions[resolutions.length - 1];
|
||||
return clamp(cappedRes, minResolution, maxResolution);
|
||||
}
|
||||
|
||||
let z = linearFindNearest(resolutions, cappedRes, direction);
|
||||
z = clamp(z + delta, 0, resolutions.length - 1);
|
||||
const index = Math.floor(z);
|
||||
if (z != index && index < resolutions.length - 1) {
|
||||
const power = resolutions[index] / resolutions[index + 1];
|
||||
return resolutions[index] / Math.pow(power, z - index);
|
||||
} else {
|
||||
return resolutions[index];
|
||||
}
|
||||
let z = Math.floor(linearFindNearest(resolutions, cappedRes, direction));
|
||||
return resolutions[z];
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
@@ -63,23 +57,22 @@ export function createSnapToResolutions(resolutions, opt_maxExtent) {
|
||||
/**
|
||||
* @param {number} power Power.
|
||||
* @param {number} maxResolution Maximum resolution.
|
||||
* @param {number=} opt_maxLevel Maximum level.
|
||||
* @param {number=} opt_minResolution Minimum resolution.
|
||||
* @param {import("./extent.js").Extent=} opt_maxExtent Maximum allowed extent.
|
||||
* @return {Type} Zoom function.
|
||||
*/
|
||||
export function createSnapToPower(power, maxResolution, opt_maxLevel, opt_maxExtent) {
|
||||
export function createSnapToPower(power, maxResolution, opt_minResolution, opt_maxExtent) {
|
||||
return (
|
||||
/**
|
||||
* @param {number|undefined} resolution Resolution.
|
||||
* @param {number} delta Delta.
|
||||
* @param {number} direction Direction.
|
||||
* @param {import("./size.js").Size} size Viewport size.
|
||||
* @param {boolean=} opt_isMoving True if an interaction or animation is in progress.
|
||||
* @return {number|undefined} Resolution.
|
||||
*/
|
||||
function(resolution, delta, direction, size, opt_isMoving) {
|
||||
function(resolution, direction, size, opt_isMoving) {
|
||||
if (resolution !== undefined) {
|
||||
let cappedRes = resolution;
|
||||
let cappedRes = Math.min(resolution, maxResolution);
|
||||
|
||||
// apply constraint related to max extent
|
||||
if (opt_maxExtent) {
|
||||
@@ -90,18 +83,16 @@ export function createSnapToPower(power, maxResolution, opt_maxLevel, opt_maxExt
|
||||
|
||||
// during interacting or animating, allow intermediary values
|
||||
if (opt_isMoving) {
|
||||
// TODO: actually take delta and direction into account
|
||||
return Math.min(resolution, cappedRes);
|
||||
return opt_minResolution !== undefined ? Math.max(opt_minResolution, cappedRes) : cappedRes;
|
||||
}
|
||||
|
||||
const offset = -direction / 2 + 0.5;
|
||||
const oldLevel = Math.floor(
|
||||
const offset = -direction * (0.5 - 1e-9) + 0.5;
|
||||
const zoomLevel = Math.floor(
|
||||
Math.log(maxResolution / cappedRes) / Math.log(power) + offset);
|
||||
let newLevel = Math.max(oldLevel + delta, 0);
|
||||
if (opt_maxLevel !== undefined) {
|
||||
newLevel = Math.min(newLevel, opt_maxLevel);
|
||||
}
|
||||
return maxResolution / Math.pow(power, newLevel);
|
||||
let newResolution = maxResolution / Math.pow(power, zoomLevel);
|
||||
return opt_minResolution !== undefined ?
|
||||
clamp(newResolution, opt_minResolution, maxResolution) :
|
||||
Math.min(maxResolution, newResolution);
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user