diff --git a/packages/timeline/src/components/cells/Cell.tsx b/packages/timeline/src/components/cells/Cell.tsx
index b5171aa4..43f8e09a 100644
--- a/packages/timeline/src/components/cells/Cell.tsx
+++ b/packages/timeline/src/components/cells/Cell.tsx
@@ -1,4 +1,4 @@
-import { Suspense } from "react"
+import { Suspense, useMemo } from "react"
import { a } from "@react-spring/three"
import { ClapSegmentCategory } from "@aitube/clap"
@@ -17,6 +17,8 @@ import { useThree } from "@react-three/fiber"
import { SegmentArea } from "@/types/timeline"
import { SegmentIcon } from "../icons/SegmentIcon"
+import { getSegmentColorScheme } from "@/utils/getSegmentColorScheme"
+
export function Cell({
segment: s
}: {
@@ -31,8 +33,7 @@ export function Cell({
// this is only used to react to changes in the segment
const segmentChanged = useSegmentChanges(s)
- const getSegmentColorScheme = useTimeline(s => s.getSegmentColorScheme)
- const colorScheme = getSegmentColorScheme(s)
+ const colorScheme = useMemo(() => getSegmentColorScheme(s), [segmentChanged])
const cellWidth = useTimeline((s) => s.cellWidth)
const getCellHeight = useTimeline((s) => s.getCellHeight)
diff --git a/packages/timeline/src/components/scroller/HorizontalScroller.tsx b/packages/timeline/src/components/scroller/HorizontalScroller.tsx
index 919f4df7..ca35ed1a 100644
--- a/packages/timeline/src/components/scroller/HorizontalScroller.tsx
+++ b/packages/timeline/src/components/scroller/HorizontalScroller.tsx
@@ -1,12 +1,20 @@
+import { useMemo } from "react"
+
import { useTimeline } from "@/hooks/useTimeline"
+import { getSegmentColorScheme } from "@/utils/getSegmentColorScheme"
+
import TimelineSlider from "../slider/TimelineSlider"
export function HorizontalScroller() {
const theme = useTimeline(s => s.theme)
+ const containerWidth = useTimeline(s => s.containerWidth)
+
const segments = useTimeline(s => s.segments)
+ const atLeastOneSegmentChanged = useTimeline(s => s.atLeastOneSegmentChanged)
+
const timelineCamera = useTimeline(s => s.timelineCamera)
const timelineControls = useTimeline(s => s.timelineControls)
@@ -26,33 +34,17 @@ export function HorizontalScroller() {
const setScrollX = useTimeline(s => s.setScrollX)
const contentWidth = useTimeline(s => s.contentWidth)
- const getSegmentColorScheme = useTimeline(s => s.getSegmentColorScheme)
-
+ const cachedSegments = useMemo(() => segments, [atLeastOneSegmentChanged, containerWidth, contentWidth])
+
if (!timelineCamera || !timelineControls) { return null }
+ // TODO: we need to be able to change the zoom level from the horizontal scroller
const handleZoomChange = (newZoom: number) => {
setHorizontalZoomLevel(newZoom)
}
return (
- {/*
- PREVIOUS COMPONENT, NOW OBSOLETE:
- {
- handleTimelinePositionChange(newRange[0])
- }}
- onWheel={(e) => {
- // handleZoomChange(cellWidth + e.deltaY)
- }}
- />
- */}
-
({
- id: s.id,
- track: s.track,
- startTimeInMs: s.startTimeInMs,
- endTimeInMs: s.endTimeInMs,
- color: getSegmentColorScheme(s).backgroundColor,
- }))}
- eventOpacityWhenInsideSlidingWindowRangeThumb={1.0}
- eventOpacityWhenOutsideSlidingWindowRangeThumb={0.7}
+ segments={cachedSegments}
+ segmentOpacityWhenInsideSlidingWindowRangeThumb={1.0}
+ segmentOpacityWhenOutsideSlidingWindowRangeThumb={0.7}
onSlidingWindowRangeThumbUpdate={({
slidingWindowRangeThumbStartTimeInMs,
slidingWindowRangeThumbEndTimeInMs
diff --git a/packages/timeline/src/components/slider/TimelineSlider.tsx b/packages/timeline/src/components/slider/TimelineSlider.tsx
index b49db488..dab627a3 100644
--- a/packages/timeline/src/components/slider/TimelineSlider.tsx
+++ b/packages/timeline/src/components/slider/TimelineSlider.tsx
@@ -1,14 +1,6 @@
-import { useTimeline } from '@/index';
+import { TimelineSegment, useTimeline } from '@/index';
import React, { useRef, useEffect, useState, useCallback, useMemo } from 'react';
-export interface TimelineSliderEvent {
- id: string;
- track: number;
- startTimeInMs: number;
- endTimeInMs: number;
- color: string;
-}
-
export interface TimelineSliderProps {
minTimeInMs: number;
maxTimeInMs: number;
@@ -25,9 +17,9 @@ export interface TimelineSliderProps {
slidingWindowRangeThumbBorderRadiusInPx: number;
slidingWindowRangeThumbBackgroundColor: string;
className: string;
- events?: TimelineSliderEvent[];
- eventOpacityWhenInsideSlidingWindowRangeThumb: number;
- eventOpacityWhenOutsideSlidingWindowRangeThumb: number;
+ segments?: TimelineSegment[];
+ segmentOpacityWhenInsideSlidingWindowRangeThumb: number;
+ segmentOpacityWhenOutsideSlidingWindowRangeThumb: number;
onSlidingWindowRangeThumbUpdate: (update: {
slidingWindowRangeThumbStartTimeInMs: number;
slidingWindowRangeThumbEndTimeInMs: number;
@@ -62,9 +54,9 @@ const TimelineSlider: React.FC = ({
slidingWindowRangeThumbBorderRadiusInPx,
slidingWindowRangeThumbBackgroundColor,
className,
- events = [],
- eventOpacityWhenInsideSlidingWindowRangeThumb,
- eventOpacityWhenOutsideSlidingWindowRangeThumb,
+ segments = [],
+ segmentOpacityWhenInsideSlidingWindowRangeThumb,
+ segmentOpacityWhenOutsideSlidingWindowRangeThumb,
onSlidingWindowRangeThumbUpdate,
onPlaybackCursorUpdate,
}) => {
@@ -90,25 +82,25 @@ const TimelineSlider: React.FC = ({
ctx.clearRect(0, 0, width * dpr, height * dpr);
- const totalTracks = Math.max(...events.map(e => e.track), 0) + 1;
+ const totalTracks = Math.max(...segments.map(e => e.track), 0) + 1;
const trackHeight = height / totalTracks;
- events.forEach(event => {
- const startX = ((event.startTimeInMs - minTimeInMs) / (maxTimeInMs - minTimeInMs)) * width;
- const endX = ((event.endTimeInMs - minTimeInMs) / (maxTimeInMs - minTimeInMs)) * width;
- const y = event.track * trackHeight;
+ segments.forEach(segment => {
+ const startX = ((segment.startTimeInMs - minTimeInMs) / (maxTimeInMs - minTimeInMs)) * width;
+ const endX = ((segment.endTimeInMs - minTimeInMs) / (maxTimeInMs - minTimeInMs)) * width;
+ const y = segment.track * trackHeight;
- ctx.fillStyle = event.color;
+ ctx.fillStyle = segment.colors.backgroundColor;
ctx.globalAlpha =
- (event.startTimeInMs >= windowStart && event.endTimeInMs <= windowEnd)
- ? eventOpacityWhenInsideSlidingWindowRangeThumb
- : eventOpacityWhenOutsideSlidingWindowRangeThumb;
+ (segment.startTimeInMs >= windowStart && segment.endTimeInMs <= windowEnd)
+ ? segmentOpacityWhenInsideSlidingWindowRangeThumb
+ : segmentOpacityWhenOutsideSlidingWindowRangeThumb;
ctx.fillRect(startX, y, endX - startX, trackHeight);
});
- }, [events, minTimeInMs, maxTimeInMs, windowStart, windowEnd, eventOpacityWhenInsideSlidingWindowRangeThumb, eventOpacityWhenOutsideSlidingWindowRangeThumb]);
+ }, [segments, minTimeInMs, maxTimeInMs, windowStart, windowEnd, segmentOpacityWhenInsideSlidingWindowRangeThumb, segmentOpacityWhenOutsideSlidingWindowRangeThumb]);
- const memoizedEvents = useMemo(() => events, [events]);
+ const memoizedEvents = useMemo(() => segments, [segments]);
const setCanvasSize = useCallback(() => {
const canvas = canvasRef.current;
diff --git a/packages/timeline/src/components/timeline/TopBarTimeScale.tsx b/packages/timeline/src/components/timeline/TopBarTimeScale.tsx
index 2fec0c2a..f2fbccb2 100644
--- a/packages/timeline/src/components/timeline/TopBarTimeScale.tsx
+++ b/packages/timeline/src/components/timeline/TopBarTimeScale.tsx
@@ -1,21 +1,19 @@
import React, { useEffect, useMemo, useRef } from "react"
-
+import { useThree } from "@react-three/fiber"
import { Plane, Text } from "@react-three/drei"
-import {
-useTimeline
-} from "@/hooks"
-
+import { useTimeline } from "@/hooks"
import { useTimeScaleGraduations } from "@/hooks/useTimeScaleGraduations"
import { formatTimestamp } from "@/utils/formatTimestamp"
import { leftBarTrackScaleWidth, topBarTimeScaleHeight } from "@/constants/themes"
-import { useThree } from "@react-three/fiber"
export function TopBarTimeScale() {
const containerRef = useRef(null);
- const { size } = useThree()
+ const containerWidth = useTimeline(s => s.containerWidth)
+
+ const { size, camera } = useThree()
const jumpAt = useTimeline(s => s.jumpAt)
const togglePlayback = useTimeline(s => s.togglePlayback)
@@ -153,7 +151,26 @@ export function TopBarTimeScale() {
))}
- {timeScaleGraduations.filter((_, idx) => (idx * cellWidth) < maxWidth).map((lineGeometry, idx) => (
+ {timeScaleGraduations
+ .filter((_, idx) => (idx * cellWidth) < maxWidth)
+ .map((lineGeometry, idx) => {
+
+ if (
+ // Hide text if it's too close to others or out of view
+ (cellWidth <= 4 && idx % 10 !== 0) ||
+ (cellWidth <= 40 && idx % unit !== 0) ||
+ idx === 0 // Always hide the 0
+
+ // TODO: those need more work
+ // ||
+ // (idx * cellWidth) < camera.position.x - size.width / 2 - cellWidth || // Out of view on the left
+ // (idx * cellWidth) > camera.position.x + size.width / 2 + cellWidth // Out of view on the right
+ ) {
+ return null
+ }
+
+
+ return (
{
formatTimestamp(
@@ -204,7 +223,8 @@ export function TopBarTimeScale() {
milliseconds: cellWidth > 20,
})}
- ))}
+ )
+ }).filter(x => x)}
>
), [
@@ -215,6 +235,7 @@ export function TopBarTimeScale() {
contentWidth,
cellWidth,
unit,
+ containerWidth,
formatTimestamp,
theme.topBarTimeScale.backgroundColor,
theme.topBarTimeScale.lineColor,
@@ -236,9 +257,10 @@ export function TopBarTimeScale() {
const disableWheel = true
if (disableWheel) {
- console.log(`user tried to change the horizontal scale, but it is disabled due to rescaling bugs (@Julian fix this!)`)
- e.stopPropagation()
- return false
+ console.log(
+ `zoom in/out is currently disabled, we need to update the min and max values and check other redrawing routines (see https://github.com/jbilcke-hf/clapper/issues/47)`)
+ e.stopPropagation()
+ return false
}
const wheelFactor = 0.3
diff --git a/packages/timeline/src/demo.tsx b/packages/timeline/src/demo.tsx
index 93ed27da..19b9b6f3 100644
--- a/packages/timeline/src/demo.tsx
+++ b/packages/timeline/src/demo.tsx
@@ -49,6 +49,21 @@ const segment: TimelineSegment = {
isGrabbedOnLeftHandle: false,
isGrabbedOnRightHandle: false,
editionStatus: SegmentEditionStatus.EDITABLE,
+ colors: {
+ baseHue: 0,
+ baseSaturation: 0,
+ baseLightness: 0,
+ backgroundColor: '',
+ backgroundColorHover: '',
+ backgroundColorDisabled: '',
+ foregroundColor: '',
+ borderColor: '',
+ textColor: '',
+ textColorHover: '',
+ waveformLineSpacing: 0,
+ waveformGradientStart: 0,
+ waveformGradientEnd: 0
+ },
}
useTimeline.setState({
diff --git a/packages/timeline/src/hooks/useTimeScaleGraduations.ts b/packages/timeline/src/hooks/useTimeScaleGraduations.ts
index 5344fe7f..c724c2fb 100644
--- a/packages/timeline/src/hooks/useTimeScaleGraduations.ts
+++ b/packages/timeline/src/hooks/useTimeScaleGraduations.ts
@@ -15,6 +15,7 @@ export const useTimeScaleGraduations = ({
}: {
unit: number
}) => {
+ const containerWidth = useTimeline(s => s.containerWidth)
const cellWidth = useTimeline(s => s.cellWidth)
const nbMaxShots = useTimeline(s => s.nbMaxShots)
const contentWidth = useTimeline((s) => s.contentWidth)
diff --git a/packages/timeline/src/hooks/useTimeline.ts b/packages/timeline/src/hooks/useTimeline.ts
index d2ae784f..5a731b2b 100644
--- a/packages/timeline/src/hooks/useTimeline.ts
+++ b/packages/timeline/src/hooks/useTimeline.ts
@@ -336,68 +336,6 @@ export const useTimeline = create((set, get) => ({
}
return height
},
-
- getSegmentColorScheme: (segment: TimelineSegment): ClapSegmentColorScheme => {
-
- const { theme } = get()
-
- let baseHue = 0
-
- let baseSaturation = theme.cell.categoryColors.GENERIC.saturation
- let baseLightness = theme.cell.categoryColors.GENERIC.lightness
-
- let backgroundColorSaturation = (segment.isSelected ? 2.2 : 1.4) * baseSaturation
- let backgroundColorHoverSaturation = (segment.isSelected ? 2.2 : 1.8) * baseSaturation
-
- let colorScheme: ClapSegmentColorScheme = {
- baseHue,
- baseSaturation,
- baseLightness,
-
- backgroundColor: hslToHex(baseHue, backgroundColorSaturation, baseLightness),
- backgroundColorHover: hslToHex(baseHue, backgroundColorHoverSaturation, baseLightness + 1),
- backgroundColorDisabled: hslToHex(baseHue, baseSaturation - 15, baseLightness - 2),
- foregroundColor: hslToHex(baseHue, baseSaturation + 40, baseLightness),
- borderColor: hslToHex(baseHue, baseSaturation + 40, baseLightness + 10),
- textColor: hslToHex(baseHue, baseSaturation + 55, baseLightness - 60),
- textColorHover: hslToHex(baseHue, baseSaturation + 55, baseLightness - 50),
-
- waveformLineSpacing: theme.cell.waveform.lineSpacing,
- waveformGradientStart: theme.cell.waveform.gradientStart,
- waveformGradientEnd: theme.cell.waveform.gradientEnd,
- }
-
- if (!segment) { return colorScheme }
-
- const clapSegmentCategoryColors: ClapSegmentCategoryColors = theme.cell.categoryColors
-
- const candidateHSL = clapSegmentCategoryColors[segment.category]
- if (!candidateHSL) { return colorScheme }
-
- baseHue = candidateHSL.hue
- baseSaturation = candidateHSL.saturation
- baseLightness = candidateHSL.lightness
-
- colorScheme = {
- baseHue,
- baseSaturation,
- baseLightness,
-
- backgroundColor: hslToHex(baseHue, backgroundColorSaturation, baseLightness),
- backgroundColorHover: hslToHex(baseHue, backgroundColorHoverSaturation, baseLightness + 1),
- backgroundColorDisabled: hslToHex(baseHue, baseSaturation - 15, baseLightness - 2),
- foregroundColor: hslToHex(baseHue, baseSaturation + 40, baseLightness),
- borderColor: hslToHex(baseHue, baseSaturation + 40, baseLightness + 10),
- textColor: hslToHex(baseHue, baseSaturation + 55, baseLightness - 60),
- textColorHover: hslToHex(baseHue, baseSaturation + 55, baseLightness - 50),
-
- waveformLineSpacing: theme.cell.waveform.lineSpacing,
- waveformGradientStart: theme.cell.waveform.gradientStart,
- waveformGradientEnd: theme.cell.waveform.gradientEnd,
- }
-
- return colorScheme
- },
setHoveredSegment: ({
hoveredSegment,
area,
diff --git a/packages/timeline/src/types/timeline.ts b/packages/timeline/src/types/timeline.ts
index cffff195..44f63590 100644
--- a/packages/timeline/src/types/timeline.ts
+++ b/packages/timeline/src/types/timeline.ts
@@ -69,6 +69,10 @@ export type BrowserOnlySegmentData = {
// Cache for textures
textures: Record
+ // pre-computed color scheme
+ // (I've added this cache after doing perf analysis)
+ colors: ClapSegmentColorScheme
+
/**
* the following fields have been added to this type only very recently
* and their implementation is not finished,
@@ -264,7 +268,6 @@ export type TimelineStoreModifiers = {
setVisibleSegments: (visibleSegments?: TimelineSegment[]) => void
getCellHeight: (trackNumber?: number) => number
getVerticalCellPosition: (start: number, end: number) => number
- getSegmentColorScheme: (segment: TimelineSegment) => ClapSegmentColorScheme
setHoveredSegment: (params?: {
hoveredSegment?: TimelineSegment
area?: SegmentArea
diff --git a/packages/timeline/src/utils/clapSegmentToTimelineSegment.ts b/packages/timeline/src/utils/clapSegmentToTimelineSegment.ts
index 20e9e29b..b90181fe 100644
--- a/packages/timeline/src/utils/clapSegmentToTimelineSegment.ts
+++ b/packages/timeline/src/utils/clapSegmentToTimelineSegment.ts
@@ -2,6 +2,7 @@ import { ClapOutputType, ClapSegment } from "@aitube/clap"
import { SegmentEditionStatus, SegmentVisibility, TimelineSegment } from "@/types"
import { getAudioBuffer } from "./getAudioBuffer"
+import { getSegmentColorScheme } from "./getSegmentColorScheme"
export async function clapSegmentToTimelineSegment(clapSegment: ClapSegment): Promise {
@@ -33,6 +34,7 @@ export async function clapSegmentToTimelineSegment(clapSegment: ClapSegment): Pr
if (!segment.editionStatus) { segment.editionStatus = SegmentEditionStatus.EDITABLE }
+ segment.colors = getSegmentColorScheme(segment)
if (!segment.audioBuffer) {
if (segment.outputType === ClapOutputType.AUDIO) {
diff --git a/packages/timeline/src/utils/getSegmentColorScheme.ts b/packages/timeline/src/utils/getSegmentColorScheme.ts
new file mode 100644
index 00000000..a3bfc663
--- /dev/null
+++ b/packages/timeline/src/utils/getSegmentColorScheme.ts
@@ -0,0 +1,67 @@
+import { ClapSegmentCategoryColors, ClapSegmentColorScheme } from "@/types/theme"
+import { hslToHex } from "./hslToHex"
+import { TimelineSegment, useTimeline } from ".."
+
+// TODO: optimize this to not re-compute thing that didn't change much
+
+export function getSegmentColorScheme(segment: TimelineSegment): ClapSegmentColorScheme {
+
+ const { theme } = useTimeline.getState()
+
+ let baseHue = 0
+
+ let baseSaturation = theme.cell.categoryColors.GENERIC.saturation
+ let baseLightness = theme.cell.categoryColors.GENERIC.lightness
+
+ let backgroundColorSaturation = (segment.isSelected ? 2.2 : 1.4) * baseSaturation
+ let backgroundColorHoverSaturation = (segment.isSelected ? 2.2 : 1.8) * baseSaturation
+
+ let colorScheme: ClapSegmentColorScheme = {
+ baseHue,
+ baseSaturation,
+ baseLightness,
+
+ backgroundColor: hslToHex(baseHue, backgroundColorSaturation, baseLightness),
+ backgroundColorHover: hslToHex(baseHue, backgroundColorHoverSaturation, baseLightness + 1),
+ backgroundColorDisabled: hslToHex(baseHue, baseSaturation - 15, baseLightness - 2),
+ foregroundColor: hslToHex(baseHue, baseSaturation + 40, baseLightness),
+ borderColor: hslToHex(baseHue, baseSaturation + 40, baseLightness + 10),
+ textColor: hslToHex(baseHue, baseSaturation + 55, baseLightness - 60),
+ textColorHover: hslToHex(baseHue, baseSaturation + 55, baseLightness - 50),
+
+ waveformLineSpacing: theme.cell.waveform.lineSpacing,
+ waveformGradientStart: theme.cell.waveform.gradientStart,
+ waveformGradientEnd: theme.cell.waveform.gradientEnd,
+ }
+
+ if (!segment) { return colorScheme }
+
+ const clapSegmentCategoryColors: ClapSegmentCategoryColors = theme.cell.categoryColors
+
+ const candidateHSL = clapSegmentCategoryColors[segment.category]
+ if (!candidateHSL) { return colorScheme }
+
+ baseHue = candidateHSL.hue
+ baseSaturation = candidateHSL.saturation
+ baseLightness = candidateHSL.lightness
+
+ colorScheme = {
+ baseHue,
+ baseSaturation,
+ baseLightness,
+
+ backgroundColor: hslToHex(baseHue, backgroundColorSaturation, baseLightness),
+ backgroundColorHover: hslToHex(baseHue, backgroundColorHoverSaturation, baseLightness + 1),
+ backgroundColorDisabled: hslToHex(baseHue, baseSaturation - 15, baseLightness - 2),
+ foregroundColor: hslToHex(baseHue, baseSaturation + 40, baseLightness),
+ borderColor: hslToHex(baseHue, baseSaturation + 40, baseLightness + 10),
+ textColor: hslToHex(baseHue, baseSaturation + 55, baseLightness - 60),
+ textColorHover: hslToHex(baseHue, baseSaturation + 55, baseLightness - 50),
+
+ waveformLineSpacing: theme.cell.waveform.lineSpacing,
+ waveformGradientStart: theme.cell.waveform.gradientStart,
+ waveformGradientEnd: theme.cell.waveform.gradientEnd,
+ }
+
+ return colorScheme
+}
\ No newline at end of file
diff --git a/packages/timeline/src/utils/hslToHex.ts b/packages/timeline/src/utils/hslToHex.ts
index facd8868..cb960c02 100644
--- a/packages/timeline/src/utils/hslToHex.ts
+++ b/packages/timeline/src/utils/hslToHex.ts
@@ -1,4 +1,41 @@
+const hue2rgb = (p: number, q: number, t: number) => {
+ if (t < 0) t += 1;
+ if (t > 1) t -= 1;
+ if (t < 1 / 6) return p + (q - p) * 6 * t;
+ if (t < 1 / 2) return q;
+ if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
+ return p;
+};
+
+// Cache for toHex function
+const toHexCache = new Map();
+const MAX_CACHE_SIZE = 10000; // Adjust this value based on your memory constraints
+
+const toHex = (x: number) => {
+ const key = Math.round(x * 255);
+ if (toHexCache.has(key)) {
+ return toHexCache.get(key)!;
+ }
+ const hex = key.toString(16).padStart(2, '0');
+ if (toHexCache.size >= MAX_CACHE_SIZE) {
+ // If cache is full, remove the oldest entry
+ const firstKey: any = toHexCache.keys().next().value;
+ toHexCache.delete(firstKey);
+ }
+ toHexCache.set(key, hex);
+ return hex;
+};
+
+// Cache for hslToHex function
+const hslToHexCache = new Map();
+const MAX_HSL_CACHE_SIZE = 10000; // Adjust this value based on your memory constraints
+
export function hslToHex(h: number, s: number, l: number): string {
+ const key = `${h},${s},${l}`;
+ if (hslToHexCache.has(key)) {
+ return hslToHexCache.get(key)!;
+ }
+
h /= 360;
s /= 100;
l /= 100;
@@ -6,23 +43,19 @@ export function hslToHex(h: number, s: number, l: number): string {
if (s === 0) {
r = g = b = l; // achromatic
} else {
- const hue2rgb = (p: number, q: number, t: number) => {
- if (t < 0) t += 1;
- if (t > 1) t -= 1;
- if (t < 1 / 6) return p + (q - p) * 6 * t;
- if (t < 1 / 2) return q;
- if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
- return p;
- };
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
const p = 2 * l - q;
r = hue2rgb(p, q, h + 1 / 3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1 / 3);
}
- const toHex = (x: number) => {
- const hex = Math.round(x * 255).toString(16);
- return hex.length === 1 ? '0' + hex : hex;
- };
- return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
+ const result = `#${toHex(r)}${toHex(g)}${toHex(b)}`;
+
+ if (hslToHexCache.size >= MAX_HSL_CACHE_SIZE) {
+ // If cache is full, remove the oldest entry
+ const firstKey: any = hslToHexCache.keys().next().value;
+ hslToHexCache.delete(firstKey);
+ }
+ hslToHexCache.set(key, result);
+ return result;
}
\ No newline at end of file
diff --git a/packages/timeline/src/utils/timelineSegmentToClapSegment.ts b/packages/timeline/src/utils/timelineSegmentToClapSegment.ts
index 695c4a79..a4470d85 100644
--- a/packages/timeline/src/utils/timelineSegmentToClapSegment.ts
+++ b/packages/timeline/src/utils/timelineSegmentToClapSegment.ts
@@ -26,5 +26,7 @@ export function timelineSegmentToClapSegment(timelineSegment: TimelineSegment):
delete segment.isPlaying
delete segment.editionStatus
+ delete segment.colors
+
return segment as ClapSegment
}
\ No newline at end of file