@waveform-playlist/ui-components 7.1.0 → 7.1.2
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 +9 -8
- package/dist/index.d.ts +9 -8
- package/dist/index.js +201 -250
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +113 -161
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/index.mjs
CHANGED
|
@@ -327,7 +327,7 @@ var AutomaticScrollCheckbox = ({
|
|
|
327
327
|
};
|
|
328
328
|
|
|
329
329
|
// src/components/Channel.tsx
|
|
330
|
-
import { useLayoutEffect
|
|
330
|
+
import { useLayoutEffect } from "react";
|
|
331
331
|
import styled9 from "styled-components";
|
|
332
332
|
|
|
333
333
|
// src/wfpl-theme.ts
|
|
@@ -493,6 +493,7 @@ import {
|
|
|
493
493
|
useContext,
|
|
494
494
|
useEffect,
|
|
495
495
|
useCallback,
|
|
496
|
+
useMemo,
|
|
496
497
|
useRef,
|
|
497
498
|
useSyncExternalStore
|
|
498
499
|
} from "react";
|
|
@@ -587,11 +588,52 @@ function useScrollViewportSelector(selector) {
|
|
|
587
588
|
() => selector(null)
|
|
588
589
|
);
|
|
589
590
|
}
|
|
591
|
+
function useVisibleChunkIndices(totalWidth, chunkWidth) {
|
|
592
|
+
const visibleChunkKey = useScrollViewportSelector((viewport) => {
|
|
593
|
+
const totalChunks = Math.ceil(totalWidth / chunkWidth);
|
|
594
|
+
const indices = [];
|
|
595
|
+
for (let i = 0; i < totalChunks; i++) {
|
|
596
|
+
const chunkLeft = i * chunkWidth;
|
|
597
|
+
const thisChunkWidth = Math.min(totalWidth - chunkLeft, chunkWidth);
|
|
598
|
+
if (viewport) {
|
|
599
|
+
const chunkEnd = chunkLeft + thisChunkWidth;
|
|
600
|
+
if (chunkEnd <= viewport.visibleStart || chunkLeft >= viewport.visibleEnd) {
|
|
601
|
+
continue;
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
indices.push(i);
|
|
605
|
+
}
|
|
606
|
+
return indices.join(",");
|
|
607
|
+
});
|
|
608
|
+
return useMemo(
|
|
609
|
+
() => visibleChunkKey ? visibleChunkKey.split(",").map(Number) : [],
|
|
610
|
+
[visibleChunkKey]
|
|
611
|
+
);
|
|
612
|
+
}
|
|
590
613
|
|
|
591
|
-
// src/
|
|
592
|
-
|
|
614
|
+
// src/hooks/useChunkedCanvasRefs.ts
|
|
615
|
+
import { useCallback as useCallback2, useEffect as useEffect2, useRef as useRef2 } from "react";
|
|
616
|
+
function useChunkedCanvasRefs() {
|
|
617
|
+
const canvasMapRef = useRef2(/* @__PURE__ */ new Map());
|
|
618
|
+
const canvasRef = useCallback2((canvas) => {
|
|
619
|
+
if (canvas !== null) {
|
|
620
|
+
const idx = parseInt(canvas.dataset.index, 10);
|
|
621
|
+
canvasMapRef.current.set(idx, canvas);
|
|
622
|
+
}
|
|
623
|
+
}, []);
|
|
624
|
+
useEffect2(() => {
|
|
625
|
+
const map = canvasMapRef.current;
|
|
626
|
+
for (const [idx, canvas] of map.entries()) {
|
|
627
|
+
if (!canvas.isConnected) {
|
|
628
|
+
map.delete(idx);
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
});
|
|
632
|
+
return { canvasRef, canvasMapRef };
|
|
633
|
+
}
|
|
593
634
|
|
|
594
635
|
// src/components/Channel.tsx
|
|
636
|
+
import { MAX_CANVAS_WIDTH } from "@waveform-playlist/core";
|
|
595
637
|
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
596
638
|
function createCanvasFillStyle(ctx, color, width, height) {
|
|
597
639
|
if (!isWaveformGradient(color)) {
|
|
@@ -652,48 +694,11 @@ var Channel = (props) => {
|
|
|
652
694
|
transparentBackground = false,
|
|
653
695
|
drawMode = "inverted"
|
|
654
696
|
} = props;
|
|
655
|
-
const
|
|
656
|
-
const
|
|
657
|
-
const totalChunks = Math.ceil(length / MAX_CANVAS_WIDTH);
|
|
658
|
-
const indices = [];
|
|
659
|
-
for (let i = 0; i < totalChunks; i++) {
|
|
660
|
-
const chunkLeft = i * MAX_CANVAS_WIDTH;
|
|
661
|
-
const chunkWidth = Math.min(length - chunkLeft, MAX_CANVAS_WIDTH);
|
|
662
|
-
if (viewport) {
|
|
663
|
-
const chunkEnd = chunkLeft + chunkWidth;
|
|
664
|
-
if (chunkEnd <= viewport.visibleStart || chunkLeft >= viewport.visibleEnd) {
|
|
665
|
-
continue;
|
|
666
|
-
}
|
|
667
|
-
}
|
|
668
|
-
indices.push(i);
|
|
669
|
-
}
|
|
670
|
-
return indices.join(",");
|
|
671
|
-
});
|
|
672
|
-
const visibleChunkIndices = visibleChunkKey ? visibleChunkKey.split(",").map(Number) : [];
|
|
673
|
-
const canvasRef = useCallback2(
|
|
674
|
-
(canvas) => {
|
|
675
|
-
if (canvas !== null) {
|
|
676
|
-
const index2 = parseInt(canvas.dataset.index, 10);
|
|
677
|
-
canvasesRef.current[index2] = canvas;
|
|
678
|
-
}
|
|
679
|
-
},
|
|
680
|
-
[]
|
|
681
|
-
);
|
|
682
|
-
useEffect2(() => {
|
|
683
|
-
const canvases = canvasesRef.current;
|
|
684
|
-
for (let i = canvases.length - 1; i >= 0; i--) {
|
|
685
|
-
if (canvases[i] && !canvases[i].isConnected) {
|
|
686
|
-
delete canvases[i];
|
|
687
|
-
}
|
|
688
|
-
}
|
|
689
|
-
});
|
|
697
|
+
const { canvasRef, canvasMapRef } = useChunkedCanvasRefs();
|
|
698
|
+
const visibleChunkIndices = useVisibleChunkIndices(length, MAX_CANVAS_WIDTH);
|
|
690
699
|
useLayoutEffect(() => {
|
|
691
|
-
const canvases = canvasesRef.current;
|
|
692
700
|
const step = barWidth + barGap;
|
|
693
|
-
for (
|
|
694
|
-
const canvas = canvases[i];
|
|
695
|
-
if (!canvas) continue;
|
|
696
|
-
const canvasIdx = parseInt(canvas.dataset.index, 10);
|
|
701
|
+
for (const [canvasIdx, canvas] of canvasMapRef.current.entries()) {
|
|
697
702
|
const globalPixelOffset = canvasIdx * MAX_CANVAS_WIDTH;
|
|
698
703
|
const ctx = canvas.getContext("2d");
|
|
699
704
|
const h2 = Math.floor(waveHeight / 2);
|
|
@@ -739,6 +744,7 @@ var Channel = (props) => {
|
|
|
739
744
|
}
|
|
740
745
|
}
|
|
741
746
|
}, [
|
|
747
|
+
canvasMapRef,
|
|
742
748
|
data,
|
|
743
749
|
bits,
|
|
744
750
|
waveHeight,
|
|
@@ -749,7 +755,7 @@ var Channel = (props) => {
|
|
|
749
755
|
barWidth,
|
|
750
756
|
barGap,
|
|
751
757
|
drawMode,
|
|
752
|
-
|
|
758
|
+
visibleChunkIndices
|
|
753
759
|
]);
|
|
754
760
|
const waveforms = visibleChunkIndices.map((i) => {
|
|
755
761
|
const chunkLeft = i * MAX_CANVAS_WIDTH;
|
|
@@ -2061,8 +2067,9 @@ var usePlayoutStatus = () => useContext6(PlayoutStatusContext);
|
|
|
2061
2067
|
var usePlayoutStatusUpdate = () => useContext6(PlayoutStatusUpdateContext);
|
|
2062
2068
|
|
|
2063
2069
|
// src/components/SpectrogramChannel.tsx
|
|
2064
|
-
import { useLayoutEffect as useLayoutEffect2,
|
|
2070
|
+
import { useLayoutEffect as useLayoutEffect2, useRef as useRef6, useEffect as useEffect6 } from "react";
|
|
2065
2071
|
import styled19 from "styled-components";
|
|
2072
|
+
import { MAX_CANVAS_WIDTH as MAX_CANVAS_WIDTH2 } from "@waveform-playlist/core";
|
|
2066
2073
|
import { jsx as jsx20 } from "react/jsx-runtime";
|
|
2067
2074
|
var LINEAR_FREQUENCY_SCALE = (f, minF, maxF) => (f - minF) / (maxF - minF);
|
|
2068
2075
|
var Wrapper3 = styled19.div.attrs((props) => ({
|
|
@@ -2116,38 +2123,13 @@ var SpectrogramChannel = ({
|
|
|
2116
2123
|
onCanvasesReady
|
|
2117
2124
|
}) => {
|
|
2118
2125
|
const channelIndex = channelIndexProp ?? index;
|
|
2119
|
-
const
|
|
2126
|
+
const { canvasRef, canvasMapRef } = useChunkedCanvasRefs();
|
|
2120
2127
|
const registeredIdsRef = useRef6([]);
|
|
2121
2128
|
const transferredCanvasesRef = useRef6(/* @__PURE__ */ new WeakSet());
|
|
2122
2129
|
const workerApiRef = useRef6(workerApi);
|
|
2123
2130
|
const onCanvasesReadyRef = useRef6(onCanvasesReady);
|
|
2124
2131
|
const isWorkerMode = !!(workerApi && clipId);
|
|
2125
|
-
const
|
|
2126
|
-
const totalChunks = Math.ceil(length / MAX_CANVAS_WIDTH);
|
|
2127
|
-
const indices = [];
|
|
2128
|
-
for (let i = 0; i < totalChunks; i++) {
|
|
2129
|
-
const chunkLeft = i * MAX_CANVAS_WIDTH;
|
|
2130
|
-
const chunkWidth = Math.min(length - chunkLeft, MAX_CANVAS_WIDTH);
|
|
2131
|
-
if (viewport) {
|
|
2132
|
-
const chunkEnd = chunkLeft + chunkWidth;
|
|
2133
|
-
if (chunkEnd <= viewport.visibleStart || chunkLeft >= viewport.visibleEnd) {
|
|
2134
|
-
continue;
|
|
2135
|
-
}
|
|
2136
|
-
}
|
|
2137
|
-
indices.push(i);
|
|
2138
|
-
}
|
|
2139
|
-
return indices.join(",");
|
|
2140
|
-
});
|
|
2141
|
-
const visibleChunkIndices = visibleChunkKey ? visibleChunkKey.split(",").map(Number) : [];
|
|
2142
|
-
const canvasRef = useCallback5(
|
|
2143
|
-
(canvas) => {
|
|
2144
|
-
if (canvas !== null) {
|
|
2145
|
-
const idx = parseInt(canvas.dataset.index, 10);
|
|
2146
|
-
canvasesRef.current[idx] = canvas;
|
|
2147
|
-
}
|
|
2148
|
-
},
|
|
2149
|
-
[]
|
|
2150
|
-
);
|
|
2132
|
+
const visibleChunkIndices = useVisibleChunkIndices(length, MAX_CANVAS_WIDTH2);
|
|
2151
2133
|
const lut = colorLUT ?? DEFAULT_COLOR_LUT;
|
|
2152
2134
|
const maxF = maxFrequency ?? (data ? data.sampleRate / 2 : 22050);
|
|
2153
2135
|
const scaleFn = frequencyScaleFn ?? LINEAR_FREQUENCY_SCALE;
|
|
@@ -2162,14 +2144,30 @@ var SpectrogramChannel = ({
|
|
|
2162
2144
|
if (!isWorkerMode) return;
|
|
2163
2145
|
const currentWorkerApi = workerApiRef.current;
|
|
2164
2146
|
if (!currentWorkerApi || !clipId) return;
|
|
2165
|
-
const
|
|
2147
|
+
const previousCount = registeredIdsRef.current.length;
|
|
2148
|
+
const remaining = [];
|
|
2149
|
+
for (const id of registeredIdsRef.current) {
|
|
2150
|
+
const match = id.match(/chunk(\d+)$/);
|
|
2151
|
+
if (!match) {
|
|
2152
|
+
remaining.push(id);
|
|
2153
|
+
continue;
|
|
2154
|
+
}
|
|
2155
|
+
const chunkIdx = parseInt(match[1], 10);
|
|
2156
|
+
const canvas = canvasMapRef.current.get(chunkIdx);
|
|
2157
|
+
if (canvas && canvas.isConnected) {
|
|
2158
|
+
remaining.push(id);
|
|
2159
|
+
} else {
|
|
2160
|
+
try {
|
|
2161
|
+
currentWorkerApi.unregisterCanvas(id);
|
|
2162
|
+
} catch (err) {
|
|
2163
|
+
console.warn(`[spectrogram] unregisterCanvas failed for ${id}:`, err);
|
|
2164
|
+
}
|
|
2165
|
+
}
|
|
2166
|
+
}
|
|
2167
|
+
registeredIdsRef.current = remaining;
|
|
2166
2168
|
const newIds = [];
|
|
2167
|
-
const
|
|
2168
|
-
for (let i = 0; i < canvases2.length; i++) {
|
|
2169
|
-
const canvas = canvases2[i];
|
|
2170
|
-
if (!canvas) continue;
|
|
2169
|
+
for (const [canvasIdx, canvas] of canvasMapRef.current.entries()) {
|
|
2171
2170
|
if (transferredCanvasesRef.current.has(canvas)) continue;
|
|
2172
|
-
const canvasIdx = parseInt(canvas.dataset.index, 10);
|
|
2173
2171
|
const canvasId = `${clipId}-ch${channelIndex}-chunk${canvasIdx}`;
|
|
2174
2172
|
let offscreen;
|
|
2175
2173
|
try {
|
|
@@ -2182,7 +2180,6 @@ var SpectrogramChannel = ({
|
|
|
2182
2180
|
try {
|
|
2183
2181
|
currentWorkerApi.registerCanvas(canvasId, offscreen);
|
|
2184
2182
|
newIds.push(canvasId);
|
|
2185
|
-
newWidths.push(Math.min(length - canvasIdx * MAX_CANVAS_WIDTH, MAX_CANVAS_WIDTH));
|
|
2186
2183
|
} catch (err) {
|
|
2187
2184
|
console.warn(`[spectrogram] registerCanvas failed for ${canvasId}:`, err);
|
|
2188
2185
|
continue;
|
|
@@ -2190,34 +2187,22 @@ var SpectrogramChannel = ({
|
|
|
2190
2187
|
}
|
|
2191
2188
|
if (newIds.length > 0) {
|
|
2192
2189
|
registeredIdsRef.current = [...registeredIdsRef.current, ...newIds];
|
|
2193
|
-
onCanvasesReadyRef.current?.(newIds, newWidths);
|
|
2194
2190
|
}
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
if (!match) {
|
|
2204
|
-
remaining.push(id);
|
|
2205
|
-
continue;
|
|
2206
|
-
}
|
|
2207
|
-
const chunkIdx = parseInt(match[1], 10);
|
|
2208
|
-
const canvas = canvasesRef.current[chunkIdx];
|
|
2209
|
-
if (canvas && canvas.isConnected) {
|
|
2210
|
-
remaining.push(id);
|
|
2211
|
-
} else {
|
|
2212
|
-
try {
|
|
2213
|
-
currentWorkerApi.unregisterCanvas(id);
|
|
2214
|
-
} catch (err) {
|
|
2215
|
-
console.warn(`[spectrogram] unregisterCanvas failed for ${id}:`, err);
|
|
2191
|
+
const canvasSetChanged = newIds.length > 0 || remaining.length < previousCount;
|
|
2192
|
+
if (canvasSetChanged) {
|
|
2193
|
+
const allIds = registeredIdsRef.current;
|
|
2194
|
+
const allWidths = allIds.map((id) => {
|
|
2195
|
+
const match = id.match(/chunk(\d+)$/);
|
|
2196
|
+
if (!match) {
|
|
2197
|
+
console.warn(`[spectrogram] Unexpected canvas ID format: ${id}`);
|
|
2198
|
+
return MAX_CANVAS_WIDTH2;
|
|
2216
2199
|
}
|
|
2217
|
-
|
|
2200
|
+
const chunkIdx = parseInt(match[1], 10);
|
|
2201
|
+
return Math.min(length - chunkIdx * MAX_CANVAS_WIDTH2, MAX_CANVAS_WIDTH2);
|
|
2202
|
+
});
|
|
2203
|
+
onCanvasesReadyRef.current?.(allIds, allWidths);
|
|
2218
2204
|
}
|
|
2219
|
-
|
|
2220
|
-
});
|
|
2205
|
+
}, [canvasMapRef, isWorkerMode, clipId, channelIndex, length, visibleChunkIndices]);
|
|
2221
2206
|
useEffect6(() => {
|
|
2222
2207
|
return () => {
|
|
2223
2208
|
const api = workerApiRef.current;
|
|
@@ -2234,15 +2219,11 @@ var SpectrogramChannel = ({
|
|
|
2234
2219
|
}, []);
|
|
2235
2220
|
useLayoutEffect2(() => {
|
|
2236
2221
|
if (isWorkerMode || !data) return;
|
|
2237
|
-
const canvases2 = canvasesRef.current;
|
|
2238
2222
|
const { frequencyBinCount, frameCount, hopSize, sampleRate, gainDb, rangeDb: rawRangeDb } = data;
|
|
2239
2223
|
const rangeDb = rawRangeDb === 0 ? 1 : rawRangeDb;
|
|
2240
2224
|
const binToFreq = (bin) => bin / frequencyBinCount * (sampleRate / 2);
|
|
2241
|
-
for (
|
|
2242
|
-
const
|
|
2243
|
-
if (!canvas) continue;
|
|
2244
|
-
const canvasIdx = parseInt(canvas.dataset.index, 10);
|
|
2245
|
-
const globalPixelOffset = canvasIdx * MAX_CANVAS_WIDTH;
|
|
2225
|
+
for (const [canvasIdx, canvas] of canvasMapRef.current.entries()) {
|
|
2226
|
+
const globalPixelOffset = canvasIdx * MAX_CANVAS_WIDTH2;
|
|
2246
2227
|
const ctx = canvas.getContext("2d");
|
|
2247
2228
|
if (!ctx) continue;
|
|
2248
2229
|
const canvasWidth = canvas.width / devicePixelRatio;
|
|
@@ -2302,10 +2283,10 @@ var SpectrogramChannel = ({
|
|
|
2302
2283
|
ctx.drawImage(tmpCanvas, 0, 0, canvas.width, canvas.height);
|
|
2303
2284
|
}
|
|
2304
2285
|
}
|
|
2305
|
-
}, [isWorkerMode, data, length, waveHeight, devicePixelRatio, samplesPerPixel, lut, minFrequency, maxF, scaleFn, hasCustomFrequencyScale,
|
|
2286
|
+
}, [canvasMapRef, isWorkerMode, data, length, waveHeight, devicePixelRatio, samplesPerPixel, lut, minFrequency, maxF, scaleFn, hasCustomFrequencyScale, visibleChunkIndices]);
|
|
2306
2287
|
const canvases = visibleChunkIndices.map((i) => {
|
|
2307
|
-
const chunkLeft = i *
|
|
2308
|
-
const currentWidth = Math.min(length - chunkLeft,
|
|
2288
|
+
const chunkLeft = i * MAX_CANVAS_WIDTH2;
|
|
2289
|
+
const currentWidth = Math.min(length - chunkLeft, MAX_CANVAS_WIDTH2);
|
|
2309
2290
|
return /* @__PURE__ */ jsx20(
|
|
2310
2291
|
SpectrogramCanvas,
|
|
2311
2292
|
{
|
|
@@ -2527,7 +2508,7 @@ var SpectrogramLabels = ({
|
|
|
2527
2508
|
import { useContext as useContext8 } from "react";
|
|
2528
2509
|
|
|
2529
2510
|
// src/components/TimeScale.tsx
|
|
2530
|
-
import React15, {
|
|
2511
|
+
import React15, { useLayoutEffect as useLayoutEffect4, useContext as useContext7, useMemo as useMemo2 } from "react";
|
|
2531
2512
|
import styled21, { withTheme as withTheme2 } from "styled-components";
|
|
2532
2513
|
|
|
2533
2514
|
// src/utils/conversions.ts
|
|
@@ -2551,6 +2532,7 @@ function secondsToPixels(seconds, samplesPerPixel, sampleRate) {
|
|
|
2551
2532
|
}
|
|
2552
2533
|
|
|
2553
2534
|
// src/components/TimeScale.tsx
|
|
2535
|
+
import { MAX_CANVAS_WIDTH as MAX_CANVAS_WIDTH3 } from "@waveform-playlist/core";
|
|
2554
2536
|
import { jsx as jsx23, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2555
2537
|
function formatTime2(milliseconds) {
|
|
2556
2538
|
const seconds = Math.floor(milliseconds / 1e3);
|
|
@@ -2602,7 +2584,7 @@ var TimeScale = (props) => {
|
|
|
2602
2584
|
secondStep,
|
|
2603
2585
|
renderTimestamp
|
|
2604
2586
|
} = props;
|
|
2605
|
-
const
|
|
2587
|
+
const { canvasRef, canvasMapRef } = useChunkedCanvasRefs();
|
|
2606
2588
|
const {
|
|
2607
2589
|
sampleRate,
|
|
2608
2590
|
samplesPerPixel,
|
|
@@ -2610,13 +2592,7 @@ var TimeScale = (props) => {
|
|
|
2610
2592
|
controls: { show: showControls, width: controlWidth }
|
|
2611
2593
|
} = useContext7(PlaylistInfoContext);
|
|
2612
2594
|
const devicePixelRatio = useDevicePixelRatio();
|
|
2613
|
-
const
|
|
2614
|
-
if (canvas !== null) {
|
|
2615
|
-
const idx = parseInt(canvas.dataset.index, 10);
|
|
2616
|
-
canvasRefsMap.current.set(idx, canvas);
|
|
2617
|
-
}
|
|
2618
|
-
}, []);
|
|
2619
|
-
const { widthX, canvasInfo, timeMarkersWithPositions } = useMemo(() => {
|
|
2595
|
+
const { widthX, canvasInfo, timeMarkersWithPositions } = useMemo2(() => {
|
|
2620
2596
|
const nextCanvasInfo = /* @__PURE__ */ new Map();
|
|
2621
2597
|
const nextMarkers = [];
|
|
2622
2598
|
const nextWidthX = secondsToPixels(duration / 1e3, samplesPerPixel, sampleRate);
|
|
@@ -2643,26 +2619,10 @@ var TimeScale = (props) => {
|
|
|
2643
2619
|
timeMarkersWithPositions: nextMarkers
|
|
2644
2620
|
};
|
|
2645
2621
|
}, [duration, samplesPerPixel, sampleRate, marker, bigStep, secondStep, renderTimestamp, timeScaleHeight]);
|
|
2646
|
-
const
|
|
2647
|
-
const totalChunks = Math.ceil(widthX / MAX_CANVAS_WIDTH);
|
|
2648
|
-
const indices = [];
|
|
2649
|
-
for (let i = 0; i < totalChunks; i++) {
|
|
2650
|
-
const chunkLeft = i * MAX_CANVAS_WIDTH;
|
|
2651
|
-
const chunkWidth = Math.min(widthX - chunkLeft, MAX_CANVAS_WIDTH);
|
|
2652
|
-
if (viewport) {
|
|
2653
|
-
const chunkEnd = chunkLeft + chunkWidth;
|
|
2654
|
-
if (chunkEnd <= viewport.visibleStart || chunkLeft >= viewport.visibleEnd) {
|
|
2655
|
-
continue;
|
|
2656
|
-
}
|
|
2657
|
-
}
|
|
2658
|
-
indices.push(i);
|
|
2659
|
-
}
|
|
2660
|
-
return indices.join(",");
|
|
2661
|
-
});
|
|
2662
|
-
const visibleChunkIndices = visibleChunkKey ? visibleChunkKey.split(",").map(Number) : [];
|
|
2622
|
+
const visibleChunkIndices = useVisibleChunkIndices(widthX, MAX_CANVAS_WIDTH3);
|
|
2663
2623
|
const visibleChunks = visibleChunkIndices.map((i) => {
|
|
2664
|
-
const chunkLeft = i *
|
|
2665
|
-
const chunkWidth = Math.min(widthX - chunkLeft,
|
|
2624
|
+
const chunkLeft = i * MAX_CANVAS_WIDTH3;
|
|
2625
|
+
const chunkWidth = Math.min(widthX - chunkLeft, MAX_CANVAS_WIDTH3);
|
|
2666
2626
|
return /* @__PURE__ */ jsx23(
|
|
2667
2627
|
TimeTickChunk,
|
|
2668
2628
|
{
|
|
@@ -2672,27 +2632,19 @@ var TimeScale = (props) => {
|
|
|
2672
2632
|
width: chunkWidth * devicePixelRatio,
|
|
2673
2633
|
height: timeScaleHeight * devicePixelRatio,
|
|
2674
2634
|
"data-index": i,
|
|
2675
|
-
ref:
|
|
2635
|
+
ref: canvasRef
|
|
2676
2636
|
},
|
|
2677
2637
|
`timescale-${i}`
|
|
2678
2638
|
);
|
|
2679
2639
|
});
|
|
2680
|
-
const firstChunkLeft = visibleChunkIndices.length > 0 ? visibleChunkIndices[0] *
|
|
2681
|
-
const lastChunkRight = visibleChunkIndices.length > 0 ? (visibleChunkIndices[visibleChunkIndices.length - 1] + 1) *
|
|
2640
|
+
const firstChunkLeft = visibleChunkIndices.length > 0 ? visibleChunkIndices[0] * MAX_CANVAS_WIDTH3 : 0;
|
|
2641
|
+
const lastChunkRight = visibleChunkIndices.length > 0 ? (visibleChunkIndices[visibleChunkIndices.length - 1] + 1) * MAX_CANVAS_WIDTH3 : Infinity;
|
|
2682
2642
|
const visibleMarkers = visibleChunkIndices.length > 0 ? timeMarkersWithPositions.filter(({ pix }) => pix >= firstChunkLeft && pix < lastChunkRight).map(({ element }) => element) : timeMarkersWithPositions.map(({ element }) => element);
|
|
2683
|
-
useEffect7(() => {
|
|
2684
|
-
const currentMap = canvasRefsMap.current;
|
|
2685
|
-
for (const [idx, canvas] of currentMap.entries()) {
|
|
2686
|
-
if (!canvas.isConnected) {
|
|
2687
|
-
currentMap.delete(idx);
|
|
2688
|
-
}
|
|
2689
|
-
}
|
|
2690
|
-
});
|
|
2691
2643
|
useLayoutEffect4(() => {
|
|
2692
|
-
for (const [chunkIdx, canvas] of
|
|
2644
|
+
for (const [chunkIdx, canvas] of canvasMapRef.current.entries()) {
|
|
2693
2645
|
const ctx = canvas.getContext("2d");
|
|
2694
2646
|
if (!ctx) continue;
|
|
2695
|
-
const chunkLeft = chunkIdx *
|
|
2647
|
+
const chunkLeft = chunkIdx * MAX_CANVAS_WIDTH3;
|
|
2696
2648
|
const chunkWidth = canvas.width / devicePixelRatio;
|
|
2697
2649
|
ctx.resetTransform();
|
|
2698
2650
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
@@ -2706,7 +2658,7 @@ var TimeScale = (props) => {
|
|
|
2706
2658
|
ctx.fillRect(localX, scaleY, 1, scaleHeight);
|
|
2707
2659
|
}
|
|
2708
2660
|
}
|
|
2709
|
-
}, [duration, devicePixelRatio, timeColor, timeScaleHeight, canvasInfo,
|
|
2661
|
+
}, [canvasMapRef, duration, devicePixelRatio, timeColor, timeScaleHeight, canvasInfo, visibleChunkIndices]);
|
|
2710
2662
|
return /* @__PURE__ */ jsxs10(
|
|
2711
2663
|
PlaylistTimeScaleScroll,
|
|
2712
2664
|
{
|
|
@@ -3178,7 +3130,7 @@ var SliderWrapper = styled30.label`
|
|
|
3178
3130
|
`;
|
|
3179
3131
|
|
|
3180
3132
|
// src/components/TrackMenu.tsx
|
|
3181
|
-
import React17, { useState as useState6, useEffect as
|
|
3133
|
+
import React17, { useState as useState6, useEffect as useEffect7, useRef as useRef8 } from "react";
|
|
3182
3134
|
import { createPortal } from "react-dom";
|
|
3183
3135
|
import styled31 from "styled-components";
|
|
3184
3136
|
import { jsx as jsx32, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
@@ -3226,9 +3178,9 @@ var TrackMenu = ({
|
|
|
3226
3178
|
const close = () => setOpen(false);
|
|
3227
3179
|
const items = typeof itemsProp === "function" ? itemsProp(close) : itemsProp;
|
|
3228
3180
|
const [dropdownPos, setDropdownPos] = useState6({ top: 0, left: 0 });
|
|
3229
|
-
const buttonRef =
|
|
3230
|
-
const dropdownRef =
|
|
3231
|
-
|
|
3181
|
+
const buttonRef = useRef8(null);
|
|
3182
|
+
const dropdownRef = useRef8(null);
|
|
3183
|
+
useEffect7(() => {
|
|
3232
3184
|
if (open && buttonRef.current) {
|
|
3233
3185
|
const rect = buttonRef.current.getBoundingClientRect();
|
|
3234
3186
|
setDropdownPos({
|
|
@@ -3237,7 +3189,7 @@ var TrackMenu = ({
|
|
|
3237
3189
|
});
|
|
3238
3190
|
}
|
|
3239
3191
|
}, [open]);
|
|
3240
|
-
|
|
3192
|
+
useEffect7(() => {
|
|
3241
3193
|
if (!open) return;
|
|
3242
3194
|
const handleClick = (e) => {
|
|
3243
3195
|
const target = e.target;
|
|
@@ -3312,7 +3264,6 @@ export {
|
|
|
3312
3264
|
InlineLabel,
|
|
3313
3265
|
LoopRegion,
|
|
3314
3266
|
LoopRegionMarkers,
|
|
3315
|
-
MAX_CANVAS_WIDTH,
|
|
3316
3267
|
MasterVolumeControl,
|
|
3317
3268
|
Playhead,
|
|
3318
3269
|
PlayheadWithMarker,
|
|
@@ -3361,6 +3312,7 @@ export {
|
|
|
3361
3312
|
useScrollViewportSelector,
|
|
3362
3313
|
useTheme2 as useTheme,
|
|
3363
3314
|
useTrackControls,
|
|
3315
|
+
useVisibleChunkIndices,
|
|
3364
3316
|
waveformColorToCss
|
|
3365
3317
|
};
|
|
3366
3318
|
//# sourceMappingURL=index.mjs.map
|