wavesurfer.js 7.10.3 → 7.11.1
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/__tests__/renderer-utils.test.d.ts +1 -0
- package/dist/__tests__/renderer-utils.test.js +320 -0
- package/dist/decoder.js +30 -6
- package/dist/draggable.js +16 -5
- package/dist/event-emitter.js +7 -6
- package/dist/fetcher.js +14 -16
- package/dist/player.js +2 -1
- package/dist/plugins/envelope.cjs +1 -1
- package/dist/plugins/envelope.esm.js +1 -1
- package/dist/plugins/envelope.js +1 -1
- package/dist/plugins/envelope.min.js +1 -1
- package/dist/plugins/hover.cjs +1 -1
- package/dist/plugins/hover.d.ts +1 -1
- package/dist/plugins/hover.esm.js +1 -1
- package/dist/plugins/hover.js +1 -1
- package/dist/plugins/hover.min.js +1 -1
- package/dist/plugins/minimap.cjs +1 -1
- package/dist/plugins/minimap.d.ts +1 -0
- package/dist/plugins/minimap.esm.js +1 -1
- package/dist/plugins/minimap.js +1 -1
- package/dist/plugins/minimap.min.js +1 -1
- package/dist/plugins/record.cjs +1 -1
- package/dist/plugins/record.d.ts +1 -0
- package/dist/plugins/record.esm.js +1 -1
- package/dist/plugins/record.js +1 -1
- package/dist/plugins/record.min.js +1 -1
- package/dist/plugins/regions.cjs +1 -1
- package/dist/plugins/regions.d.ts +4 -2
- package/dist/plugins/regions.esm.js +1 -1
- package/dist/plugins/regions.js +1 -1
- package/dist/plugins/regions.min.js +1 -1
- package/dist/plugins/spectrogram-windowed.cjs +1 -1
- package/dist/plugins/spectrogram-windowed.esm.js +1 -1
- package/dist/plugins/spectrogram-windowed.js +1 -1
- package/dist/plugins/spectrogram-windowed.min.js +1 -1
- package/dist/plugins/spectrogram.cjs +1 -1
- package/dist/plugins/spectrogram.esm.js +1 -1
- package/dist/plugins/spectrogram.js +1 -1
- package/dist/plugins/spectrogram.min.js +1 -1
- package/dist/plugins/timeline.cjs +1 -1
- package/dist/plugins/timeline.d.ts +2 -0
- package/dist/plugins/timeline.esm.js +1 -1
- package/dist/plugins/timeline.js +1 -1
- package/dist/plugins/timeline.min.js +1 -1
- package/dist/plugins/zoom.cjs +1 -1
- package/dist/plugins/zoom.d.ts +10 -1
- package/dist/plugins/zoom.esm.js +1 -1
- package/dist/plugins/zoom.js +1 -1
- package/dist/plugins/zoom.min.js +1 -1
- package/dist/renderer-utils.d.ts +117 -0
- package/dist/renderer-utils.js +232 -0
- package/dist/renderer.d.ts +3 -3
- package/dist/renderer.js +133 -182
- package/dist/timer.d.ts +2 -1
- package/dist/timer.js +23 -9
- package/dist/types.d.ts +2 -0
- package/dist/wavesurfer.cjs +1 -1
- package/dist/wavesurfer.d.ts +2 -0
- package/dist/wavesurfer.esm.js +1 -1
- package/dist/wavesurfer.js +27 -10
- package/dist/wavesurfer.min.js +1 -1
- package/dist/webaudio.d.ts +4 -0
- package/dist/webaudio.js +13 -2
- package/package.json +6 -5
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
import { MAX_CANVAS_WIDTH, MAX_NODES, calculateBarHeights, calculateBarRenderConfig, calculateBarSegments, calculateLinePaths, calculateScrollPercentages, calculateSingleCanvasWidth, calculateVerticalScale, calculateWaveformLayout, clampToUnit, clampWidthToBarGrid, getLazyRenderRange, getPixelRatio, getRelativePointerPosition, resolveBarYPosition, resolveChannelHeight, resolveColorValue, shouldClearCanvases, shouldRenderBars, sliceChannelData, } from '../renderer-utils.js';
|
|
2
|
+
describe('renderer-utils', () => {
|
|
3
|
+
describe('clampToUnit', () => {
|
|
4
|
+
it('clamps numbers to the [0, 1] range', () => {
|
|
5
|
+
expect(clampToUnit(-0.5)).toBe(0);
|
|
6
|
+
expect(clampToUnit(0.3)).toBe(0.3);
|
|
7
|
+
expect(clampToUnit(1.8)).toBe(1);
|
|
8
|
+
});
|
|
9
|
+
});
|
|
10
|
+
describe('calculateBarRenderConfig', () => {
|
|
11
|
+
const options = {
|
|
12
|
+
container: document.createElement('div'),
|
|
13
|
+
barWidth: 2,
|
|
14
|
+
barGap: 1,
|
|
15
|
+
barRadius: 3,
|
|
16
|
+
};
|
|
17
|
+
it('derives spacing values and scaling information', () => {
|
|
18
|
+
const config = calculateBarRenderConfig({
|
|
19
|
+
width: 100,
|
|
20
|
+
height: 50,
|
|
21
|
+
length: 10,
|
|
22
|
+
options,
|
|
23
|
+
pixelRatio: 2,
|
|
24
|
+
});
|
|
25
|
+
expect(config).toEqual({
|
|
26
|
+
halfHeight: 25,
|
|
27
|
+
barWidth: 4,
|
|
28
|
+
barGap: 2,
|
|
29
|
+
barRadius: 3,
|
|
30
|
+
barIndexScale: 100 / ((4 + 2) * 10),
|
|
31
|
+
barSpacing: 6,
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
describe('calculateBarHeights', () => {
|
|
36
|
+
it('returns rounded heights and ensures total height is at least 1', () => {
|
|
37
|
+
expect(calculateBarHeights({
|
|
38
|
+
maxTop: 0.5,
|
|
39
|
+
maxBottom: 0.25,
|
|
40
|
+
halfHeight: 20,
|
|
41
|
+
vScale: 1,
|
|
42
|
+
})).toEqual({ topHeight: 10, totalHeight: 15 });
|
|
43
|
+
expect(calculateBarHeights({
|
|
44
|
+
maxTop: 0,
|
|
45
|
+
maxBottom: 0,
|
|
46
|
+
halfHeight: 20,
|
|
47
|
+
vScale: 1,
|
|
48
|
+
})).toEqual({ topHeight: 0, totalHeight: 1 });
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
describe('resolveBarYPosition', () => {
|
|
52
|
+
const baseArgs = {
|
|
53
|
+
halfHeight: 20,
|
|
54
|
+
topHeight: 10,
|
|
55
|
+
totalHeight: 20,
|
|
56
|
+
canvasHeight: 40,
|
|
57
|
+
};
|
|
58
|
+
it('positions bars relative to alignment', () => {
|
|
59
|
+
expect(resolveBarYPosition(Object.assign({ barAlign: 'top' }, baseArgs))).toBe(0);
|
|
60
|
+
expect(resolveBarYPosition(Object.assign({ barAlign: 'bottom' }, baseArgs))).toBe(20);
|
|
61
|
+
expect(resolveBarYPosition(Object.assign({ barAlign: undefined }, baseArgs))).toBe(10);
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
describe('calculateBarSegments', () => {
|
|
65
|
+
const options = {
|
|
66
|
+
container: document.createElement('div'),
|
|
67
|
+
};
|
|
68
|
+
it('aggregates bar segments across the channel data', () => {
|
|
69
|
+
const { barIndexScale, barSpacing, barWidth, halfHeight } = calculateBarRenderConfig({
|
|
70
|
+
width: 6,
|
|
71
|
+
height: 20,
|
|
72
|
+
length: 6,
|
|
73
|
+
options,
|
|
74
|
+
pixelRatio: 1,
|
|
75
|
+
});
|
|
76
|
+
const segments = calculateBarSegments({
|
|
77
|
+
channelData: [
|
|
78
|
+
new Float32Array([0.2, -0.4, 0.6, -0.8, 1, -1]),
|
|
79
|
+
new Float32Array([0.1, -0.2, 0.3, -0.4, 0.5, -0.6]),
|
|
80
|
+
],
|
|
81
|
+
barIndexScale,
|
|
82
|
+
barSpacing,
|
|
83
|
+
barWidth,
|
|
84
|
+
halfHeight,
|
|
85
|
+
vScale: 1,
|
|
86
|
+
canvasHeight: 40,
|
|
87
|
+
barAlign: undefined,
|
|
88
|
+
});
|
|
89
|
+
expect(segments).toEqual([
|
|
90
|
+
{ x: 0, y: 8, width: 1, height: 3 },
|
|
91
|
+
{ x: 1, y: 6, width: 1, height: 6 },
|
|
92
|
+
{ x: 2, y: 4, width: 1, height: 9 },
|
|
93
|
+
{ x: 3, y: 2, width: 1, height: 12 },
|
|
94
|
+
{ x: 4, y: 0, width: 1, height: 15 },
|
|
95
|
+
{ x: 5, y: 0, width: 1, height: 16 },
|
|
96
|
+
]);
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
describe('getRelativePointerPosition', () => {
|
|
100
|
+
it('returns pointer coordinates as relative offsets', () => {
|
|
101
|
+
const rect = {
|
|
102
|
+
left: 10,
|
|
103
|
+
top: 20,
|
|
104
|
+
width: 200,
|
|
105
|
+
height: 100,
|
|
106
|
+
};
|
|
107
|
+
expect(getRelativePointerPosition(rect, 110, 70)).toEqual([0.5, 0.5]);
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
describe('resolveChannelHeight', () => {
|
|
111
|
+
it('returns numeric height when provided', () => {
|
|
112
|
+
expect(resolveChannelHeight({
|
|
113
|
+
optionsHeight: 150,
|
|
114
|
+
parentHeight: 0,
|
|
115
|
+
numberOfChannels: 2,
|
|
116
|
+
})).toBe(150);
|
|
117
|
+
});
|
|
118
|
+
it('splits height across channels when auto with overlays disabled', () => {
|
|
119
|
+
const splitChannels = [{ overlay: false }, { overlay: false }];
|
|
120
|
+
expect(resolveChannelHeight({
|
|
121
|
+
optionsHeight: 'auto',
|
|
122
|
+
optionsSplitChannels: splitChannels,
|
|
123
|
+
parentHeight: 200,
|
|
124
|
+
numberOfChannels: 2,
|
|
125
|
+
})).toBe(100);
|
|
126
|
+
});
|
|
127
|
+
it('falls back to default height when invalid', () => {
|
|
128
|
+
expect(resolveChannelHeight({
|
|
129
|
+
optionsHeight: 'invalid',
|
|
130
|
+
parentHeight: 0,
|
|
131
|
+
numberOfChannels: 2,
|
|
132
|
+
defaultHeight: 75,
|
|
133
|
+
})).toBe(75);
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
describe('getPixelRatio', () => {
|
|
137
|
+
it('never returns less than 1', () => {
|
|
138
|
+
expect(getPixelRatio(undefined)).toBe(1);
|
|
139
|
+
expect(getPixelRatio(0.5)).toBe(1);
|
|
140
|
+
expect(getPixelRatio(2)).toBe(2);
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
describe('shouldRenderBars', () => {
|
|
144
|
+
const options = { container: document.createElement('div') };
|
|
145
|
+
it('returns true when any bar option is configured', () => {
|
|
146
|
+
expect(shouldRenderBars(Object.assign(Object.assign({}, options), { barWidth: 1 }))).toBe(true);
|
|
147
|
+
expect(shouldRenderBars(Object.assign(Object.assign({}, options), { barGap: 2 }))).toBe(true);
|
|
148
|
+
expect(shouldRenderBars(Object.assign(Object.assign({}, options), { barAlign: 'top' }))).toBe(true);
|
|
149
|
+
});
|
|
150
|
+
it('returns false when bars are not configured', () => {
|
|
151
|
+
expect(shouldRenderBars(options)).toBe(false);
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
describe('resolveColorValue', () => {
|
|
155
|
+
const canvas = document.createElement('canvas');
|
|
156
|
+
let createLinearGradient;
|
|
157
|
+
let addColorStop;
|
|
158
|
+
beforeEach(() => {
|
|
159
|
+
createLinearGradient = jest.fn(() => ({ addColorStop }));
|
|
160
|
+
addColorStop = jest.fn();
|
|
161
|
+
jest.spyOn(document, 'createElement').mockImplementation(() => canvas);
|
|
162
|
+
jest
|
|
163
|
+
.spyOn(canvas, 'getContext')
|
|
164
|
+
.mockImplementation(() => ({ createLinearGradient }));
|
|
165
|
+
});
|
|
166
|
+
afterEach(() => {
|
|
167
|
+
jest.restoreAllMocks();
|
|
168
|
+
});
|
|
169
|
+
it('returns string values unchanged', () => {
|
|
170
|
+
expect(resolveColorValue('#000', 2)).toBe('#000');
|
|
171
|
+
});
|
|
172
|
+
it('falls back to default gray when gradient list is empty', () => {
|
|
173
|
+
expect(resolveColorValue([], 2)).toBe('#999');
|
|
174
|
+
});
|
|
175
|
+
it('uses the single color when gradient list has one item', () => {
|
|
176
|
+
expect(resolveColorValue(['#111'], 2)).toBe('#111');
|
|
177
|
+
});
|
|
178
|
+
it('creates a canvas gradient for multiple colors', () => {
|
|
179
|
+
const gradient = resolveColorValue(['#000', '#fff'], 2);
|
|
180
|
+
expect(createLinearGradient).toHaveBeenCalledWith(0, 0, 0, 300);
|
|
181
|
+
expect(addColorStop).toHaveBeenCalledTimes(2);
|
|
182
|
+
expect(addColorStop).toHaveBeenNthCalledWith(1, 0, '#000');
|
|
183
|
+
expect(addColorStop).toHaveBeenNthCalledWith(2, 1, '#fff');
|
|
184
|
+
expect(gradient.addColorStop).toBe(addColorStop);
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
describe('calculateWaveformLayout', () => {
|
|
188
|
+
const baseArgs = {
|
|
189
|
+
duration: 2,
|
|
190
|
+
parentWidth: 300,
|
|
191
|
+
pixelRatio: 1,
|
|
192
|
+
};
|
|
193
|
+
it('uses parent width when not scrollable and fillParent is true', () => {
|
|
194
|
+
expect(calculateWaveformLayout(Object.assign(Object.assign({}, baseArgs), { minPxPerSec: 10, fillParent: true }))).toEqual({
|
|
195
|
+
scrollWidth: 20,
|
|
196
|
+
isScrollable: false,
|
|
197
|
+
useParentWidth: true,
|
|
198
|
+
width: 300,
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
it('uses scroll width when waveform exceeds parent width', () => {
|
|
202
|
+
expect(calculateWaveformLayout(Object.assign(Object.assign({}, baseArgs), { minPxPerSec: 500, fillParent: true }))).toEqual({
|
|
203
|
+
scrollWidth: 1000,
|
|
204
|
+
isScrollable: true,
|
|
205
|
+
useParentWidth: false,
|
|
206
|
+
width: 1000,
|
|
207
|
+
});
|
|
208
|
+
});
|
|
209
|
+
});
|
|
210
|
+
describe('clampWidthToBarGrid', () => {
|
|
211
|
+
const options = { container: document.createElement('div'), barWidth: 2, barGap: 1 };
|
|
212
|
+
it('returns original width when bars are disabled', () => {
|
|
213
|
+
expect(clampWidthToBarGrid(123, { container: document.createElement('div') })).toBe(123);
|
|
214
|
+
});
|
|
215
|
+
it('clamps width down to align with bar grid spacing', () => {
|
|
216
|
+
expect(clampWidthToBarGrid(10, options)).toBe(9);
|
|
217
|
+
});
|
|
218
|
+
});
|
|
219
|
+
describe('calculateSingleCanvasWidth', () => {
|
|
220
|
+
const options = { container: document.createElement('div'), barWidth: 2, barGap: 1 };
|
|
221
|
+
it('limits width by canvas cap, client size, and total width', () => {
|
|
222
|
+
expect(calculateSingleCanvasWidth({
|
|
223
|
+
clientWidth: 9000,
|
|
224
|
+
totalWidth: 5000,
|
|
225
|
+
options,
|
|
226
|
+
})).toBe(clampWidthToBarGrid(Math.min(MAX_CANVAS_WIDTH, 5000), options));
|
|
227
|
+
});
|
|
228
|
+
});
|
|
229
|
+
describe('sliceChannelData', () => {
|
|
230
|
+
it('returns proportional slices based on offset and width', () => {
|
|
231
|
+
const channel = new Float32Array([1, 2, 3, 4, 5, 6, 7, 8]);
|
|
232
|
+
const slices = sliceChannelData({
|
|
233
|
+
channelData: [channel, channel],
|
|
234
|
+
offset: 100,
|
|
235
|
+
clampedWidth: 50,
|
|
236
|
+
totalWidth: 200,
|
|
237
|
+
});
|
|
238
|
+
expect(slices[0]).toEqual(new Float32Array([5, 6]));
|
|
239
|
+
expect(slices[1]).toEqual(new Float32Array([5, 6]));
|
|
240
|
+
});
|
|
241
|
+
});
|
|
242
|
+
describe('shouldClearCanvases', () => {
|
|
243
|
+
it('clears when exceeding maximum nodes', () => {
|
|
244
|
+
expect(shouldClearCanvases(MAX_NODES)).toBe(false);
|
|
245
|
+
expect(shouldClearCanvases(MAX_NODES + 1)).toBe(true);
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
describe('getLazyRenderRange', () => {
|
|
249
|
+
it('returns surrounding canvas indices', () => {
|
|
250
|
+
expect(getLazyRenderRange({
|
|
251
|
+
scrollLeft: 50,
|
|
252
|
+
totalWidth: 200,
|
|
253
|
+
numCanvases: 5,
|
|
254
|
+
})).toEqual([0, 1, 2]);
|
|
255
|
+
});
|
|
256
|
+
it('defaults to the first canvas when width is zero', () => {
|
|
257
|
+
expect(getLazyRenderRange({ scrollLeft: 0, totalWidth: 0, numCanvases: 3 })).toEqual([0]);
|
|
258
|
+
});
|
|
259
|
+
});
|
|
260
|
+
describe('calculateVerticalScale', () => {
|
|
261
|
+
it('returns base scale when not normalizing', () => {
|
|
262
|
+
expect(calculateVerticalScale({
|
|
263
|
+
channelData: [new Float32Array([0.5])],
|
|
264
|
+
barHeight: 2,
|
|
265
|
+
normalize: false,
|
|
266
|
+
})).toBe(2);
|
|
267
|
+
});
|
|
268
|
+
it('normalizes against the maximum magnitude when requested', () => {
|
|
269
|
+
expect(calculateVerticalScale({
|
|
270
|
+
channelData: [new Float32Array([0.25, -0.5])],
|
|
271
|
+
barHeight: 2,
|
|
272
|
+
normalize: true,
|
|
273
|
+
})).toBe(4);
|
|
274
|
+
});
|
|
275
|
+
});
|
|
276
|
+
describe('calculateLinePaths', () => {
|
|
277
|
+
it('produces symmetrical paths for mirrored channel data', () => {
|
|
278
|
+
const [topPath, bottomPath] = calculateLinePaths({
|
|
279
|
+
channelData: [new Float32Array([0, 0.5, 1]), new Float32Array([0, 0.25, 0.75])],
|
|
280
|
+
width: 6,
|
|
281
|
+
height: 8,
|
|
282
|
+
vScale: 1,
|
|
283
|
+
});
|
|
284
|
+
expect(topPath[0]).toEqual({ x: 0, y: 4 });
|
|
285
|
+
expect(topPath[topPath.length - 1]).toEqual({ x: 6, y: 4 });
|
|
286
|
+
expect(bottomPath[0]).toEqual({ x: 0, y: 4 });
|
|
287
|
+
expect(bottomPath[bottomPath.length - 1]).toEqual({ x: 6, y: 4 });
|
|
288
|
+
expect(topPath).toEqual([
|
|
289
|
+
{ x: 0, y: 4 },
|
|
290
|
+
{ x: 0, y: 3 },
|
|
291
|
+
{ x: 2, y: 2 },
|
|
292
|
+
{ x: 4, y: 0 },
|
|
293
|
+
{ x: 6, y: 4 },
|
|
294
|
+
]);
|
|
295
|
+
expect(bottomPath).toEqual([
|
|
296
|
+
{ x: 0, y: 4 },
|
|
297
|
+
{ x: 0, y: 5 },
|
|
298
|
+
{ x: 2, y: 5 },
|
|
299
|
+
{ x: 4, y: 7 },
|
|
300
|
+
{ x: 6, y: 4 },
|
|
301
|
+
]);
|
|
302
|
+
});
|
|
303
|
+
});
|
|
304
|
+
describe('calculateScrollPercentages', () => {
|
|
305
|
+
it('returns zero percentages when scroll width is zero', () => {
|
|
306
|
+
expect(calculateScrollPercentages({
|
|
307
|
+
scrollLeft: 0,
|
|
308
|
+
clientWidth: 100,
|
|
309
|
+
scrollWidth: 0,
|
|
310
|
+
})).toEqual({ startX: 0, endX: 0 });
|
|
311
|
+
});
|
|
312
|
+
it('returns start and end ratios relative to scroll width', () => {
|
|
313
|
+
expect(calculateScrollPercentages({
|
|
314
|
+
scrollLeft: 50,
|
|
315
|
+
clientWidth: 100,
|
|
316
|
+
scrollWidth: 400,
|
|
317
|
+
})).toEqual({ startX: 0.125, endX: 0.375 });
|
|
318
|
+
});
|
|
319
|
+
});
|
|
320
|
+
});
|
package/dist/decoder.js
CHANGED
|
@@ -11,8 +11,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
11
11
|
function decode(audioData, sampleRate) {
|
|
12
12
|
return __awaiter(this, void 0, void 0, function* () {
|
|
13
13
|
const audioCtx = new AudioContext({ sampleRate });
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
try {
|
|
15
|
+
return yield audioCtx.decodeAudioData(audioData);
|
|
16
|
+
}
|
|
17
|
+
finally {
|
|
18
|
+
// Ensure AudioContext is always closed, even on synchronous errors
|
|
19
|
+
audioCtx.close();
|
|
20
|
+
}
|
|
16
21
|
});
|
|
17
22
|
}
|
|
18
23
|
/** Normalize peaks to -1..1 */
|
|
@@ -36,17 +41,36 @@ function normalize(channelData) {
|
|
|
36
41
|
}
|
|
37
42
|
/** Create an audio buffer from pre-decoded audio data */
|
|
38
43
|
function createBuffer(channelData, duration) {
|
|
44
|
+
// Validate inputs
|
|
45
|
+
if (!channelData || channelData.length === 0) {
|
|
46
|
+
throw new Error('channelData must be a non-empty array');
|
|
47
|
+
}
|
|
48
|
+
if (duration <= 0) {
|
|
49
|
+
throw new Error('duration must be greater than 0');
|
|
50
|
+
}
|
|
39
51
|
// If a single array of numbers is passed, make it an array of arrays
|
|
40
52
|
if (typeof channelData[0] === 'number')
|
|
41
53
|
channelData = [channelData];
|
|
54
|
+
// Validate channel data after conversion
|
|
55
|
+
if (!channelData[0] || channelData[0].length === 0) {
|
|
56
|
+
throw new Error('channelData must contain non-empty channel arrays');
|
|
57
|
+
}
|
|
42
58
|
// Normalize to -1..1
|
|
43
59
|
normalize(channelData);
|
|
60
|
+
// Convert to Float32Array for consistency
|
|
61
|
+
const float32Channels = channelData.map((channel) => channel instanceof Float32Array ? channel : Float32Array.from(channel));
|
|
44
62
|
return {
|
|
45
63
|
duration,
|
|
46
|
-
length:
|
|
47
|
-
sampleRate:
|
|
48
|
-
numberOfChannels:
|
|
49
|
-
getChannelData: (i) =>
|
|
64
|
+
length: float32Channels[0].length,
|
|
65
|
+
sampleRate: float32Channels[0].length / duration,
|
|
66
|
+
numberOfChannels: float32Channels.length,
|
|
67
|
+
getChannelData: (i) => {
|
|
68
|
+
const channel = float32Channels[i];
|
|
69
|
+
if (!channel) {
|
|
70
|
+
throw new Error(`Channel ${i} not found`);
|
|
71
|
+
}
|
|
72
|
+
return channel;
|
|
73
|
+
},
|
|
50
74
|
copyFromChannel: AudioBuffer.prototype.copyFromChannel,
|
|
51
75
|
copyToChannel: AudioBuffer.prototype.copyToChannel,
|
|
52
76
|
};
|
package/dist/draggable.js
CHANGED
|
@@ -1,20 +1,24 @@
|
|
|
1
1
|
export function makeDraggable(element, onDrag, onStart, onEnd, threshold = 3, mouseButton = 0, touchDelay = 100) {
|
|
2
2
|
if (!element)
|
|
3
3
|
return () => void 0;
|
|
4
|
+
const activePointers = new Map();
|
|
4
5
|
const isTouchDevice = matchMedia('(pointer: coarse)').matches;
|
|
5
6
|
let unsubscribeDocument = () => void 0;
|
|
6
7
|
const onPointerDown = (event) => {
|
|
7
8
|
if (event.button !== mouseButton)
|
|
8
9
|
return;
|
|
9
|
-
event.
|
|
10
|
-
|
|
10
|
+
activePointers.set(event.pointerId, event);
|
|
11
|
+
if (activePointers.size > 1) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
11
14
|
let startX = event.clientX;
|
|
12
15
|
let startY = event.clientY;
|
|
13
16
|
let isDragging = false;
|
|
14
17
|
const touchStartTime = Date.now();
|
|
15
18
|
const onPointerMove = (event) => {
|
|
16
|
-
event.
|
|
17
|
-
|
|
19
|
+
if (event.defaultPrevented || activePointers.size > 1) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
18
22
|
if (isTouchDevice && Date.now() - touchStartTime < touchDelay)
|
|
19
23
|
return;
|
|
20
24
|
const x = event.clientX;
|
|
@@ -22,6 +26,8 @@ export function makeDraggable(element, onDrag, onStart, onEnd, threshold = 3, mo
|
|
|
22
26
|
const dx = x - startX;
|
|
23
27
|
const dy = y - startY;
|
|
24
28
|
if (isDragging || Math.abs(dx) > threshold || Math.abs(dy) > threshold) {
|
|
29
|
+
event.preventDefault();
|
|
30
|
+
event.stopPropagation();
|
|
25
31
|
const rect = element.getBoundingClientRect();
|
|
26
32
|
const { left, top } = rect;
|
|
27
33
|
if (!isDragging) {
|
|
@@ -34,6 +40,7 @@ export function makeDraggable(element, onDrag, onStart, onEnd, threshold = 3, mo
|
|
|
34
40
|
}
|
|
35
41
|
};
|
|
36
42
|
const onPointerUp = (event) => {
|
|
43
|
+
activePointers.delete(event.pointerId);
|
|
37
44
|
if (isDragging) {
|
|
38
45
|
const x = event.clientX;
|
|
39
46
|
const y = event.clientY;
|
|
@@ -44,7 +51,7 @@ export function makeDraggable(element, onDrag, onStart, onEnd, threshold = 3, mo
|
|
|
44
51
|
unsubscribeDocument();
|
|
45
52
|
};
|
|
46
53
|
const onPointerLeave = (e) => {
|
|
47
|
-
|
|
54
|
+
activePointers.delete(e.pointerId);
|
|
48
55
|
if (!e.relatedTarget || e.relatedTarget === document.documentElement) {
|
|
49
56
|
onPointerUp(e);
|
|
50
57
|
}
|
|
@@ -56,6 +63,9 @@ export function makeDraggable(element, onDrag, onStart, onEnd, threshold = 3, mo
|
|
|
56
63
|
}
|
|
57
64
|
};
|
|
58
65
|
const onTouchMove = (event) => {
|
|
66
|
+
if (event.defaultPrevented || activePointers.size > 1) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
59
69
|
if (isDragging) {
|
|
60
70
|
event.preventDefault();
|
|
61
71
|
}
|
|
@@ -81,5 +91,6 @@ export function makeDraggable(element, onDrag, onStart, onEnd, threshold = 3, mo
|
|
|
81
91
|
return () => {
|
|
82
92
|
unsubscribeDocument();
|
|
83
93
|
element.removeEventListener('pointerdown', onPointerDown);
|
|
94
|
+
activePointers.clear();
|
|
84
95
|
};
|
|
85
96
|
}
|
package/dist/event-emitter.js
CHANGED
|
@@ -8,15 +8,16 @@ class EventEmitter {
|
|
|
8
8
|
if (!this.listeners[event]) {
|
|
9
9
|
this.listeners[event] = new Set();
|
|
10
10
|
}
|
|
11
|
-
this.listeners[event].add(listener);
|
|
12
11
|
if (options === null || options === void 0 ? void 0 : options.once) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
this.un(event,
|
|
12
|
+
// Create a wrapper that removes itself after being called once
|
|
13
|
+
const onceWrapper = (...args) => {
|
|
14
|
+
this.un(event, onceWrapper);
|
|
15
|
+
listener(...args);
|
|
16
16
|
};
|
|
17
|
-
this.
|
|
18
|
-
return
|
|
17
|
+
this.listeners[event].add(onceWrapper);
|
|
18
|
+
return () => this.un(event, onceWrapper);
|
|
19
19
|
}
|
|
20
|
+
this.listeners[event].add(listener);
|
|
20
21
|
return () => this.un(event, listener);
|
|
21
22
|
}
|
|
22
23
|
/** Unsubscribe from an event */
|
package/dist/fetcher.js
CHANGED
|
@@ -15,28 +15,26 @@ function watchProgress(response, progressCallback) {
|
|
|
15
15
|
const contentLength = Number(response.headers.get('Content-Length')) || 0;
|
|
16
16
|
let receivedLength = 0;
|
|
17
17
|
// Process the data
|
|
18
|
-
const processChunk = (value) =>
|
|
18
|
+
const processChunk = (value) => {
|
|
19
19
|
// Add to the received length
|
|
20
20
|
receivedLength += (value === null || value === void 0 ? void 0 : value.length) || 0;
|
|
21
21
|
const percentage = Math.round((receivedLength / contentLength) * 100);
|
|
22
22
|
progressCallback(percentage);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
data = yield reader.read();
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
|
-
// Continue reading data until done
|
|
34
|
-
if (!data.done) {
|
|
23
|
+
};
|
|
24
|
+
// Use iteration instead of recursion to avoid stack issues
|
|
25
|
+
try {
|
|
26
|
+
while (true) {
|
|
27
|
+
const data = yield reader.read();
|
|
28
|
+
if (data.done) {
|
|
29
|
+
break;
|
|
30
|
+
}
|
|
35
31
|
processChunk(data.value);
|
|
36
|
-
yield read();
|
|
37
32
|
}
|
|
38
|
-
}
|
|
39
|
-
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
// Ignore errors because we can only handle the main response
|
|
36
|
+
console.warn('Progress tracking error:', err);
|
|
37
|
+
}
|
|
40
38
|
});
|
|
41
39
|
}
|
|
42
40
|
function fetchBlob(url, progressCallback, requestInit) {
|
package/dist/player.js
CHANGED
|
@@ -75,11 +75,12 @@ class Player extends EventEmitter {
|
|
|
75
75
|
if (this.isExternalMedia)
|
|
76
76
|
return;
|
|
77
77
|
this.media.pause();
|
|
78
|
-
this.media.remove();
|
|
79
78
|
this.revokeSrc();
|
|
80
79
|
this.media.removeAttribute('src');
|
|
81
80
|
// Load resets the media element to its initial state
|
|
82
81
|
this.media.load();
|
|
82
|
+
// Remove from DOM after cleanup
|
|
83
|
+
this.media.remove();
|
|
83
84
|
}
|
|
84
85
|
setMediaElement(element) {
|
|
85
86
|
this.media = element;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";class t{constructor(){this.listeners={}}on(t,e,i){if(this.listeners[t]||(this.listeners[t]=new Set),this.listeners[t].add(e),null==i?void 0:i.once){const i=()=>{this.un(t,i),this.un(t,e)};return this.on(t,i),i}return()=>this.un(t,e)}un(t,e){var i;null===(i=this.listeners[t])||void 0===i||i.delete(e)}once(t,e){return this.on(t,e,{once:!0})}unAll(){this.listeners={}}emit(t,...e){this.listeners[t]&&this.listeners[t].forEach((t=>t(...e)))}}class e extends t{constructor(t){super(),this.subscriptions=[],this.isDestroyed=!1,this.options=t}onInit(){}_init(t){this.isDestroyed&&(this.subscriptions=[],this.isDestroyed=!1),this.wavesurfer=t,this.onInit()}destroy(){this.emit("destroy"),this.subscriptions.forEach((t=>t())),this.subscriptions=[],this.isDestroyed=!0,this.wavesurfer=void 0}}function i(t,e,i,o,n=3,s=0,r=100){if(!t)return()=>{};const l=matchMedia("(pointer: coarse)").matches;let h=()=>{};const a=a=>{if(a.button!==s)return;a.preventDefault(),a.stopPropagation();let u=a.clientX,c=a.clientY,d=!1;const p=Date.now(),m=o=>{if(o.preventDefault(),o.stopPropagation(),l&&Date.now()-p<r)return;const s=o.clientX,h=o.clientY,a=s-u,m=h-c;if(d||Math.abs(a)>n||Math.abs(m)>n){const o=t.getBoundingClientRect(),{left:n,top:r}=o;d||(null==i||i(u-n,c-r),d=!0),e(a,m,s-n,h-r),u=s,c=h}},v=e=>{if(d){const i=e.clientX,n=e.clientY,s=t.getBoundingClientRect(),{left:r,top:l}=s;null==o||o(i-r,n-l)}h()},g=t=>{t.relatedTarget&&t.relatedTarget!==document.documentElement||v(t)},f=t=>{d&&(t.stopPropagation(),t.preventDefault())},y=t=>{d&&t.preventDefault()};document.addEventListener("pointermove",m),document.addEventListener("pointerup",v),document.addEventListener("pointerout",g),document.addEventListener("pointercancel",g),document.addEventListener("touchmove",y,{passive:!1}),document.addEventListener("click",f,{capture:!0}),h=()=>{document.removeEventListener("pointermove",m),document.removeEventListener("pointerup",v),document.removeEventListener("pointerout",g),document.removeEventListener("pointercancel",g),document.removeEventListener("touchmove",y),setTimeout((()=>{document.removeEventListener("click",f,{capture:!0})}),10)}};return t.addEventListener("pointerdown",a),()=>{h(),t.removeEventListener("pointerdown",a)}}function o(t,e){const i=e.xmlns?document.createElementNS(e.xmlns,t):document.createElement(t);for(const[t,n]of Object.entries(e))if("children"===t&&n)for(const[t,e]of Object.entries(n))e instanceof Node?i.appendChild(e):"string"==typeof e?i.appendChild(document.createTextNode(e)):i.appendChild(o(t,e));else"style"===t?Object.assign(i.style,n):"textContent"===t?i.textContent=n:i.setAttribute(t,n.toString());return i}function n(t,e,i){const n=o(t,e||{});return null==i||i.appendChild(n),n}const s={points:[],lineWidth:4,lineColor:"rgba(0, 0, 255, 0.5)",dragPointSize:10,dragPointFill:"rgba(255, 255, 255, 0.8)",dragPointStroke:"rgba(255, 255, 255, 0.8)"};class r extends t{constructor(t,e){super(),this.subscriptions=[],this.subscriptions=[],this.options=t,this.polyPoints=new Map;const o=e.clientWidth,s=e.clientHeight,r=n("svg",{xmlns:"http://www.w3.org/2000/svg",width:"100%",height:"100%",viewBox:`0 0 ${o} ${s}`,preserveAspectRatio:"none",style:{position:"absolute",left:"0",top:"0",zIndex:"4"},part:"envelope"},e);this.svg=r;const l=n("polyline",{xmlns:"http://www.w3.org/2000/svg",points:`0,${s} ${o},${s}`,stroke:t.lineColor,"stroke-width":t.lineWidth,fill:"none",part:"polyline",style:t.dragLine?{cursor:"row-resize",pointerEvents:"stroke"}:{}},r);t.dragLine&&this.subscriptions.push(i(l,((t,e)=>{const{height:i}=r.viewBox.baseVal,{points:o}=l;for(let t=1;t<o.numberOfItems-1;t++){const n=o.getItem(t);n.y=Math.min(i,Math.max(0,n.y+e))}const n=r.querySelectorAll("ellipse");Array.from(n).forEach((t=>{const o=Math.min(i,Math.max(0,Number(t.getAttribute("cy"))+e));t.setAttribute("cy",o.toString())})),this.emit("line-move",e/i)}))),r.addEventListener("dblclick",(t=>{const e=r.getBoundingClientRect(),i=t.clientX-e.left,o=t.clientY-e.top;this.emit("point-create",i/e.width,o/e.height)}));{let t;const e=()=>clearTimeout(t);r.addEventListener("touchstart",(i=>{1===i.touches.length?t=window.setTimeout((()=>{i.preventDefault();const t=r.getBoundingClientRect(),e=i.touches[0].clientX-t.left,o=i.touches[0].clientY-t.top;this.emit("point-create",e/t.width,o/t.height)}),500):e()})),r.addEventListener("touchmove",e),r.addEventListener("touchend",e)}}makeDraggable(t,e){this.subscriptions.push(i(t,e,(()=>t.style.cursor="grabbing"),(()=>t.style.cursor="grab"),1))}createCircle(t,e){const i=this.options.dragPointSize/2;return n("ellipse",{xmlns:"http://www.w3.org/2000/svg",cx:t,cy:e,rx:i,ry:i,fill:this.options.dragPointFill,stroke:this.options.dragPointStroke,"stroke-width":"2",style:{cursor:"grab",pointerEvents:"all"},part:"envelope-circle"},this.svg)}removePolyPoint(t){const e=this.polyPoints.get(t);if(!e)return;const{polyPoint:i,circle:o}=e,{points:n}=this.svg.querySelector("polyline"),s=Array.from(n).findIndex((t=>t.x===i.x&&t.y===i.y));n.removeItem(s),o.remove(),this.polyPoints.delete(t)}addPolyPoint(t,e,i){const{svg:o}=this,{width:n,height:s}=o.viewBox.baseVal,r=t*n,l=s-e*s,h=this.options.dragPointSize/2,a=o.createSVGPoint();a.x=t*n,a.y=s-e*s;const u=this.createCircle(r,l),{points:c}=o.querySelector("polyline"),d=Array.from(c).findIndex((t=>t.x>=r));c.insertItemBefore(a,Math.max(d,1)),this.polyPoints.set(i,{polyPoint:a,circle:u}),this.makeDraggable(u,((t,e)=>{const o=a.x+t,r=a.y+e;if(o<-h||r<-h||o>n+h||r>s+h)return void this.emit("point-dragout",i);const l=Array.from(c).find((t=>t.x>a.x)),d=Array.from(c).findLast((t=>t.x<a.x));l&&o>=l.x||d&&o<=d.x||(a.x=o,a.y=r,u.setAttribute("cx",o.toString()),u.setAttribute("cy",r.toString()),this.emit("point-move",i,o/n,r/s))}))}update(){const{svg:t}=this,{clientWidth:e,clientHeight:i}=t;if(!e||!i)return;const o=t.viewBox.baseVal.width/e,n=t.viewBox.baseVal.height/i;t.querySelectorAll("ellipse").forEach((t=>{const e=this.options.dragPointSize/2,i=e*o,s=e*n;t.setAttribute("rx",i.toString()),t.setAttribute("ry",s.toString())}))}destroy(){this.subscriptions.forEach((t=>t())),this.polyPoints.clear(),this.svg.remove()}}class l extends e{constructor(t){super(t),this.polyline=null,this.throttleTimeout=null,this.volume=1,this.points=t.points||[],this.options=Object.assign({},s,t),this.options.lineColor=this.options.lineColor||s.lineColor,this.options.dragPointFill=this.options.dragPointFill||s.dragPointFill,this.options.dragPointStroke=this.options.dragPointStroke||s.dragPointStroke,this.options.dragPointSize=this.options.dragPointSize||s.dragPointSize}static create(t){return new l(t)}addPoint(t){var e;t.id||(t.id=Math.random().toString(36).slice(2));const i=this.points.findLastIndex((e=>e.time<t.time));this.points.splice(i+1,0,t),this.emitPoints();const o=null===(e=this.wavesurfer)||void 0===e?void 0:e.getDuration();o&&this.addPolyPoint(t,o)}removePoint(t){var e;const i=this.points.indexOf(t);i>-1&&(this.points.splice(i,1),null===(e=this.polyline)||void 0===e||e.removePolyPoint(t),this.emitPoints())}getPoints(){return this.points}setPoints(t){this.points.slice().forEach((t=>this.removePoint(t))),t.forEach((t=>this.addPoint(t)))}destroy(){var t;null===(t=this.polyline)||void 0===t||t.destroy(),super.destroy()}getCurrentVolume(){return this.volume}setVolume(t){var e;this.volume=t,null===(e=this.wavesurfer)||void 0===e||e.setVolume(t)}onInit(){var t;if(!this.wavesurfer)throw Error("WaveSurfer is not initialized");const{options:e}=this;e.volume=null!==(t=e.volume)&&void 0!==t?t:this.wavesurfer.getVolume(),this.setVolume(e.volume),this.subscriptions.push(this.wavesurfer.on("decode",(t=>{this.initPolyline(),this.points.forEach((e=>{this.addPolyPoint(e,t)}))})),this.wavesurfer.on("redraw",(()=>{var t;null===(t=this.polyline)||void 0===t||t.update()})),this.wavesurfer.on("timeupdate",(t=>{this.onTimeUpdate(t)})))}emitPoints(){this.throttleTimeout&&clearTimeout(this.throttleTimeout),this.throttleTimeout=setTimeout((()=>{this.emit("points-change",this.points)}),200)}initPolyline(){if(this.polyline&&this.polyline.destroy(),!this.wavesurfer)return;const t=this.wavesurfer.getWrapper();this.polyline=new r(this.options,t),this.subscriptions.push(this.polyline.on("point-move",((t,e,i)=>{var o;const n=(null===(o=this.wavesurfer)||void 0===o?void 0:o.getDuration())||0;t.time=e*n,t.volume=1-i,this.emitPoints()})),this.polyline.on("point-dragout",(t=>{this.removePoint(t)})),this.polyline.on("point-create",((t,e)=>{var i;this.addPoint({time:t*((null===(i=this.wavesurfer)||void 0===i?void 0:i.getDuration())||0),volume:1-e})})),this.polyline.on("line-move",(t=>{var e;this.points.forEach((e=>{e.volume=Math.min(1,Math.max(0,e.volume-t))})),this.emitPoints(),this.onTimeUpdate((null===(e=this.wavesurfer)||void 0===e?void 0:e.getCurrentTime())||0)})))}addPolyPoint(t,e){var i;null===(i=this.polyline)||void 0===i||i.addPolyPoint(t.time/e,t.volume,t)}onTimeUpdate(t){if(!this.wavesurfer)return;let e=this.points.find((e=>e.time>t));e||(e={time:this.wavesurfer.getDuration()||0,volume:0});let i=this.points.findLast((e=>e.time<=t));i||(i={time:0,volume:0});const o=e.time-i.time,n=e.volume-i.volume,s=i.volume+(t-i.time)*(n/o),r=Math.min(1,Math.max(0,s)),l=Math.round(100*r)/100;l!==this.getCurrentVolume()&&(this.setVolume(l),this.emit("volume-change",l))}}module.exports=l;
|
|
1
|
+
"use strict";class t{constructor(){this.listeners={}}on(t,e,i){if(this.listeners[t]||(this.listeners[t]=new Set),null==i?void 0:i.once){const i=(...s)=>{this.un(t,i),e(...s)};return this.listeners[t].add(i),()=>this.un(t,i)}return this.listeners[t].add(e),()=>this.un(t,e)}un(t,e){var i;null===(i=this.listeners[t])||void 0===i||i.delete(e)}once(t,e){return this.on(t,e,{once:!0})}unAll(){this.listeners={}}emit(t,...e){this.listeners[t]&&this.listeners[t].forEach((t=>t(...e)))}}class e extends t{constructor(t){super(),this.subscriptions=[],this.isDestroyed=!1,this.options=t}onInit(){}_init(t){this.isDestroyed&&(this.subscriptions=[],this.isDestroyed=!1),this.wavesurfer=t,this.onInit()}destroy(){this.emit("destroy"),this.subscriptions.forEach((t=>t())),this.subscriptions=[],this.isDestroyed=!0,this.wavesurfer=void 0}}function i(t,e,i,s,o=3,n=0,r=100){if(!t)return()=>{};const l=new Map,h=matchMedia("(pointer: coarse)").matches;let u=()=>{};const c=c=>{if(c.button!==n)return;if(l.set(c.pointerId,c),l.size>1)return;let a=c.clientX,d=c.clientY,p=!1;const v=Date.now(),m=s=>{if(s.defaultPrevented||l.size>1)return;if(h&&Date.now()-v<r)return;const n=s.clientX,u=s.clientY,c=n-a,m=u-d;if(p||Math.abs(c)>o||Math.abs(m)>o){s.preventDefault(),s.stopPropagation();const o=t.getBoundingClientRect(),{left:r,top:l}=o;p||(null==i||i(a-r,d-l),p=!0),e(c,m,n-r,u-l),a=n,d=u}},g=e=>{if(l.delete(e.pointerId),p){const i=e.clientX,o=e.clientY,n=t.getBoundingClientRect(),{left:r,top:l}=n;null==s||s(i-r,o-l)}u()},f=t=>{l.delete(t.pointerId),t.relatedTarget&&t.relatedTarget!==document.documentElement||g(t)},y=t=>{p&&(t.stopPropagation(),t.preventDefault())},P=t=>{t.defaultPrevented||l.size>1||p&&t.preventDefault()};document.addEventListener("pointermove",m),document.addEventListener("pointerup",g),document.addEventListener("pointerout",f),document.addEventListener("pointercancel",f),document.addEventListener("touchmove",P,{passive:!1}),document.addEventListener("click",y,{capture:!0}),u=()=>{document.removeEventListener("pointermove",m),document.removeEventListener("pointerup",g),document.removeEventListener("pointerout",f),document.removeEventListener("pointercancel",f),document.removeEventListener("touchmove",P),setTimeout((()=>{document.removeEventListener("click",y,{capture:!0})}),10)}};return t.addEventListener("pointerdown",c),()=>{u(),t.removeEventListener("pointerdown",c),l.clear()}}function s(t,e){const i=e.xmlns?document.createElementNS(e.xmlns,t):document.createElement(t);for(const[t,o]of Object.entries(e))if("children"===t&&o)for(const[t,e]of Object.entries(o))e instanceof Node?i.appendChild(e):"string"==typeof e?i.appendChild(document.createTextNode(e)):i.appendChild(s(t,e));else"style"===t?Object.assign(i.style,o):"textContent"===t?i.textContent=o:i.setAttribute(t,o.toString());return i}function o(t,e,i){const o=s(t,e||{});return null==i||i.appendChild(o),o}const n={points:[],lineWidth:4,lineColor:"rgba(0, 0, 255, 0.5)",dragPointSize:10,dragPointFill:"rgba(255, 255, 255, 0.8)",dragPointStroke:"rgba(255, 255, 255, 0.8)"};class r extends t{constructor(t,e){super(),this.subscriptions=[],this.subscriptions=[],this.options=t,this.polyPoints=new Map;const s=e.clientWidth,n=e.clientHeight,r=o("svg",{xmlns:"http://www.w3.org/2000/svg",width:"100%",height:"100%",viewBox:`0 0 ${s} ${n}`,preserveAspectRatio:"none",style:{position:"absolute",left:"0",top:"0",zIndex:"4"},part:"envelope"},e);this.svg=r;const l=o("polyline",{xmlns:"http://www.w3.org/2000/svg",points:`0,${n} ${s},${n}`,stroke:t.lineColor,"stroke-width":t.lineWidth,fill:"none",part:"polyline",style:t.dragLine?{cursor:"row-resize",pointerEvents:"stroke"}:{}},r);t.dragLine&&this.subscriptions.push(i(l,((t,e)=>{const{height:i}=r.viewBox.baseVal,{points:s}=l;for(let t=1;t<s.numberOfItems-1;t++){const o=s.getItem(t);o.y=Math.min(i,Math.max(0,o.y+e))}const o=r.querySelectorAll("ellipse");Array.from(o).forEach((t=>{const s=Math.min(i,Math.max(0,Number(t.getAttribute("cy"))+e));t.setAttribute("cy",s.toString())})),this.emit("line-move",e/i)}))),this.dblClickListener=t=>{const e=r.getBoundingClientRect(),i=t.clientX-e.left,s=t.clientY-e.top;this.emit("point-create",i/e.width,s/e.height)},r.addEventListener("dblclick",this.dblClickListener);const h=()=>{void 0!==this.pressTimer&&(clearTimeout(this.pressTimer),this.pressTimer=void 0)};this.touchStartListener=t=>{1===t.touches.length?this.pressTimer=window.setTimeout((()=>{t.preventDefault();const e=r.getBoundingClientRect(),i=t.touches[0].clientX-e.left,s=t.touches[0].clientY-e.top;this.emit("point-create",i/e.width,s/e.height)}),500):h()},this.touchMoveListener=h,this.touchEndListener=h,r.addEventListener("touchstart",this.touchStartListener),r.addEventListener("touchmove",this.touchMoveListener),r.addEventListener("touchend",this.touchEndListener)}makeDraggable(t,e){this.subscriptions.push(i(t,e,(()=>t.style.cursor="grabbing"),(()=>t.style.cursor="grab"),1))}createCircle(t,e){const i=this.options.dragPointSize/2;return o("ellipse",{xmlns:"http://www.w3.org/2000/svg",cx:t,cy:e,rx:i,ry:i,fill:this.options.dragPointFill,stroke:this.options.dragPointStroke,"stroke-width":"2",style:{cursor:"grab",pointerEvents:"all"},part:"envelope-circle"},this.svg)}removePolyPoint(t){const e=this.polyPoints.get(t);if(!e)return;const{polyPoint:i,circle:s}=e,{points:o}=this.svg.querySelector("polyline"),n=Array.from(o).findIndex((t=>t.x===i.x&&t.y===i.y));o.removeItem(n),s.remove(),this.polyPoints.delete(t)}addPolyPoint(t,e,i){const{svg:s}=this,{width:o,height:n}=s.viewBox.baseVal,r=t*o,l=n-e*n,h=this.options.dragPointSize/2,u=s.createSVGPoint();u.x=t*o,u.y=n-e*n;const c=this.createCircle(r,l),{points:a}=s.querySelector("polyline"),d=Array.from(a).findIndex((t=>t.x>=r));a.insertItemBefore(u,Math.max(d,1)),this.polyPoints.set(i,{polyPoint:u,circle:c}),this.makeDraggable(c,((t,e)=>{const s=u.x+t,r=u.y+e;if(s<-h||r<-h||s>o+h||r>n+h)return void this.emit("point-dragout",i);const l=Array.from(a).find((t=>t.x>u.x)),d=Array.from(a).findLast((t=>t.x<u.x));l&&s>=l.x||d&&s<=d.x||(u.x=s,u.y=r,c.setAttribute("cx",s.toString()),c.setAttribute("cy",r.toString()),this.emit("point-move",i,s/o,r/n))}))}update(){const{svg:t}=this,{clientWidth:e,clientHeight:i}=t;if(!e||!i)return;const s=t.viewBox.baseVal.width/e,o=t.viewBox.baseVal.height/i;t.querySelectorAll("ellipse").forEach((t=>{const e=this.options.dragPointSize/2,i=e*s,n=e*o;t.setAttribute("rx",i.toString()),t.setAttribute("ry",n.toString())}))}destroy(){void 0!==this.pressTimer&&(clearTimeout(this.pressTimer),this.pressTimer=void 0),this.dblClickListener&&(this.svg.removeEventListener("dblclick",this.dblClickListener),this.dblClickListener=void 0),this.touchStartListener&&(this.svg.removeEventListener("touchstart",this.touchStartListener),this.touchStartListener=void 0),this.touchMoveListener&&(this.svg.removeEventListener("touchmove",this.touchMoveListener),this.touchMoveListener=void 0),this.touchEndListener&&(this.svg.removeEventListener("touchend",this.touchEndListener),this.touchEndListener=void 0),this.subscriptions.forEach((t=>t())),this.polyPoints.clear(),this.svg.remove()}}class l extends e{constructor(t){super(t),this.polyline=null,this.throttleTimeout=null,this.volume=1,this.points=t.points||[],this.options=Object.assign({},n,t),this.options.lineColor=this.options.lineColor||n.lineColor,this.options.dragPointFill=this.options.dragPointFill||n.dragPointFill,this.options.dragPointStroke=this.options.dragPointStroke||n.dragPointStroke,this.options.dragPointSize=this.options.dragPointSize||n.dragPointSize}static create(t){return new l(t)}addPoint(t){var e;t.id||(t.id=Math.random().toString(36).slice(2));const i=this.points.findLastIndex((e=>e.time<t.time));this.points.splice(i+1,0,t),this.emitPoints();const s=null===(e=this.wavesurfer)||void 0===e?void 0:e.getDuration();s&&this.addPolyPoint(t,s)}removePoint(t){var e;const i=this.points.indexOf(t);i>-1&&(this.points.splice(i,1),null===(e=this.polyline)||void 0===e||e.removePolyPoint(t),this.emitPoints())}getPoints(){return this.points}setPoints(t){this.points.slice().forEach((t=>this.removePoint(t))),t.forEach((t=>this.addPoint(t)))}destroy(){var t;this.throttleTimeout&&(clearTimeout(this.throttleTimeout),this.throttleTimeout=null),null===(t=this.polyline)||void 0===t||t.destroy(),super.destroy()}getCurrentVolume(){return this.volume}setVolume(t){var e;this.volume=t,null===(e=this.wavesurfer)||void 0===e||e.setVolume(t)}onInit(){var t;if(!this.wavesurfer)throw Error("WaveSurfer is not initialized");const{options:e}=this;e.volume=null!==(t=e.volume)&&void 0!==t?t:this.wavesurfer.getVolume(),this.setVolume(e.volume),this.subscriptions.push(this.wavesurfer.on("decode",(t=>{this.initPolyline(),this.points.forEach((e=>{this.addPolyPoint(e,t)}))})),this.wavesurfer.on("redraw",(()=>{var t;null===(t=this.polyline)||void 0===t||t.update()})),this.wavesurfer.on("timeupdate",(t=>{this.onTimeUpdate(t)})))}emitPoints(){this.throttleTimeout&&clearTimeout(this.throttleTimeout),this.throttleTimeout=setTimeout((()=>{this.emit("points-change",this.points)}),200)}initPolyline(){if(this.polyline&&this.polyline.destroy(),!this.wavesurfer)return;const t=this.wavesurfer.getWrapper();this.polyline=new r(this.options,t),this.subscriptions.push(this.polyline.on("point-move",((t,e,i)=>{var s;const o=(null===(s=this.wavesurfer)||void 0===s?void 0:s.getDuration())||0;t.time=e*o,t.volume=1-i,this.emitPoints()})),this.polyline.on("point-dragout",(t=>{this.removePoint(t)})),this.polyline.on("point-create",((t,e)=>{var i;this.addPoint({time:t*((null===(i=this.wavesurfer)||void 0===i?void 0:i.getDuration())||0),volume:1-e})})),this.polyline.on("line-move",(t=>{var e;this.points.forEach((e=>{e.volume=Math.min(1,Math.max(0,e.volume-t))})),this.emitPoints(),this.onTimeUpdate((null===(e=this.wavesurfer)||void 0===e?void 0:e.getCurrentTime())||0)})))}addPolyPoint(t,e){var i;null===(i=this.polyline)||void 0===i||i.addPolyPoint(t.time/e,t.volume,t)}onTimeUpdate(t){if(!this.wavesurfer)return;let e=this.points.find((e=>e.time>t));e||(e={time:this.wavesurfer.getDuration()||0,volume:0});let i=this.points.findLast((e=>e.time<=t));i||(i={time:0,volume:0});const s=e.time-i.time,o=e.volume-i.volume,n=i.volume+(t-i.time)*(o/s),r=Math.min(1,Math.max(0,n)),l=Math.round(100*r)/100;l!==this.getCurrentVolume()&&(this.setVolume(l),this.emit("volume-change",l))}}module.exports=l;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
class t{constructor(){this.listeners={}}on(t,e,i){if(this.listeners[t]||(this.listeners[t]=new Set),this.listeners[t].add(e),null==i?void 0:i.once){const i=()=>{this.un(t,i),this.un(t,e)};return this.on(t,i),i}return()=>this.un(t,e)}un(t,e){var i;null===(i=this.listeners[t])||void 0===i||i.delete(e)}once(t,e){return this.on(t,e,{once:!0})}unAll(){this.listeners={}}emit(t,...e){this.listeners[t]&&this.listeners[t].forEach((t=>t(...e)))}}class e extends t{constructor(t){super(),this.subscriptions=[],this.isDestroyed=!1,this.options=t}onInit(){}_init(t){this.isDestroyed&&(this.subscriptions=[],this.isDestroyed=!1),this.wavesurfer=t,this.onInit()}destroy(){this.emit("destroy"),this.subscriptions.forEach((t=>t())),this.subscriptions=[],this.isDestroyed=!0,this.wavesurfer=void 0}}function i(t,e,i,o,n=3,s=0,r=100){if(!t)return()=>{};const l=matchMedia("(pointer: coarse)").matches;let h=()=>{};const a=a=>{if(a.button!==s)return;a.preventDefault(),a.stopPropagation();let u=a.clientX,c=a.clientY,d=!1;const p=Date.now(),m=o=>{if(o.preventDefault(),o.stopPropagation(),l&&Date.now()-p<r)return;const s=o.clientX,h=o.clientY,a=s-u,m=h-c;if(d||Math.abs(a)>n||Math.abs(m)>n){const o=t.getBoundingClientRect(),{left:n,top:r}=o;d||(null==i||i(u-n,c-r),d=!0),e(a,m,s-n,h-r),u=s,c=h}},v=e=>{if(d){const i=e.clientX,n=e.clientY,s=t.getBoundingClientRect(),{left:r,top:l}=s;null==o||o(i-r,n-l)}h()},g=t=>{t.relatedTarget&&t.relatedTarget!==document.documentElement||v(t)},f=t=>{d&&(t.stopPropagation(),t.preventDefault())},y=t=>{d&&t.preventDefault()};document.addEventListener("pointermove",m),document.addEventListener("pointerup",v),document.addEventListener("pointerout",g),document.addEventListener("pointercancel",g),document.addEventListener("touchmove",y,{passive:!1}),document.addEventListener("click",f,{capture:!0}),h=()=>{document.removeEventListener("pointermove",m),document.removeEventListener("pointerup",v),document.removeEventListener("pointerout",g),document.removeEventListener("pointercancel",g),document.removeEventListener("touchmove",y),setTimeout((()=>{document.removeEventListener("click",f,{capture:!0})}),10)}};return t.addEventListener("pointerdown",a),()=>{h(),t.removeEventListener("pointerdown",a)}}function o(t,e){const i=e.xmlns?document.createElementNS(e.xmlns,t):document.createElement(t);for(const[t,n]of Object.entries(e))if("children"===t&&n)for(const[t,e]of Object.entries(n))e instanceof Node?i.appendChild(e):"string"==typeof e?i.appendChild(document.createTextNode(e)):i.appendChild(o(t,e));else"style"===t?Object.assign(i.style,n):"textContent"===t?i.textContent=n:i.setAttribute(t,n.toString());return i}function n(t,e,i){const n=o(t,e||{});return null==i||i.appendChild(n),n}const s={points:[],lineWidth:4,lineColor:"rgba(0, 0, 255, 0.5)",dragPointSize:10,dragPointFill:"rgba(255, 255, 255, 0.8)",dragPointStroke:"rgba(255, 255, 255, 0.8)"};class r extends t{constructor(t,e){super(),this.subscriptions=[],this.subscriptions=[],this.options=t,this.polyPoints=new Map;const o=e.clientWidth,s=e.clientHeight,r=n("svg",{xmlns:"http://www.w3.org/2000/svg",width:"100%",height:"100%",viewBox:`0 0 ${o} ${s}`,preserveAspectRatio:"none",style:{position:"absolute",left:"0",top:"0",zIndex:"4"},part:"envelope"},e);this.svg=r;const l=n("polyline",{xmlns:"http://www.w3.org/2000/svg",points:`0,${s} ${o},${s}`,stroke:t.lineColor,"stroke-width":t.lineWidth,fill:"none",part:"polyline",style:t.dragLine?{cursor:"row-resize",pointerEvents:"stroke"}:{}},r);t.dragLine&&this.subscriptions.push(i(l,((t,e)=>{const{height:i}=r.viewBox.baseVal,{points:o}=l;for(let t=1;t<o.numberOfItems-1;t++){const n=o.getItem(t);n.y=Math.min(i,Math.max(0,n.y+e))}const n=r.querySelectorAll("ellipse");Array.from(n).forEach((t=>{const o=Math.min(i,Math.max(0,Number(t.getAttribute("cy"))+e));t.setAttribute("cy",o.toString())})),this.emit("line-move",e/i)}))),r.addEventListener("dblclick",(t=>{const e=r.getBoundingClientRect(),i=t.clientX-e.left,o=t.clientY-e.top;this.emit("point-create",i/e.width,o/e.height)}));{let t;const e=()=>clearTimeout(t);r.addEventListener("touchstart",(i=>{1===i.touches.length?t=window.setTimeout((()=>{i.preventDefault();const t=r.getBoundingClientRect(),e=i.touches[0].clientX-t.left,o=i.touches[0].clientY-t.top;this.emit("point-create",e/t.width,o/t.height)}),500):e()})),r.addEventListener("touchmove",e),r.addEventListener("touchend",e)}}makeDraggable(t,e){this.subscriptions.push(i(t,e,(()=>t.style.cursor="grabbing"),(()=>t.style.cursor="grab"),1))}createCircle(t,e){const i=this.options.dragPointSize/2;return n("ellipse",{xmlns:"http://www.w3.org/2000/svg",cx:t,cy:e,rx:i,ry:i,fill:this.options.dragPointFill,stroke:this.options.dragPointStroke,"stroke-width":"2",style:{cursor:"grab",pointerEvents:"all"},part:"envelope-circle"},this.svg)}removePolyPoint(t){const e=this.polyPoints.get(t);if(!e)return;const{polyPoint:i,circle:o}=e,{points:n}=this.svg.querySelector("polyline"),s=Array.from(n).findIndex((t=>t.x===i.x&&t.y===i.y));n.removeItem(s),o.remove(),this.polyPoints.delete(t)}addPolyPoint(t,e,i){const{svg:o}=this,{width:n,height:s}=o.viewBox.baseVal,r=t*n,l=s-e*s,h=this.options.dragPointSize/2,a=o.createSVGPoint();a.x=t*n,a.y=s-e*s;const u=this.createCircle(r,l),{points:c}=o.querySelector("polyline"),d=Array.from(c).findIndex((t=>t.x>=r));c.insertItemBefore(a,Math.max(d,1)),this.polyPoints.set(i,{polyPoint:a,circle:u}),this.makeDraggable(u,((t,e)=>{const o=a.x+t,r=a.y+e;if(o<-h||r<-h||o>n+h||r>s+h)return void this.emit("point-dragout",i);const l=Array.from(c).find((t=>t.x>a.x)),d=Array.from(c).findLast((t=>t.x<a.x));l&&o>=l.x||d&&o<=d.x||(a.x=o,a.y=r,u.setAttribute("cx",o.toString()),u.setAttribute("cy",r.toString()),this.emit("point-move",i,o/n,r/s))}))}update(){const{svg:t}=this,{clientWidth:e,clientHeight:i}=t;if(!e||!i)return;const o=t.viewBox.baseVal.width/e,n=t.viewBox.baseVal.height/i;t.querySelectorAll("ellipse").forEach((t=>{const e=this.options.dragPointSize/2,i=e*o,s=e*n;t.setAttribute("rx",i.toString()),t.setAttribute("ry",s.toString())}))}destroy(){this.subscriptions.forEach((t=>t())),this.polyPoints.clear(),this.svg.remove()}}class l extends e{constructor(t){super(t),this.polyline=null,this.throttleTimeout=null,this.volume=1,this.points=t.points||[],this.options=Object.assign({},s,t),this.options.lineColor=this.options.lineColor||s.lineColor,this.options.dragPointFill=this.options.dragPointFill||s.dragPointFill,this.options.dragPointStroke=this.options.dragPointStroke||s.dragPointStroke,this.options.dragPointSize=this.options.dragPointSize||s.dragPointSize}static create(t){return new l(t)}addPoint(t){var e;t.id||(t.id=Math.random().toString(36).slice(2));const i=this.points.findLastIndex((e=>e.time<t.time));this.points.splice(i+1,0,t),this.emitPoints();const o=null===(e=this.wavesurfer)||void 0===e?void 0:e.getDuration();o&&this.addPolyPoint(t,o)}removePoint(t){var e;const i=this.points.indexOf(t);i>-1&&(this.points.splice(i,1),null===(e=this.polyline)||void 0===e||e.removePolyPoint(t),this.emitPoints())}getPoints(){return this.points}setPoints(t){this.points.slice().forEach((t=>this.removePoint(t))),t.forEach((t=>this.addPoint(t)))}destroy(){var t;null===(t=this.polyline)||void 0===t||t.destroy(),super.destroy()}getCurrentVolume(){return this.volume}setVolume(t){var e;this.volume=t,null===(e=this.wavesurfer)||void 0===e||e.setVolume(t)}onInit(){var t;if(!this.wavesurfer)throw Error("WaveSurfer is not initialized");const{options:e}=this;e.volume=null!==(t=e.volume)&&void 0!==t?t:this.wavesurfer.getVolume(),this.setVolume(e.volume),this.subscriptions.push(this.wavesurfer.on("decode",(t=>{this.initPolyline(),this.points.forEach((e=>{this.addPolyPoint(e,t)}))})),this.wavesurfer.on("redraw",(()=>{var t;null===(t=this.polyline)||void 0===t||t.update()})),this.wavesurfer.on("timeupdate",(t=>{this.onTimeUpdate(t)})))}emitPoints(){this.throttleTimeout&&clearTimeout(this.throttleTimeout),this.throttleTimeout=setTimeout((()=>{this.emit("points-change",this.points)}),200)}initPolyline(){if(this.polyline&&this.polyline.destroy(),!this.wavesurfer)return;const t=this.wavesurfer.getWrapper();this.polyline=new r(this.options,t),this.subscriptions.push(this.polyline.on("point-move",((t,e,i)=>{var o;const n=(null===(o=this.wavesurfer)||void 0===o?void 0:o.getDuration())||0;t.time=e*n,t.volume=1-i,this.emitPoints()})),this.polyline.on("point-dragout",(t=>{this.removePoint(t)})),this.polyline.on("point-create",((t,e)=>{var i;this.addPoint({time:t*((null===(i=this.wavesurfer)||void 0===i?void 0:i.getDuration())||0),volume:1-e})})),this.polyline.on("line-move",(t=>{var e;this.points.forEach((e=>{e.volume=Math.min(1,Math.max(0,e.volume-t))})),this.emitPoints(),this.onTimeUpdate((null===(e=this.wavesurfer)||void 0===e?void 0:e.getCurrentTime())||0)})))}addPolyPoint(t,e){var i;null===(i=this.polyline)||void 0===i||i.addPolyPoint(t.time/e,t.volume,t)}onTimeUpdate(t){if(!this.wavesurfer)return;let e=this.points.find((e=>e.time>t));e||(e={time:this.wavesurfer.getDuration()||0,volume:0});let i=this.points.findLast((e=>e.time<=t));i||(i={time:0,volume:0});const o=e.time-i.time,n=e.volume-i.volume,s=i.volume+(t-i.time)*(n/o),r=Math.min(1,Math.max(0,s)),l=Math.round(100*r)/100;l!==this.getCurrentVolume()&&(this.setVolume(l),this.emit("volume-change",l))}}export{l as default};
|
|
1
|
+
class t{constructor(){this.listeners={}}on(t,e,i){if(this.listeners[t]||(this.listeners[t]=new Set),null==i?void 0:i.once){const i=(...s)=>{this.un(t,i),e(...s)};return this.listeners[t].add(i),()=>this.un(t,i)}return this.listeners[t].add(e),()=>this.un(t,e)}un(t,e){var i;null===(i=this.listeners[t])||void 0===i||i.delete(e)}once(t,e){return this.on(t,e,{once:!0})}unAll(){this.listeners={}}emit(t,...e){this.listeners[t]&&this.listeners[t].forEach((t=>t(...e)))}}class e extends t{constructor(t){super(),this.subscriptions=[],this.isDestroyed=!1,this.options=t}onInit(){}_init(t){this.isDestroyed&&(this.subscriptions=[],this.isDestroyed=!1),this.wavesurfer=t,this.onInit()}destroy(){this.emit("destroy"),this.subscriptions.forEach((t=>t())),this.subscriptions=[],this.isDestroyed=!0,this.wavesurfer=void 0}}function i(t,e,i,s,o=3,n=0,r=100){if(!t)return()=>{};const l=new Map,h=matchMedia("(pointer: coarse)").matches;let u=()=>{};const a=a=>{if(a.button!==n)return;if(l.set(a.pointerId,a),l.size>1)return;let c=a.clientX,d=a.clientY,p=!1;const v=Date.now(),m=s=>{if(s.defaultPrevented||l.size>1)return;if(h&&Date.now()-v<r)return;const n=s.clientX,u=s.clientY,a=n-c,m=u-d;if(p||Math.abs(a)>o||Math.abs(m)>o){s.preventDefault(),s.stopPropagation();const o=t.getBoundingClientRect(),{left:r,top:l}=o;p||(null==i||i(c-r,d-l),p=!0),e(a,m,n-r,u-l),c=n,d=u}},g=e=>{if(l.delete(e.pointerId),p){const i=e.clientX,o=e.clientY,n=t.getBoundingClientRect(),{left:r,top:l}=n;null==s||s(i-r,o-l)}u()},f=t=>{l.delete(t.pointerId),t.relatedTarget&&t.relatedTarget!==document.documentElement||g(t)},y=t=>{p&&(t.stopPropagation(),t.preventDefault())},P=t=>{t.defaultPrevented||l.size>1||p&&t.preventDefault()};document.addEventListener("pointermove",m),document.addEventListener("pointerup",g),document.addEventListener("pointerout",f),document.addEventListener("pointercancel",f),document.addEventListener("touchmove",P,{passive:!1}),document.addEventListener("click",y,{capture:!0}),u=()=>{document.removeEventListener("pointermove",m),document.removeEventListener("pointerup",g),document.removeEventListener("pointerout",f),document.removeEventListener("pointercancel",f),document.removeEventListener("touchmove",P),setTimeout((()=>{document.removeEventListener("click",y,{capture:!0})}),10)}};return t.addEventListener("pointerdown",a),()=>{u(),t.removeEventListener("pointerdown",a),l.clear()}}function s(t,e){const i=e.xmlns?document.createElementNS(e.xmlns,t):document.createElement(t);for(const[t,o]of Object.entries(e))if("children"===t&&o)for(const[t,e]of Object.entries(o))e instanceof Node?i.appendChild(e):"string"==typeof e?i.appendChild(document.createTextNode(e)):i.appendChild(s(t,e));else"style"===t?Object.assign(i.style,o):"textContent"===t?i.textContent=o:i.setAttribute(t,o.toString());return i}function o(t,e,i){const o=s(t,e||{});return null==i||i.appendChild(o),o}const n={points:[],lineWidth:4,lineColor:"rgba(0, 0, 255, 0.5)",dragPointSize:10,dragPointFill:"rgba(255, 255, 255, 0.8)",dragPointStroke:"rgba(255, 255, 255, 0.8)"};class r extends t{constructor(t,e){super(),this.subscriptions=[],this.subscriptions=[],this.options=t,this.polyPoints=new Map;const s=e.clientWidth,n=e.clientHeight,r=o("svg",{xmlns:"http://www.w3.org/2000/svg",width:"100%",height:"100%",viewBox:`0 0 ${s} ${n}`,preserveAspectRatio:"none",style:{position:"absolute",left:"0",top:"0",zIndex:"4"},part:"envelope"},e);this.svg=r;const l=o("polyline",{xmlns:"http://www.w3.org/2000/svg",points:`0,${n} ${s},${n}`,stroke:t.lineColor,"stroke-width":t.lineWidth,fill:"none",part:"polyline",style:t.dragLine?{cursor:"row-resize",pointerEvents:"stroke"}:{}},r);t.dragLine&&this.subscriptions.push(i(l,((t,e)=>{const{height:i}=r.viewBox.baseVal,{points:s}=l;for(let t=1;t<s.numberOfItems-1;t++){const o=s.getItem(t);o.y=Math.min(i,Math.max(0,o.y+e))}const o=r.querySelectorAll("ellipse");Array.from(o).forEach((t=>{const s=Math.min(i,Math.max(0,Number(t.getAttribute("cy"))+e));t.setAttribute("cy",s.toString())})),this.emit("line-move",e/i)}))),this.dblClickListener=t=>{const e=r.getBoundingClientRect(),i=t.clientX-e.left,s=t.clientY-e.top;this.emit("point-create",i/e.width,s/e.height)},r.addEventListener("dblclick",this.dblClickListener);const h=()=>{void 0!==this.pressTimer&&(clearTimeout(this.pressTimer),this.pressTimer=void 0)};this.touchStartListener=t=>{1===t.touches.length?this.pressTimer=window.setTimeout((()=>{t.preventDefault();const e=r.getBoundingClientRect(),i=t.touches[0].clientX-e.left,s=t.touches[0].clientY-e.top;this.emit("point-create",i/e.width,s/e.height)}),500):h()},this.touchMoveListener=h,this.touchEndListener=h,r.addEventListener("touchstart",this.touchStartListener),r.addEventListener("touchmove",this.touchMoveListener),r.addEventListener("touchend",this.touchEndListener)}makeDraggable(t,e){this.subscriptions.push(i(t,e,(()=>t.style.cursor="grabbing"),(()=>t.style.cursor="grab"),1))}createCircle(t,e){const i=this.options.dragPointSize/2;return o("ellipse",{xmlns:"http://www.w3.org/2000/svg",cx:t,cy:e,rx:i,ry:i,fill:this.options.dragPointFill,stroke:this.options.dragPointStroke,"stroke-width":"2",style:{cursor:"grab",pointerEvents:"all"},part:"envelope-circle"},this.svg)}removePolyPoint(t){const e=this.polyPoints.get(t);if(!e)return;const{polyPoint:i,circle:s}=e,{points:o}=this.svg.querySelector("polyline"),n=Array.from(o).findIndex((t=>t.x===i.x&&t.y===i.y));o.removeItem(n),s.remove(),this.polyPoints.delete(t)}addPolyPoint(t,e,i){const{svg:s}=this,{width:o,height:n}=s.viewBox.baseVal,r=t*o,l=n-e*n,h=this.options.dragPointSize/2,u=s.createSVGPoint();u.x=t*o,u.y=n-e*n;const a=this.createCircle(r,l),{points:c}=s.querySelector("polyline"),d=Array.from(c).findIndex((t=>t.x>=r));c.insertItemBefore(u,Math.max(d,1)),this.polyPoints.set(i,{polyPoint:u,circle:a}),this.makeDraggable(a,((t,e)=>{const s=u.x+t,r=u.y+e;if(s<-h||r<-h||s>o+h||r>n+h)return void this.emit("point-dragout",i);const l=Array.from(c).find((t=>t.x>u.x)),d=Array.from(c).findLast((t=>t.x<u.x));l&&s>=l.x||d&&s<=d.x||(u.x=s,u.y=r,a.setAttribute("cx",s.toString()),a.setAttribute("cy",r.toString()),this.emit("point-move",i,s/o,r/n))}))}update(){const{svg:t}=this,{clientWidth:e,clientHeight:i}=t;if(!e||!i)return;const s=t.viewBox.baseVal.width/e,o=t.viewBox.baseVal.height/i;t.querySelectorAll("ellipse").forEach((t=>{const e=this.options.dragPointSize/2,i=e*s,n=e*o;t.setAttribute("rx",i.toString()),t.setAttribute("ry",n.toString())}))}destroy(){void 0!==this.pressTimer&&(clearTimeout(this.pressTimer),this.pressTimer=void 0),this.dblClickListener&&(this.svg.removeEventListener("dblclick",this.dblClickListener),this.dblClickListener=void 0),this.touchStartListener&&(this.svg.removeEventListener("touchstart",this.touchStartListener),this.touchStartListener=void 0),this.touchMoveListener&&(this.svg.removeEventListener("touchmove",this.touchMoveListener),this.touchMoveListener=void 0),this.touchEndListener&&(this.svg.removeEventListener("touchend",this.touchEndListener),this.touchEndListener=void 0),this.subscriptions.forEach((t=>t())),this.polyPoints.clear(),this.svg.remove()}}class l extends e{constructor(t){super(t),this.polyline=null,this.throttleTimeout=null,this.volume=1,this.points=t.points||[],this.options=Object.assign({},n,t),this.options.lineColor=this.options.lineColor||n.lineColor,this.options.dragPointFill=this.options.dragPointFill||n.dragPointFill,this.options.dragPointStroke=this.options.dragPointStroke||n.dragPointStroke,this.options.dragPointSize=this.options.dragPointSize||n.dragPointSize}static create(t){return new l(t)}addPoint(t){var e;t.id||(t.id=Math.random().toString(36).slice(2));const i=this.points.findLastIndex((e=>e.time<t.time));this.points.splice(i+1,0,t),this.emitPoints();const s=null===(e=this.wavesurfer)||void 0===e?void 0:e.getDuration();s&&this.addPolyPoint(t,s)}removePoint(t){var e;const i=this.points.indexOf(t);i>-1&&(this.points.splice(i,1),null===(e=this.polyline)||void 0===e||e.removePolyPoint(t),this.emitPoints())}getPoints(){return this.points}setPoints(t){this.points.slice().forEach((t=>this.removePoint(t))),t.forEach((t=>this.addPoint(t)))}destroy(){var t;this.throttleTimeout&&(clearTimeout(this.throttleTimeout),this.throttleTimeout=null),null===(t=this.polyline)||void 0===t||t.destroy(),super.destroy()}getCurrentVolume(){return this.volume}setVolume(t){var e;this.volume=t,null===(e=this.wavesurfer)||void 0===e||e.setVolume(t)}onInit(){var t;if(!this.wavesurfer)throw Error("WaveSurfer is not initialized");const{options:e}=this;e.volume=null!==(t=e.volume)&&void 0!==t?t:this.wavesurfer.getVolume(),this.setVolume(e.volume),this.subscriptions.push(this.wavesurfer.on("decode",(t=>{this.initPolyline(),this.points.forEach((e=>{this.addPolyPoint(e,t)}))})),this.wavesurfer.on("redraw",(()=>{var t;null===(t=this.polyline)||void 0===t||t.update()})),this.wavesurfer.on("timeupdate",(t=>{this.onTimeUpdate(t)})))}emitPoints(){this.throttleTimeout&&clearTimeout(this.throttleTimeout),this.throttleTimeout=setTimeout((()=>{this.emit("points-change",this.points)}),200)}initPolyline(){if(this.polyline&&this.polyline.destroy(),!this.wavesurfer)return;const t=this.wavesurfer.getWrapper();this.polyline=new r(this.options,t),this.subscriptions.push(this.polyline.on("point-move",((t,e,i)=>{var s;const o=(null===(s=this.wavesurfer)||void 0===s?void 0:s.getDuration())||0;t.time=e*o,t.volume=1-i,this.emitPoints()})),this.polyline.on("point-dragout",(t=>{this.removePoint(t)})),this.polyline.on("point-create",((t,e)=>{var i;this.addPoint({time:t*((null===(i=this.wavesurfer)||void 0===i?void 0:i.getDuration())||0),volume:1-e})})),this.polyline.on("line-move",(t=>{var e;this.points.forEach((e=>{e.volume=Math.min(1,Math.max(0,e.volume-t))})),this.emitPoints(),this.onTimeUpdate((null===(e=this.wavesurfer)||void 0===e?void 0:e.getCurrentTime())||0)})))}addPolyPoint(t,e){var i;null===(i=this.polyline)||void 0===i||i.addPolyPoint(t.time/e,t.volume,t)}onTimeUpdate(t){if(!this.wavesurfer)return;let e=this.points.find((e=>e.time>t));e||(e={time:this.wavesurfer.getDuration()||0,volume:0});let i=this.points.findLast((e=>e.time<=t));i||(i={time:0,volume:0});const s=e.time-i.time,o=e.volume-i.volume,n=i.volume+(t-i.time)*(o/s),r=Math.min(1,Math.max(0,n)),l=Math.round(100*r)/100;l!==this.getCurrentVolume()&&(this.setVolume(l),this.emit("volume-change",l))}}export{l as default};
|