Skip to content

Commit

Permalink
feat: formattimefn and title for markers
Browse files Browse the repository at this point in the history
  • Loading branch information
smukkejohan committed Jan 24, 2024
1 parent 13e8ab7 commit 45e3b38
Show file tree
Hide file tree
Showing 10 changed files with 80 additions and 21 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
"@typescript-eslint/parser": "^6.19.0",
"autoprefixer": "^10.4.16",
"conventional-changelog-eslint": "^5.0.0",
"dayjs": "^1.11.10",
"dequal": "^2.0.3",
"eslint": "^8.56.0",
"eslint-config-prettier": "^9.1.0",
Expand Down
7 changes: 7 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/lib/Block.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export class Block implements ISequenceChild {
data?: {
[key: string]: unknown;
};
markers: { time: number; label: string }[] = [];
markers: { time: number; title?: string }[] = [];
errors: { type: string; message: string }[] = [];

private _inTime?: number;
Expand Down
2 changes: 1 addition & 1 deletion src/lib/components/Block.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@
{#if markers.length > 0}
<div class="tl-block-markers">
{#each markers as marker, index}
<BlockMarker time={marker.time} {index} disableSnapping={handle != null} {block}
<BlockMarker time={marker.time} title={marker.title} {index} disableSnapping={handle != null} {block}
></BlockMarker>
{/each}
</div>
Expand Down
12 changes: 10 additions & 2 deletions src/lib/components/BlockMarker.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,21 @@
export let time: number;
export let index: number;
export let title = `Marker #${index + 1}`;
export let disableSnapping = false;
export let block: Block;
export let tag = 'div';
const { duration, width, scrubOverride, time: playheadTime } = getSequenceContext();
const { duration, width, scrubOverride, time: playheadTime, formatTimeFn } = getSequenceContext();
//export let format = (value: number) => `${Math.round(value)}`;
export let formatTitle = () => {
return `${title} (+${formatTimeFn(time)})`;
};
$: timeToPixel = (1 / $duration) * $width;
$: absoluteTime = time + block.absoluteInTime;
Expand All @@ -25,7 +33,7 @@
>
<!-- Render transparent interactive marker above block content (block handle)-->
<div
title="marker #{index} at {time}"
title="{formatTitle()}"
class="tl-block-marker-interactive"
on:pointerdown
on:focus
Expand Down
7 changes: 5 additions & 2 deletions src/lib/components/Sequence.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,17 @@
const disabled = writable(false);
const snapTimes = writable([]);
export let formatTimeFn = (value: number) => `${Math.round(value)}`;
setSequenceContext({
time,
duration,
sequence: sequenceData,
width,
snapTimes,
selectedHandle,
scrubOverride
scrubOverride,
formatTimeFn
});
$: currentTime = $time;
Expand Down Expand Up @@ -84,7 +87,7 @@
>
<slot {currentTime} layers={$sequenceData.layers}>
<slot name="timebar">
<Timebar />
<Timebar {formatTimeFn} />
</slot>

<slot name="layers" {layers}>
Expand Down
1 change: 1 addition & 0 deletions src/lib/components/SequenceContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export type SequenceContext = {
snapTimes: Writable<number[]>;
scrubOverride: Writable<boolean>;
sequence: Writable<Sequence>;
formatTimeFn: (time: number) => string;
};

export const key = Symbol();
Expand Down
4 changes: 2 additions & 2 deletions src/lib/components/Timebar.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
import TimebarLabel from './TimebarLabel.svelte';
const { time, duration, scrubOverride, selectedHandle } = getSequenceContext();
const { time, duration, scrubOverride, selectedHandle, formatTimeFn: sequenceFormatTimeFn } = getSequenceContext();
export let formatTimeFn = (value: number) => `${Math.round(value)}`;
export let formatTimeFn = sequenceFormatTimeFn;
// We could instead have a store for timebarLabels that we loop over to allow showing n number of relevant times and control through context
let extraTime: number | null = null;
Expand Down
4 changes: 2 additions & 2 deletions src/lib/components/TimebarLabel.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
import { uniqueClasses } from '../utils';
import { getSequenceContext } from './SequenceContext';
const { duration, width } = getSequenceContext();
const { duration, width, formatTimeFn } = getSequenceContext();
export let formatFn = (value: number) => `${Math.round(value)}`;
export let formatFn = formatTimeFn;
export let time: number;
let pos: number;
Expand Down
61 changes: 50 additions & 11 deletions src/routes/examples/markers/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
import CustomLayer from './CustomLayer.svelte';
import { Label, Input } from 'flowbite-svelte';
import dayjs from 'dayjs';
import dayjsDuration from 'dayjs/plugin/duration';
dayjs.extend(dayjsDuration);
const PromoterBlockTemplate = {
key: 'promoter',
type: 'promoter',
Expand Down Expand Up @@ -32,43 +36,40 @@
markers: [
{
time: 1000,
label: 'scene 1'
title: 'scene 1'
},
{
time: 1050,
label: 'scene 2'
title: 'scene 2'
},
{
time: 300,
label: 'scene 3'
},
{
time: 4000,
label: 'scene 4'
},
{
time: 5000,
label: 'scene 5'
},
{
time: 6000,
label: 'scene 6'
title: 'scene 6'
},
{
time: 7000,
label: 'scene 7'
title: 'scene 7'
},
{
time: 8000,
label: 'scene 8'
title: 'scene 8'
},
{
time: 9000,
label: 'scene 9'
title: 'scene 9'
},
{
time: 10000,
label: 'scene 10'
title: 'scene 10'
}
]
}
Expand Down Expand Up @@ -181,6 +182,44 @@
/*
TODO: toggle snapping
*/
const millisInSecond = 1000;
const millisInFrame = (framerate: number) => {
return (1 / framerate) * millisInSecond;
};
type formatTimeOptions = {
framerate?: number;
format?: string;
};
const formatTimeFn = (time: number, options?: formatTimeOptions) => {
if (time === undefined || time === null) {
return '';
}
time = Math.floor(time);
let format = options?.format ?? 'HH:mm:ss.SSS';
const framerate = options?.framerate ?? 25;
const duration = dayjs.duration(time, 'milliseconds');
if (format.includes('FF')) {
// calculate remaining frames after smallest unit in format string
const millis = duration.milliseconds();
const frames = Math.floor(millis / millisInFrame(framerate));
format = format.replace('FF', `${frames}`.padStart(2, '0'));
}
if (format.includes('R')) {
format = format.replace('R', `${framerate}`);
}
return `${duration.format(format)}`;
};
</script>

<section class="pb-6">
Expand Down Expand Up @@ -219,11 +258,11 @@
<Sequence
{sequence}
bind:currentTime={$time}
formatTimeFn={formatTimeFn}
class="mb-4 w-full dark:border-gray-700 dark:bg-gray-800"
>
<SequenceTimebar
slot="timebar"
formatTimeFn={(value) => `${value}`}
class="dark:bg-gray-900"
/>

Expand Down

0 comments on commit 45e3b38

Please sign in to comment.