summaryrefslogtreecommitdiff
path: root/apps/web/src/lib/timeline/zoom-utils.ts
diff options
context:
space:
mode:
authorMaze Winther <mazewinther@gmail.com>2026-02-02 19:46:51 +0100
committerMaze Winther <mazewinther@gmail.com>2026-02-02 19:46:51 +0100
commitad794fa43b472942f58af6d42dcecb1d358c5929 (patch)
treebc326b533a788ea600a0e6aefc17807738a752b5 /apps/web/src/lib/timeline/zoom-utils.ts
parent7d5914353b8f78652f12b880fcd16c5ab82b3769 (diff)
parent9ca32e5e39d3a1a7eaf6086f9f0d14e10e03afbd (diff)
downloadopencut-ad794fa43b472942f58af6d42dcecb1d358c5929.tar.gz
Merge branch 'timeline-zoom'
Diffstat (limited to 'apps/web/src/lib/timeline/zoom-utils.ts')
-rw-r--r--apps/web/src/lib/timeline/zoom-utils.ts33
1 files changed, 33 insertions, 0 deletions
diff --git a/apps/web/src/lib/timeline/zoom-utils.ts b/apps/web/src/lib/timeline/zoom-utils.ts
index 49f7fcb6..bbc0b6ae 100644
--- a/apps/web/src/lib/timeline/zoom-utils.ts
+++ b/apps/web/src/lib/timeline/zoom-utils.ts
@@ -51,3 +51,36 @@ export function getZoomPercent({
}): number {
return (zoomLevel - minZoom) / (TIMELINE_CONSTANTS.ZOOM_MAX - minZoom);
}
+
+/**
+ * convert linear slider position (0-1) to exponential zoom level.
+ * at low slider values, zoom changes are small. at high values, changes are large.
+ */
+export function sliderToZoom({
+ sliderPosition,
+ minZoom,
+ maxZoom = TIMELINE_CONSTANTS.ZOOM_MAX,
+}: {
+ sliderPosition: number;
+ minZoom: number;
+ maxZoom?: number;
+}): number {
+ const clampedPosition = Math.max(0, Math.min(1, sliderPosition));
+ return minZoom * (maxZoom / minZoom) ** clampedPosition;
+}
+
+/**
+ * convert exponential zoom level to linear slider position (0-1).
+ */
+export function zoomToSlider({
+ zoomLevel,
+ minZoom,
+ maxZoom = TIMELINE_CONSTANTS.ZOOM_MAX,
+}: {
+ zoomLevel: number;
+ minZoom: number;
+ maxZoom?: number;
+}): number {
+ const clampedZoom = Math.max(minZoom, Math.min(maxZoom, zoomLevel));
+ return Math.log(clampedZoom / minZoom) / Math.log(maxZoom / minZoom);
+}