150 lines
3.0 KiB
TypeScript
150 lines
3.0 KiB
TypeScript
import type { Bookmark } from "@/lib/timeline";
|
|
import { roundToFrame } from "opencut-wasm";
|
|
|
|
export const BOOKMARK_TIME_EPSILON = 0.001;
|
|
|
|
function bookmarkTimeEqual({
|
|
bookmarkTime,
|
|
frameTime,
|
|
}: {
|
|
bookmarkTime: number;
|
|
frameTime: number;
|
|
}): boolean {
|
|
return Math.abs(bookmarkTime - frameTime) < BOOKMARK_TIME_EPSILON;
|
|
}
|
|
|
|
export function findBookmarkIndex({
|
|
bookmarks,
|
|
frameTime,
|
|
}: {
|
|
bookmarks: Bookmark[];
|
|
frameTime: number;
|
|
}): number {
|
|
return bookmarks.findIndex((bookmark) =>
|
|
bookmarkTimeEqual({ bookmarkTime: bookmark.time, frameTime }),
|
|
);
|
|
}
|
|
|
|
export function isBookmarkAtTime({
|
|
bookmarks,
|
|
frameTime,
|
|
}: {
|
|
bookmarks: Bookmark[];
|
|
frameTime: number;
|
|
}): boolean {
|
|
return bookmarks.some((bookmark) =>
|
|
bookmarkTimeEqual({ bookmarkTime: bookmark.time, frameTime }),
|
|
);
|
|
}
|
|
|
|
export function toggleBookmarkInArray({
|
|
bookmarks,
|
|
frameTime,
|
|
}: {
|
|
bookmarks: Bookmark[];
|
|
frameTime: number;
|
|
}): Bookmark[] {
|
|
const bookmarkIndex = findBookmarkIndex({ bookmarks, frameTime });
|
|
|
|
if (bookmarkIndex !== -1) {
|
|
return bookmarks.filter((_, index) => index !== bookmarkIndex);
|
|
}
|
|
|
|
const newBookmarks = [...bookmarks, { time: frameTime }];
|
|
return newBookmarks.slice().sort((a, b) => a.time - b.time);
|
|
}
|
|
|
|
export function removeBookmarkFromArray({
|
|
bookmarks,
|
|
frameTime,
|
|
}: {
|
|
bookmarks: Bookmark[];
|
|
frameTime: number;
|
|
}): Bookmark[] {
|
|
return bookmarks.filter(
|
|
(bookmark) =>
|
|
!bookmarkTimeEqual({ bookmarkTime: bookmark.time, frameTime }),
|
|
);
|
|
}
|
|
|
|
export function updateBookmarkInArray({
|
|
bookmarks,
|
|
frameTime,
|
|
updates,
|
|
}: {
|
|
bookmarks: Bookmark[];
|
|
frameTime: number;
|
|
updates: Partial<Omit<Bookmark, "time">>;
|
|
}): Bookmark[] {
|
|
const index = findBookmarkIndex({ bookmarks, frameTime });
|
|
if (index === -1) {
|
|
return bookmarks;
|
|
}
|
|
|
|
const updated = { ...bookmarks[index], ...updates };
|
|
const result = [...bookmarks];
|
|
result[index] = updated;
|
|
return result;
|
|
}
|
|
|
|
export function moveBookmarkInArray({
|
|
bookmarks,
|
|
fromTime,
|
|
toTime,
|
|
}: {
|
|
bookmarks: Bookmark[];
|
|
fromTime: number;
|
|
toTime: number;
|
|
}): Bookmark[] {
|
|
const index = findBookmarkIndex({ bookmarks, frameTime: fromTime });
|
|
if (index === -1) {
|
|
return bookmarks;
|
|
}
|
|
|
|
const updated = { ...bookmarks[index], time: toTime };
|
|
const result = [...bookmarks];
|
|
result[index] = updated;
|
|
return result.slice().sort((a, b) => a.time - b.time);
|
|
}
|
|
|
|
export function getFrameTime({
|
|
time,
|
|
fps,
|
|
}: {
|
|
time: number;
|
|
fps: number;
|
|
}): number {
|
|
return roundToFrame({ time, fps });
|
|
}
|
|
|
|
export function getBookmarkAtTime({
|
|
bookmarks,
|
|
frameTime,
|
|
}: {
|
|
bookmarks: Bookmark[];
|
|
frameTime: number;
|
|
}): Bookmark | null {
|
|
const index = findBookmarkIndex({ bookmarks, frameTime });
|
|
return index === -1 ? null : bookmarks[index];
|
|
}
|
|
|
|
export function getBookmarksActiveAtTime({
|
|
bookmarks,
|
|
time,
|
|
}: {
|
|
bookmarks: Bookmark[];
|
|
time: number;
|
|
}): Bookmark[] {
|
|
return bookmarks.filter((bookmark) => {
|
|
const start = bookmark.time;
|
|
const end =
|
|
bookmark.duration != null && bookmark.duration > 0
|
|
? start + bookmark.duration
|
|
: start;
|
|
return (
|
|
time >= start - BOOKMARK_TIME_EPSILON &&
|
|
time <= end + BOOKMARK_TIME_EPSILON
|
|
);
|
|
});
|
|
}
|