diff options
| author | Maze Winther <mazewinther@gmail.com> | 2026-03-01 01:32:09 +0100 |
|---|---|---|
| committer | Maze Winther <mazewinther@gmail.com> | 2026-03-01 01:32:09 +0100 |
| commit | 5e7c27f542e94ffee5d2106ce318b6f43cc7e738 (patch) | |
| tree | b33c3370c01b9b2ee685f1039543bc02f8764f7b /apps/web/src/lib/timeline/pixel-utils.ts | |
| parent | 744419469da403be57d30b5b19f6b43246caa57d (diff) | |
| parent | 354f4dec67ef7eb39d34fca941ca34025a68136b (diff) | |
| download | opencut-5e7c27f542e94ffee5d2106ce318b6f43cc7e738.tar.gz | |
Merge branch 'dev' into ripple-editing
Diffstat (limited to 'apps/web/src/lib/timeline/pixel-utils.ts')
| -rw-r--r-- | apps/web/src/lib/timeline/pixel-utils.ts | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/apps/web/src/lib/timeline/pixel-utils.ts b/apps/web/src/lib/timeline/pixel-utils.ts new file mode 100644 index 00000000..4c0c243c --- /dev/null +++ b/apps/web/src/lib/timeline/pixel-utils.ts @@ -0,0 +1,79 @@ +import { TIMELINE_CONSTANTS } from "@/constants/timeline-constants"; + +export const TIMELINE_INDICATOR_LINE_WIDTH_PX = 2; + +function getDevicePixelRatio({ + devicePixelRatio, +}: { + devicePixelRatio?: number; +}): number { + if ( + typeof devicePixelRatio === "number" && + Number.isFinite(devicePixelRatio) && + devicePixelRatio > 0 + ) { + return devicePixelRatio; + } + + if (typeof window === "undefined") { + return 1; + } + + if (Number.isFinite(window.devicePixelRatio) && window.devicePixelRatio > 0) { + return window.devicePixelRatio; + } + + return 1; +} + +export function getTimelinePixelsPerSecond({ + zoomLevel, +}: { + zoomLevel: number; +}): number { + return TIMELINE_CONSTANTS.PIXELS_PER_SECOND * zoomLevel; +} + +export function timelineTimeToPixels({ + time, + zoomLevel, +}: { + time: number; + zoomLevel: number; +}): number { + return time * getTimelinePixelsPerSecond({ zoomLevel }); +} + +export function snapPixelToDeviceGrid({ + pixel, + devicePixelRatio, +}: { + pixel: number; + devicePixelRatio?: number; +}): number { + const safeDevicePixelRatio = getDevicePixelRatio({ devicePixelRatio }); + return Math.round(pixel * safeDevicePixelRatio) / safeDevicePixelRatio; +} + +export function timelineTimeToSnappedPixels({ + time, + zoomLevel, + devicePixelRatio, +}: { + time: number; + zoomLevel: number; + devicePixelRatio?: number; +}): number { + const rawPixel = timelineTimeToPixels({ time, zoomLevel }); + return snapPixelToDeviceGrid({ pixel: rawPixel, devicePixelRatio }); +} + +export function getCenteredLineLeft({ + centerPixel, + lineWidthPx = TIMELINE_INDICATOR_LINE_WIDTH_PX, +}: { + centerPixel: number; + lineWidthPx?: number; +}): number { + return centerPixel - lineWidthPx / 2; +} |
