summaryrefslogtreecommitdiff
path: root/apps/web/src/lib/timeline/zoom-utils.ts
diff options
context:
space:
mode:
Diffstat (limited to 'apps/web/src/lib/timeline/zoom-utils.ts')
-rw-r--r--apps/web/src/lib/timeline/zoom-utils.ts53
1 files changed, 53 insertions, 0 deletions
diff --git a/apps/web/src/lib/timeline/zoom-utils.ts b/apps/web/src/lib/timeline/zoom-utils.ts
new file mode 100644
index 00000000..49f7fcb6
--- /dev/null
+++ b/apps/web/src/lib/timeline/zoom-utils.ts
@@ -0,0 +1,53 @@
+import { TIMELINE_CONSTANTS } from "@/constants/timeline-constants";
+
+const PADDING_MAX_RATIO = 0.75;
+const PADDING_MIN_RATIO = 0.15;
+const PADDING_MIN_AT_ZOOM_PERCENT = 0.2;
+
+export function getTimelineZoomMin({
+ duration,
+ containerWidth,
+}: {
+ duration: number;
+ containerWidth: number | null | undefined;
+}): number {
+ const safeDuration = Math.max(duration, 1);
+ const safeContainerWidth = containerWidth ?? 1000;
+ const contentRatioAtMinZoom = 1 - PADDING_MAX_RATIO;
+ const availableWidth = safeContainerWidth * contentRatioAtMinZoom;
+ const zoomToFit =
+ availableWidth / (safeDuration * TIMELINE_CONSTANTS.PIXELS_PER_SECOND);
+
+ return Math.min(TIMELINE_CONSTANTS.ZOOM_MAX, zoomToFit);
+}
+
+export function getTimelinePaddingPx({
+ containerWidth,
+ zoomLevel,
+ minZoom,
+}: {
+ containerWidth: number;
+ zoomLevel: number;
+ minZoom: number;
+}): number {
+ const zoomPercent = getZoomPercent({ zoomLevel, minZoom });
+ const paddingTransitionPercent = Math.min(
+ zoomPercent / PADDING_MIN_AT_ZOOM_PERCENT,
+ 1,
+ );
+ const paddingRatio =
+ PADDING_MAX_RATIO -
+ (PADDING_MAX_RATIO - PADDING_MIN_RATIO) * paddingTransitionPercent;
+
+ return containerWidth * paddingRatio;
+}
+
+export function getZoomPercent({
+ zoomLevel,
+ minZoom,
+}: {
+ zoomLevel: number;
+ minZoom: number;
+}): number {
+ return (zoomLevel - minZoom) / (TIMELINE_CONSTANTS.ZOOM_MAX - minZoom);
+}