core/analyzers/panel.analyzer.ts
core/analyzers/panel.analyzer.ts is a file in Bane's Lab Site. 53 lines of code and 15 definitions.
import type { PanelExtent as Extent, PanelView, PanelPoint as Point } from "#types/panel.types";
import { PANEL_MAX_SCALE, PANEL_MIN_SCALE } from "#configuration/constants/panel.constants";
import { HALF } from "#configuration/constants/element.constants";
export const ORIGIN_VIEW: PanelView = { scale: 1, x: 0, y: 0 };
const clamp = function clamp(value: number, low: number, high: number): number {
return Math.min(Math.max(value, low), high);
};
export const extentOf = function extentOf(element: Element): Extent {
const rect = element.getBoundingClientRect();
return { height: rect.height, width: rect.width };
};
export const contentExtentOf = function contentExtentOf(stage: Element, scale: number): Extent {
const rect = extentOf(stage);
return { height: rect.height / scale, width: rect.width / scale };
};
export const boundedView = function boundedView(view: PanelView, viewport: Extent, content: Extent): PanelView {
const spanX = viewport.width - content.width * view.scale;
const spanY = viewport.height - content.height * view.scale;
return {
scale: view.scale,
x: clamp(view.x, Math.min(0, spanX), Math.max(0, spanX)),
y: clamp(view.y, Math.min(0, spanY), Math.max(0, spanY)),
};
};
export const zoomedView = function zoomedView(view: PanelView, factor: number, anchor: Point): PanelView {
const scale = clamp(view.scale * factor, PANEL_MIN_SCALE, PANEL_MAX_SCALE);
const ratio = scale / view.scale;
return { scale, x: anchor.x - (anchor.x - view.x) * ratio, y: anchor.y - (anchor.y - view.y) * ratio };
};
export const fittedView = function fittedView(viewport: Extent, content: Extent, ceiling = 1): PanelView {
if (content.width === 0 || content.height === 0) {
return ORIGIN_VIEW;
}
const scale = clamp(
Math.min(viewport.width / content.width, viewport.height / content.height, ceiling),
PANEL_MIN_SCALE,
ceiling,
);
return {
scale,
x: (viewport.width - content.width * scale) / HALF,
y: (viewport.height - content.height * scale) / HALF,
};
};
export const centerOf = function centerOf(extent: Extent): Point {
return { x: extent.width / HALF, y: extent.height / HALF };
};
export const distanceBetween = function distanceBetween(a: Point, b: Point): number {
return Math.hypot(a.x - b.x, a.y - b.y);
};
export const midpointOf = function midpointOf(a: Point, b: Point): Point {
return { x: (a.x + b.x) / HALF, y: (a.y + b.y) / HALF };
};