Create a class for PannableState, add inverse transformation

main
Shad Amethyst 2 years ago
parent 5121ffddfa
commit f38127a4ad

@ -313,17 +313,6 @@ export function attachTouch(element, options = {}) {
} }
} }
/**
* @typedef {object} PannableState
* An immutable object returned by `Pannable::getState()`
* @prop {number} dx
* @prop {number} dy
* @prop {number} scale
* @prop {number} logScale
* @prop {(x: number, y: number) => [x: number, y: number]} get
* Returns the transformed coordinates
**/
/** /**
* @typedef {object} PannableOptions * @typedef {object} PannableOptions
* @prop {number=} downscale * @prop {number=} downscale
@ -391,19 +380,8 @@ export class Pannable {
} }
/** @returns {PannableState} **/ /** @returns {PannableState} **/
getState() { getState(cx = 0, cy = 0) {
const scale = this.scale; return new PannableState(this.dx + cx, this.dy + cy, this.logScale);
const dx = this.dx;
const dy = this.dy;
return {
dx,
dy,
logScale: this.logScale,
scale,
get: (x, y) => {
return [x * scale + dx, y * scale + dy];
}
};
} }
/** /**
@ -448,6 +426,51 @@ export class Pannable {
} }
} }
/**
* An immutable view of `Pannable`, returned by `Pannable::getState`.
**/
export class PannableState {
/**
* @param {number} dx
* @param {number} dy
* @param {number} logScale
**/
constructor(dx, dy, logScale) {
/** @readonly The X offset to move coordinates by *after* multiplying them by `scale` **/
this.dx = dx;
/** @readonly The Y offset to move coordinates by *after* multiplying them by `scale` **/
this.dy = dy;
/** @readonly The base-2 logarithm of `scale`, used internally for precision purposes **/
this.logScale = logScale;
/** @readonly The zoom strength **/
this.scale = Math.pow(2, logScale);
}
/**
* Transforms the input coordinates from the "pannable" coordinates
* to the "real" coordinates (what you will display on screen)
*
* @param {number} x The X "pannable" coordinate
* @param {number} y The Y "pannable" coordinate
* @returns {[x: number, y: number]}
**/
get(x, y) {
return [x * this.scale + this.dx, y * this.scale + this.dy];
}
/**
* Transforms the input coordinates from the "real" coordinates (where they are on screen)
* to the "pannable" coordinates; this is the inverse operation of the `PannableState::get` method.
*
* @param {number} x The X "real" coordinate
* @param {number} y The Y "real" coordinate
* @returns {[x: number, y: number]}
**/
inverse(x, y) {
return [(x - this.dx) / this.scale, (y - this.dy) / this.scale];
}
}
/** /**
* @typedef {PannableOptions & { * @typedef {PannableOptions & {
* onUpdate?: (state: PannableState) => void, * onUpdate?: (state: PannableState) => void,

@ -28,13 +28,14 @@ export function usePannable(config: PannableOptions & UsePannableOptions) {
return newState; return newState;
}, },
getState: () => { getState: () => {
const result = state(); const preTransformed = state();
const [cx, cy] = center(); const [cx, cy] = center();
return {
...result, return new PannableState(
dx: result.dx + cx, preTransformed.dx + cx,
dy: result.dy + cy, preTransformed.dy + cy,
}; preTransformed.logScale
);
} }
}; };
} }

Loading…
Cancel
Save