@waveform-playlist/ui-components 12.0.0 → 13.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +32 -15
- package/dist/index.d.ts +32 -15
- package/dist/index.js +42 -49
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +42 -49
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.d.mts
CHANGED
|
@@ -353,8 +353,20 @@ interface PlayheadProps {
|
|
|
353
353
|
controlsOffset?: number;
|
|
354
354
|
/** Function to get current audio context time - required for smooth animation */
|
|
355
355
|
getAudioContextTime?: () => number;
|
|
356
|
-
/**
|
|
356
|
+
/**
|
|
357
|
+
* Returns raw playback time from the engine (auto-wraps at loop boundaries).
|
|
358
|
+
* This is the scheduling position — for playhead display use `visualTimeRef`
|
|
359
|
+
* which already has `outputLatency` and `lookAhead` subtracted.
|
|
360
|
+
*/
|
|
357
361
|
getPlaybackTime?: () => number;
|
|
362
|
+
/**
|
|
363
|
+
* Ref to the visually-aligned playback time (raw time minus `outputLatency`
|
|
364
|
+
* and `engine.lookAhead`), kept current by the provider's animation loop
|
|
365
|
+
* during playback and by pause/stop/seek paths when stopped. Use this for
|
|
366
|
+
* playhead positioning so it lines up with audible output and matches the
|
|
367
|
+
* progress fill in `ChannelWithProgress`.
|
|
368
|
+
*/
|
|
369
|
+
visualTimeRef?: react__default.RefObject<number>;
|
|
358
370
|
}
|
|
359
371
|
/**
|
|
360
372
|
* Type for custom playhead render functions.
|
|
@@ -468,9 +480,14 @@ interface SelectionTimeInputsProps {
|
|
|
468
480
|
}
|
|
469
481
|
declare const SelectionTimeInputs: react__default.FC<SelectionTimeInputsProps>;
|
|
470
482
|
|
|
471
|
-
interface
|
|
472
|
-
|
|
473
|
-
|
|
483
|
+
interface SpectrogramCanvasRegistration {
|
|
484
|
+
canvasId: string;
|
|
485
|
+
canvas: OffscreenCanvas;
|
|
486
|
+
clipId: string;
|
|
487
|
+
channelIndex: number;
|
|
488
|
+
chunkIndex: number;
|
|
489
|
+
widthPx: number;
|
|
490
|
+
heightPx: number;
|
|
474
491
|
}
|
|
475
492
|
interface SpectrogramChannelProps {
|
|
476
493
|
/** Visual position index — used for CSS positioning (top offset). */
|
|
@@ -485,12 +502,12 @@ interface SpectrogramChannelProps {
|
|
|
485
502
|
devicePixelRatio?: number;
|
|
486
503
|
/** Samples per pixel at current zoom level */
|
|
487
504
|
samplesPerPixel: number;
|
|
488
|
-
/**
|
|
489
|
-
workerApi: SpectrogramWorkerCanvasApi;
|
|
490
|
-
/** Clip ID used to construct unique canvas IDs for worker registration */
|
|
505
|
+
/** Clip ID used to construct unique canvas IDs */
|
|
491
506
|
clipId: string;
|
|
492
|
-
/**
|
|
493
|
-
|
|
507
|
+
/** Single-call canvas registration. Receives the transferred OffscreenCanvas + metadata. */
|
|
508
|
+
onCanvasRegister: (reg: SpectrogramCanvasRegistration) => void;
|
|
509
|
+
/** Counterpart for chunk unmount / component unmount. */
|
|
510
|
+
onCanvasUnregister: (canvasId: string) => void;
|
|
494
511
|
}
|
|
495
512
|
declare const SpectrogramChannel: FunctionComponent<SpectrogramChannelProps>;
|
|
496
513
|
|
|
@@ -507,12 +524,12 @@ interface SmartChannelProps {
|
|
|
507
524
|
renderMode?: RenderMode;
|
|
508
525
|
/** Samples per pixel at current zoom level */
|
|
509
526
|
samplesPerPixel?: number;
|
|
510
|
-
/**
|
|
511
|
-
spectrogramWorkerApi?: SpectrogramWorkerCanvasApi;
|
|
512
|
-
/** Clip ID for worker canvas registration */
|
|
527
|
+
/** Clip ID for spectrogram canvas registration */
|
|
513
528
|
spectrogramClipId?: string;
|
|
514
|
-
/**
|
|
515
|
-
|
|
529
|
+
/** Single-call registration for spectrogram canvases (from SpectrogramIntegration). */
|
|
530
|
+
spectrogramOnCanvasRegister?: (reg: SpectrogramCanvasRegistration) => void;
|
|
531
|
+
/** Counterpart for chunk unmount / unmount. */
|
|
532
|
+
spectrogramOnCanvasUnregister?: (canvasId: string) => void;
|
|
516
533
|
/** MIDI note data for piano-roll rendering */
|
|
517
534
|
midiNotes?: MidiNoteData[];
|
|
518
535
|
/** Sample rate for MIDI note time → pixel conversion */
|
|
@@ -921,4 +938,4 @@ declare const BaseSlider: styled_components_dist_types.IStyledComponentBase<"web
|
|
|
921
938
|
ref?: ((instance: HTMLInputElement | null) => void | react.DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES[keyof react.DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES]) | react.RefObject<HTMLInputElement> | null | undefined;
|
|
922
939
|
}>, never>, never>> & string;
|
|
923
940
|
|
|
924
|
-
export { AudioPosition, type AudioPositionProps, AutomaticScrollCheckbox, type AutomaticScrollCheckboxProps, BaseButton, BaseCheckbox, BaseCheckboxLabel, BaseCheckboxWrapper, BaseControlButton, BaseInput, BaseInputSmall, BaseLabel, BaseSelect, BaseSelectSmall, BaseSlider, type BeatsAndBarsContextValue, BeatsAndBarsProvider, type BeatsAndBarsProviderProps, Button, ButtonGroup, CLIP_BOUNDARY_WIDTH, CLIP_BOUNDARY_WIDTH_TOUCH, CLIP_HEADER_HEIGHT, Channel, type ChannelProps, Clip, ClipBoundary, type ClipBoundaryProps, ClipHeader, ClipHeaderPresentational, type ClipHeaderPresentationalProps, type ClipHeaderProps, type ClipProps, ClipViewportOriginProvider, CloseButton, type ColorStop, Controls$1 as Controls, DevicePixelRatioProvider, DotsIcon, type DragHandleProps, FadeOverlay, type FadeOverlayProps, type GradientStop, Header, InlineLabel, LoopRegion, LoopRegionMarkers, type LoopRegionMarkersProps, type LoopRegionProps, MasterVolumeControl, type MasterVolumeControlProps, PianoRollChannel, type PianoRollChannelProps, Playhead, type PlayheadProps, PlayheadWithMarker, Playlist, PlaylistErrorBoundary, type PlaylistErrorBoundaryProps, PlaylistInfoContext, type PlaylistProps, PlayoutProvider, type PrecomputedTickData, type RenderPlayheadFunction, type ScaleMode, ScreenReaderOnly, type ScrollViewport, ScrollViewportProvider, SegmentedVUMeter, type SegmentedVUMeterProps, Selection, type SelectionProps, SelectionTimeInputs, type SelectionTimeInputsProps, Slider, SliderWrapper, SmartChannel, type SmartChannelProps, SmartScale, type SmartScaleProps, type SnapTo, SpectrogramChannel, type SpectrogramChannelProps, SpectrogramLabels, type SpectrogramLabelsProps,
|
|
941
|
+
export { AudioPosition, type AudioPositionProps, AutomaticScrollCheckbox, type AutomaticScrollCheckboxProps, BaseButton, BaseCheckbox, BaseCheckboxLabel, BaseCheckboxWrapper, BaseControlButton, BaseInput, BaseInputSmall, BaseLabel, BaseSelect, BaseSelectSmall, BaseSlider, type BeatsAndBarsContextValue, BeatsAndBarsProvider, type BeatsAndBarsProviderProps, Button, ButtonGroup, CLIP_BOUNDARY_WIDTH, CLIP_BOUNDARY_WIDTH_TOUCH, CLIP_HEADER_HEIGHT, Channel, type ChannelProps, Clip, ClipBoundary, type ClipBoundaryProps, ClipHeader, ClipHeaderPresentational, type ClipHeaderPresentationalProps, type ClipHeaderProps, type ClipProps, ClipViewportOriginProvider, CloseButton, type ColorStop, Controls$1 as Controls, DevicePixelRatioProvider, DotsIcon, type DragHandleProps, FadeOverlay, type FadeOverlayProps, type GradientStop, Header, InlineLabel, LoopRegion, LoopRegionMarkers, type LoopRegionMarkersProps, type LoopRegionProps, MasterVolumeControl, type MasterVolumeControlProps, PianoRollChannel, type PianoRollChannelProps, Playhead, type PlayheadProps, PlayheadWithMarker, Playlist, PlaylistErrorBoundary, type PlaylistErrorBoundaryProps, PlaylistInfoContext, type PlaylistProps, PlayoutProvider, type PrecomputedTickData, type RenderPlayheadFunction, type ScaleMode, ScreenReaderOnly, type ScrollViewport, ScrollViewportProvider, SegmentedVUMeter, type SegmentedVUMeterProps, Selection, type SelectionProps, SelectionTimeInputs, type SelectionTimeInputsProps, Slider, SliderWrapper, SmartChannel, type SmartChannelProps, SmartScale, type SmartScaleProps, type SnapTo, type SpectrogramCanvasRegistration, SpectrogramChannel, type SpectrogramChannelProps, SpectrogramLabels, type SpectrogramLabelsProps, StyledPlaylist, StyledTimeScale, type TimeFormat, TimeFormatSelect, type TimeFormatSelectProps, TimeInput, type TimeInputProps, TimeScale, type TimeScaleProps, TimescaleLoopRegion, type TimescaleLoopRegionProps, Track, TrackControlsContext, TrackMenu, type TrackMenuItem, type TrackMenuProps, type TrackProps, TrashIcon, VolumeDownIcon, VolumeUpIcon, type WaveformColor, type WaveformDrawMode, type WaveformGradient, type WaveformPlaylistTheme, darkTheme, defaultTheme, formatTime, getScaleInfo, isWaveformGradient, parseTime, pixelsToSamples, pixelsToSeconds, samplesToPixels, samplesToSeconds, secondsToPixels, secondsToSamples, useBeatsAndBars, useClipViewportOrigin, useDevicePixelRatio, usePlaylistInfo, usePlayoutStatus, usePlayoutStatusUpdate, useScrollViewport, useScrollViewportSelector, useTheme, useTrackControls, useVisibleChunkIndices, waveformColorToCss };
|
package/dist/index.d.ts
CHANGED
|
@@ -353,8 +353,20 @@ interface PlayheadProps {
|
|
|
353
353
|
controlsOffset?: number;
|
|
354
354
|
/** Function to get current audio context time - required for smooth animation */
|
|
355
355
|
getAudioContextTime?: () => number;
|
|
356
|
-
/**
|
|
356
|
+
/**
|
|
357
|
+
* Returns raw playback time from the engine (auto-wraps at loop boundaries).
|
|
358
|
+
* This is the scheduling position — for playhead display use `visualTimeRef`
|
|
359
|
+
* which already has `outputLatency` and `lookAhead` subtracted.
|
|
360
|
+
*/
|
|
357
361
|
getPlaybackTime?: () => number;
|
|
362
|
+
/**
|
|
363
|
+
* Ref to the visually-aligned playback time (raw time minus `outputLatency`
|
|
364
|
+
* and `engine.lookAhead`), kept current by the provider's animation loop
|
|
365
|
+
* during playback and by pause/stop/seek paths when stopped. Use this for
|
|
366
|
+
* playhead positioning so it lines up with audible output and matches the
|
|
367
|
+
* progress fill in `ChannelWithProgress`.
|
|
368
|
+
*/
|
|
369
|
+
visualTimeRef?: react__default.RefObject<number>;
|
|
358
370
|
}
|
|
359
371
|
/**
|
|
360
372
|
* Type for custom playhead render functions.
|
|
@@ -468,9 +480,14 @@ interface SelectionTimeInputsProps {
|
|
|
468
480
|
}
|
|
469
481
|
declare const SelectionTimeInputs: react__default.FC<SelectionTimeInputsProps>;
|
|
470
482
|
|
|
471
|
-
interface
|
|
472
|
-
|
|
473
|
-
|
|
483
|
+
interface SpectrogramCanvasRegistration {
|
|
484
|
+
canvasId: string;
|
|
485
|
+
canvas: OffscreenCanvas;
|
|
486
|
+
clipId: string;
|
|
487
|
+
channelIndex: number;
|
|
488
|
+
chunkIndex: number;
|
|
489
|
+
widthPx: number;
|
|
490
|
+
heightPx: number;
|
|
474
491
|
}
|
|
475
492
|
interface SpectrogramChannelProps {
|
|
476
493
|
/** Visual position index — used for CSS positioning (top offset). */
|
|
@@ -485,12 +502,12 @@ interface SpectrogramChannelProps {
|
|
|
485
502
|
devicePixelRatio?: number;
|
|
486
503
|
/** Samples per pixel at current zoom level */
|
|
487
504
|
samplesPerPixel: number;
|
|
488
|
-
/**
|
|
489
|
-
workerApi: SpectrogramWorkerCanvasApi;
|
|
490
|
-
/** Clip ID used to construct unique canvas IDs for worker registration */
|
|
505
|
+
/** Clip ID used to construct unique canvas IDs */
|
|
491
506
|
clipId: string;
|
|
492
|
-
/**
|
|
493
|
-
|
|
507
|
+
/** Single-call canvas registration. Receives the transferred OffscreenCanvas + metadata. */
|
|
508
|
+
onCanvasRegister: (reg: SpectrogramCanvasRegistration) => void;
|
|
509
|
+
/** Counterpart for chunk unmount / component unmount. */
|
|
510
|
+
onCanvasUnregister: (canvasId: string) => void;
|
|
494
511
|
}
|
|
495
512
|
declare const SpectrogramChannel: FunctionComponent<SpectrogramChannelProps>;
|
|
496
513
|
|
|
@@ -507,12 +524,12 @@ interface SmartChannelProps {
|
|
|
507
524
|
renderMode?: RenderMode;
|
|
508
525
|
/** Samples per pixel at current zoom level */
|
|
509
526
|
samplesPerPixel?: number;
|
|
510
|
-
/**
|
|
511
|
-
spectrogramWorkerApi?: SpectrogramWorkerCanvasApi;
|
|
512
|
-
/** Clip ID for worker canvas registration */
|
|
527
|
+
/** Clip ID for spectrogram canvas registration */
|
|
513
528
|
spectrogramClipId?: string;
|
|
514
|
-
/**
|
|
515
|
-
|
|
529
|
+
/** Single-call registration for spectrogram canvases (from SpectrogramIntegration). */
|
|
530
|
+
spectrogramOnCanvasRegister?: (reg: SpectrogramCanvasRegistration) => void;
|
|
531
|
+
/** Counterpart for chunk unmount / unmount. */
|
|
532
|
+
spectrogramOnCanvasUnregister?: (canvasId: string) => void;
|
|
516
533
|
/** MIDI note data for piano-roll rendering */
|
|
517
534
|
midiNotes?: MidiNoteData[];
|
|
518
535
|
/** Sample rate for MIDI note time → pixel conversion */
|
|
@@ -921,4 +938,4 @@ declare const BaseSlider: styled_components_dist_types.IStyledComponentBase<"web
|
|
|
921
938
|
ref?: ((instance: HTMLInputElement | null) => void | react.DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES[keyof react.DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES]) | react.RefObject<HTMLInputElement> | null | undefined;
|
|
922
939
|
}>, never>, never>> & string;
|
|
923
940
|
|
|
924
|
-
export { AudioPosition, type AudioPositionProps, AutomaticScrollCheckbox, type AutomaticScrollCheckboxProps, BaseButton, BaseCheckbox, BaseCheckboxLabel, BaseCheckboxWrapper, BaseControlButton, BaseInput, BaseInputSmall, BaseLabel, BaseSelect, BaseSelectSmall, BaseSlider, type BeatsAndBarsContextValue, BeatsAndBarsProvider, type BeatsAndBarsProviderProps, Button, ButtonGroup, CLIP_BOUNDARY_WIDTH, CLIP_BOUNDARY_WIDTH_TOUCH, CLIP_HEADER_HEIGHT, Channel, type ChannelProps, Clip, ClipBoundary, type ClipBoundaryProps, ClipHeader, ClipHeaderPresentational, type ClipHeaderPresentationalProps, type ClipHeaderProps, type ClipProps, ClipViewportOriginProvider, CloseButton, type ColorStop, Controls$1 as Controls, DevicePixelRatioProvider, DotsIcon, type DragHandleProps, FadeOverlay, type FadeOverlayProps, type GradientStop, Header, InlineLabel, LoopRegion, LoopRegionMarkers, type LoopRegionMarkersProps, type LoopRegionProps, MasterVolumeControl, type MasterVolumeControlProps, PianoRollChannel, type PianoRollChannelProps, Playhead, type PlayheadProps, PlayheadWithMarker, Playlist, PlaylistErrorBoundary, type PlaylistErrorBoundaryProps, PlaylistInfoContext, type PlaylistProps, PlayoutProvider, type PrecomputedTickData, type RenderPlayheadFunction, type ScaleMode, ScreenReaderOnly, type ScrollViewport, ScrollViewportProvider, SegmentedVUMeter, type SegmentedVUMeterProps, Selection, type SelectionProps, SelectionTimeInputs, type SelectionTimeInputsProps, Slider, SliderWrapper, SmartChannel, type SmartChannelProps, SmartScale, type SmartScaleProps, type SnapTo, SpectrogramChannel, type SpectrogramChannelProps, SpectrogramLabels, type SpectrogramLabelsProps,
|
|
941
|
+
export { AudioPosition, type AudioPositionProps, AutomaticScrollCheckbox, type AutomaticScrollCheckboxProps, BaseButton, BaseCheckbox, BaseCheckboxLabel, BaseCheckboxWrapper, BaseControlButton, BaseInput, BaseInputSmall, BaseLabel, BaseSelect, BaseSelectSmall, BaseSlider, type BeatsAndBarsContextValue, BeatsAndBarsProvider, type BeatsAndBarsProviderProps, Button, ButtonGroup, CLIP_BOUNDARY_WIDTH, CLIP_BOUNDARY_WIDTH_TOUCH, CLIP_HEADER_HEIGHT, Channel, type ChannelProps, Clip, ClipBoundary, type ClipBoundaryProps, ClipHeader, ClipHeaderPresentational, type ClipHeaderPresentationalProps, type ClipHeaderProps, type ClipProps, ClipViewportOriginProvider, CloseButton, type ColorStop, Controls$1 as Controls, DevicePixelRatioProvider, DotsIcon, type DragHandleProps, FadeOverlay, type FadeOverlayProps, type GradientStop, Header, InlineLabel, LoopRegion, LoopRegionMarkers, type LoopRegionMarkersProps, type LoopRegionProps, MasterVolumeControl, type MasterVolumeControlProps, PianoRollChannel, type PianoRollChannelProps, Playhead, type PlayheadProps, PlayheadWithMarker, Playlist, PlaylistErrorBoundary, type PlaylistErrorBoundaryProps, PlaylistInfoContext, type PlaylistProps, PlayoutProvider, type PrecomputedTickData, type RenderPlayheadFunction, type ScaleMode, ScreenReaderOnly, type ScrollViewport, ScrollViewportProvider, SegmentedVUMeter, type SegmentedVUMeterProps, Selection, type SelectionProps, SelectionTimeInputs, type SelectionTimeInputsProps, Slider, SliderWrapper, SmartChannel, type SmartChannelProps, SmartScale, type SmartScaleProps, type SnapTo, type SpectrogramCanvasRegistration, SpectrogramChannel, type SpectrogramChannelProps, SpectrogramLabels, type SpectrogramLabelsProps, StyledPlaylist, StyledTimeScale, type TimeFormat, TimeFormatSelect, type TimeFormatSelectProps, TimeInput, type TimeInputProps, TimeScale, type TimeScaleProps, TimescaleLoopRegion, type TimescaleLoopRegionProps, Track, TrackControlsContext, TrackMenu, type TrackMenuItem, type TrackMenuProps, type TrackProps, TrashIcon, VolumeDownIcon, VolumeUpIcon, type WaveformColor, type WaveformDrawMode, type WaveformGradient, type WaveformPlaylistTheme, darkTheme, defaultTheme, formatTime, getScaleInfo, isWaveformGradient, parseTime, pixelsToSamples, pixelsToSeconds, samplesToPixels, samplesToSeconds, secondsToPixels, secondsToSamples, useBeatsAndBars, useClipViewportOrigin, useDevicePixelRatio, usePlaylistInfo, usePlayoutStatus, usePlayoutStatusUpdate, useScrollViewport, useScrollViewportSelector, useTheme, useTrackControls, useVisibleChunkIndices, waveformColorToCss };
|
package/dist/index.js
CHANGED
|
@@ -1602,6 +1602,7 @@ var PlayheadWithMarker = ({
|
|
|
1602
1602
|
color = "#ff0000",
|
|
1603
1603
|
isPlaying,
|
|
1604
1604
|
currentTimeRef,
|
|
1605
|
+
visualTimeRef,
|
|
1605
1606
|
playbackStartTimeRef,
|
|
1606
1607
|
audioStartPositionRef,
|
|
1607
1608
|
samplesPerPixel,
|
|
@@ -1616,7 +1617,9 @@ var PlayheadWithMarker = ({
|
|
|
1616
1617
|
const updatePosition = () => {
|
|
1617
1618
|
if (containerRef.current) {
|
|
1618
1619
|
let time;
|
|
1619
|
-
if (
|
|
1620
|
+
if (visualTimeRef?.current !== void 0 && visualTimeRef.current !== null) {
|
|
1621
|
+
time = visualTimeRef.current;
|
|
1622
|
+
} else if (isPlaying) {
|
|
1620
1623
|
if (getPlaybackTime) {
|
|
1621
1624
|
time = getPlaybackTime();
|
|
1622
1625
|
} else if (getAudioContextTime) {
|
|
@@ -1652,6 +1655,7 @@ var PlayheadWithMarker = ({
|
|
|
1652
1655
|
samplesPerPixel,
|
|
1653
1656
|
controlsOffset,
|
|
1654
1657
|
currentTimeRef,
|
|
1658
|
+
visualTimeRef,
|
|
1655
1659
|
playbackStartTimeRef,
|
|
1656
1660
|
audioStartPositionRef,
|
|
1657
1661
|
getAudioContextTime,
|
|
@@ -1659,7 +1663,7 @@ var PlayheadWithMarker = ({
|
|
|
1659
1663
|
]);
|
|
1660
1664
|
(0, import_react9.useEffect)(() => {
|
|
1661
1665
|
if (!isPlaying && containerRef.current) {
|
|
1662
|
-
const time = currentTimeRef.current ?? 0;
|
|
1666
|
+
const time = visualTimeRef?.current ?? currentTimeRef.current ?? 0;
|
|
1663
1667
|
const pos = time * sampleRate / samplesPerPixel + controlsOffset;
|
|
1664
1668
|
containerRef.current.style.transform = `translate3d(${pos}px, 0, 0)`;
|
|
1665
1669
|
}
|
|
@@ -2457,28 +2461,28 @@ var SpectrogramChannel = ({
|
|
|
2457
2461
|
waveHeight,
|
|
2458
2462
|
devicePixelRatio = 1,
|
|
2459
2463
|
samplesPerPixel: _samplesPerPixel,
|
|
2460
|
-
workerApi,
|
|
2461
2464
|
clipId,
|
|
2462
|
-
|
|
2465
|
+
onCanvasRegister,
|
|
2466
|
+
onCanvasUnregister
|
|
2463
2467
|
}) => {
|
|
2464
2468
|
const channelIndex = channelIndexProp ?? index;
|
|
2465
2469
|
const { canvasRef, canvasMapRef } = useChunkedCanvasRefs();
|
|
2466
2470
|
const registeredIdsRef = (0, import_react20.useRef)([]);
|
|
2467
2471
|
const transferredCanvasesRef = (0, import_react20.useRef)(/* @__PURE__ */ new WeakSet());
|
|
2468
|
-
const
|
|
2469
|
-
const
|
|
2472
|
+
const onCanvasRegisterRef = (0, import_react20.useRef)(onCanvasRegister);
|
|
2473
|
+
const onCanvasUnregisterRef = (0, import_react20.useRef)(onCanvasUnregister);
|
|
2470
2474
|
const clipOriginX = useClipViewportOrigin();
|
|
2471
2475
|
const visibleChunkIndices = useVisibleChunkIndices(length, import_core5.MAX_CANVAS_WIDTH, clipOriginX);
|
|
2472
2476
|
(0, import_react20.useEffect)(() => {
|
|
2473
|
-
|
|
2474
|
-
}, [
|
|
2477
|
+
onCanvasRegisterRef.current = onCanvasRegister;
|
|
2478
|
+
}, [onCanvasRegister]);
|
|
2475
2479
|
(0, import_react20.useEffect)(() => {
|
|
2476
|
-
|
|
2477
|
-
}, [
|
|
2480
|
+
onCanvasUnregisterRef.current = onCanvasUnregister;
|
|
2481
|
+
}, [onCanvasUnregister]);
|
|
2478
2482
|
(0, import_react20.useEffect)(() => {
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
const
|
|
2483
|
+
if (!clipId) return;
|
|
2484
|
+
const unregister = onCanvasUnregisterRef.current;
|
|
2485
|
+
const register = onCanvasRegisterRef.current;
|
|
2482
2486
|
const remaining = [];
|
|
2483
2487
|
for (const id of registeredIdsRef.current) {
|
|
2484
2488
|
const match = id.match(/chunk(\d+)$/);
|
|
@@ -2492,14 +2496,13 @@ var SpectrogramChannel = ({
|
|
|
2492
2496
|
remaining.push(id);
|
|
2493
2497
|
} else {
|
|
2494
2498
|
try {
|
|
2495
|
-
|
|
2499
|
+
unregister(id);
|
|
2496
2500
|
} catch (err) {
|
|
2497
|
-
console.warn(`[spectrogram]
|
|
2501
|
+
console.warn(`[spectrogram] unregister failed for ${id}:`, err);
|
|
2498
2502
|
}
|
|
2499
2503
|
}
|
|
2500
2504
|
}
|
|
2501
2505
|
registeredIdsRef.current = remaining;
|
|
2502
|
-
const newIds = [];
|
|
2503
2506
|
for (const [canvasIdx, canvas] of canvasMapRef.current.entries()) {
|
|
2504
2507
|
if (transferredCanvasesRef.current.has(canvas)) continue;
|
|
2505
2508
|
const canvasId = `${clipId}-ch${channelIndex}-chunk${canvasIdx}`;
|
|
@@ -2511,41 +2514,31 @@ var SpectrogramChannel = ({
|
|
|
2511
2514
|
continue;
|
|
2512
2515
|
}
|
|
2513
2516
|
transferredCanvasesRef.current.add(canvas);
|
|
2517
|
+
const widthPx = Math.min(length - canvasIdx * import_core5.MAX_CANVAS_WIDTH, import_core5.MAX_CANVAS_WIDTH);
|
|
2514
2518
|
try {
|
|
2515
|
-
|
|
2516
|
-
|
|
2519
|
+
register({
|
|
2520
|
+
canvasId,
|
|
2521
|
+
canvas: offscreen,
|
|
2522
|
+
clipId,
|
|
2523
|
+
channelIndex,
|
|
2524
|
+
chunkIndex: canvasIdx,
|
|
2525
|
+
widthPx,
|
|
2526
|
+
heightPx: waveHeight
|
|
2527
|
+
});
|
|
2528
|
+
registeredIdsRef.current.push(canvasId);
|
|
2517
2529
|
} catch (err) {
|
|
2518
|
-
console.warn(`[spectrogram]
|
|
2519
|
-
continue;
|
|
2530
|
+
console.warn(`[spectrogram] register failed for ${canvasId}:`, err);
|
|
2520
2531
|
}
|
|
2521
2532
|
}
|
|
2522
|
-
|
|
2523
|
-
registeredIdsRef.current = [...registeredIdsRef.current, ...newIds];
|
|
2524
|
-
}
|
|
2525
|
-
const canvasSetChanged = newIds.length > 0 || remaining.length < previousCount;
|
|
2526
|
-
if (canvasSetChanged) {
|
|
2527
|
-
const allIds = registeredIdsRef.current;
|
|
2528
|
-
const allWidths = allIds.map((id) => {
|
|
2529
|
-
const match = id.match(/chunk(\d+)$/);
|
|
2530
|
-
if (!match) {
|
|
2531
|
-
console.warn(`[spectrogram] Unexpected canvas ID format: ${id}`);
|
|
2532
|
-
return import_core5.MAX_CANVAS_WIDTH;
|
|
2533
|
-
}
|
|
2534
|
-
const chunkIdx = parseInt(match[1], 10);
|
|
2535
|
-
return Math.min(length - chunkIdx * import_core5.MAX_CANVAS_WIDTH, import_core5.MAX_CANVAS_WIDTH);
|
|
2536
|
-
});
|
|
2537
|
-
onCanvasesReadyRef.current?.(allIds, allWidths);
|
|
2538
|
-
}
|
|
2539
|
-
}, [canvasMapRef, clipId, channelIndex, length, visibleChunkIndices]);
|
|
2533
|
+
}, [canvasMapRef, clipId, channelIndex, length, waveHeight, visibleChunkIndices]);
|
|
2540
2534
|
(0, import_react20.useEffect)(() => {
|
|
2541
2535
|
return () => {
|
|
2542
|
-
const
|
|
2543
|
-
if (!api) return;
|
|
2536
|
+
const unregister = onCanvasUnregisterRef.current;
|
|
2544
2537
|
for (const id of registeredIdsRef.current) {
|
|
2545
2538
|
try {
|
|
2546
|
-
|
|
2539
|
+
unregister(id);
|
|
2547
2540
|
} catch (err) {
|
|
2548
|
-
console.warn(`[spectrogram]
|
|
2541
|
+
console.warn(`[spectrogram] unregister failed for ${id}:`, err);
|
|
2549
2542
|
}
|
|
2550
2543
|
}
|
|
2551
2544
|
registeredIdsRef.current = [];
|
|
@@ -2578,9 +2571,9 @@ var SmartChannel = ({
|
|
|
2578
2571
|
transparentBackground,
|
|
2579
2572
|
renderMode = "waveform",
|
|
2580
2573
|
samplesPerPixel: sppProp,
|
|
2581
|
-
spectrogramWorkerApi,
|
|
2582
2574
|
spectrogramClipId,
|
|
2583
|
-
|
|
2575
|
+
spectrogramOnCanvasRegister,
|
|
2576
|
+
spectrogramOnCanvasUnregister,
|
|
2584
2577
|
midiNotes,
|
|
2585
2578
|
sampleRate: sampleRateProp,
|
|
2586
2579
|
clipOffsetSeconds,
|
|
@@ -2599,7 +2592,7 @@ var SmartChannel = ({
|
|
|
2599
2592
|
const waveOutlineColor = isSelected && theme ? theme.selectedWaveOutlineColor : theme?.waveOutlineColor;
|
|
2600
2593
|
const waveFillColor = isSelected && theme ? theme.selectedWaveFillColor : theme?.waveFillColor;
|
|
2601
2594
|
const drawMode = theme?.waveformDrawMode || "inverted";
|
|
2602
|
-
const hasSpectrogram =
|
|
2595
|
+
const hasSpectrogram = spectrogramClipId && spectrogramOnCanvasRegister && spectrogramOnCanvasUnregister;
|
|
2603
2596
|
if (renderMode === "spectrogram" && hasSpectrogram) {
|
|
2604
2597
|
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
2605
2598
|
SpectrogramChannel,
|
|
@@ -2609,9 +2602,9 @@ var SmartChannel = ({
|
|
|
2609
2602
|
waveHeight,
|
|
2610
2603
|
devicePixelRatio,
|
|
2611
2604
|
samplesPerPixel,
|
|
2612
|
-
workerApi: spectrogramWorkerApi,
|
|
2613
2605
|
clipId: spectrogramClipId,
|
|
2614
|
-
|
|
2606
|
+
onCanvasRegister: spectrogramOnCanvasRegister,
|
|
2607
|
+
onCanvasUnregister: spectrogramOnCanvasUnregister
|
|
2615
2608
|
}
|
|
2616
2609
|
);
|
|
2617
2610
|
}
|
|
@@ -2627,9 +2620,9 @@ var SmartChannel = ({
|
|
|
2627
2620
|
waveHeight: halfHeight,
|
|
2628
2621
|
devicePixelRatio,
|
|
2629
2622
|
samplesPerPixel,
|
|
2630
|
-
workerApi: spectrogramWorkerApi,
|
|
2631
2623
|
clipId: spectrogramClipId,
|
|
2632
|
-
|
|
2624
|
+
onCanvasRegister: spectrogramOnCanvasRegister,
|
|
2625
|
+
onCanvasUnregister: spectrogramOnCanvasUnregister
|
|
2633
2626
|
}
|
|
2634
2627
|
),
|
|
2635
2628
|
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|