wavesurfer.js 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/README.md +2 -1
- package/dist/decoder.js +0 -2
- package/dist/plugins/envelope.js +1 -348
- package/dist/plugins/hover.js +1 -103
- package/dist/plugins/minimap.cjs +1 -1
- package/dist/plugins/minimap.esm.js +1 -1
- package/dist/plugins/minimap.js +1 -109
- package/dist/plugins/minimap.min.js +1 -1
- package/dist/plugins/record.js +1 -122
- package/dist/plugins/regions.cjs +1 -1
- package/dist/plugins/regions.esm.js +1 -1
- package/dist/plugins/regions.js +1 -363
- package/dist/plugins/regions.min.js +1 -1
- package/dist/plugins/spectrogram.js +1 -484
- package/dist/plugins/timeline.js +1 -166
- package/dist/wavesurfer.cjs +1 -1
- package/dist/wavesurfer.esm.js +1 -1
- package/dist/wavesurfer.min.js +1 -1
- package/package.json +11 -9
package/dist/plugins/regions.js
CHANGED
|
@@ -1,363 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Regions are visual overlays on the waveform that can be used to mark segments of audio.
|
|
3
|
-
* Regions can be clicked on, dragged and resized.
|
|
4
|
-
* You can set the color and content of each region, as well as their HTML content.
|
|
5
|
-
*/
|
|
6
|
-
import BasePlugin from '../base-plugin.js';
|
|
7
|
-
import { makeDraggable } from '../draggable.js';
|
|
8
|
-
import EventEmitter from '../event-emitter.js';
|
|
9
|
-
class SingleRegion extends EventEmitter {
|
|
10
|
-
constructor(params, totalDuration) {
|
|
11
|
-
var _a, _b, _c, _d, _e, _f;
|
|
12
|
-
super();
|
|
13
|
-
this.totalDuration = totalDuration;
|
|
14
|
-
this.minLength = 0;
|
|
15
|
-
this.maxLength = Infinity;
|
|
16
|
-
this.id = params.id || `region-${Math.random().toString(32).slice(2)}`;
|
|
17
|
-
this.start = params.start;
|
|
18
|
-
this.end = (_a = params.end) !== null && _a !== void 0 ? _a : params.start;
|
|
19
|
-
this.drag = (_b = params.drag) !== null && _b !== void 0 ? _b : true;
|
|
20
|
-
this.resize = (_c = params.resize) !== null && _c !== void 0 ? _c : true;
|
|
21
|
-
this.color = (_d = params.color) !== null && _d !== void 0 ? _d : 'rgba(0, 0, 0, 0.1)';
|
|
22
|
-
this.minLength = (_e = params.minLength) !== null && _e !== void 0 ? _e : this.minLength;
|
|
23
|
-
this.maxLength = (_f = params.maxLength) !== null && _f !== void 0 ? _f : this.maxLength;
|
|
24
|
-
this.element = this.initElement(params.content);
|
|
25
|
-
this.renderPosition();
|
|
26
|
-
this.initMouseEvents();
|
|
27
|
-
}
|
|
28
|
-
initElement(content) {
|
|
29
|
-
const element = document.createElement('div');
|
|
30
|
-
const isMarker = this.start === this.end;
|
|
31
|
-
element.setAttribute('part', `${isMarker ? 'marker' : 'region'} ${this.id}`);
|
|
32
|
-
element.setAttribute('style', `
|
|
33
|
-
position: absolute;
|
|
34
|
-
height: 100%;
|
|
35
|
-
background-color: ${isMarker ? 'none' : this.color};
|
|
36
|
-
border-left: ${isMarker ? '2px solid ' + this.color : 'none'};
|
|
37
|
-
border-radius: 2px;
|
|
38
|
-
box-sizing: border-box;
|
|
39
|
-
transition: background-color 0.2s ease;
|
|
40
|
-
cursor: ${this.drag ? 'grab' : 'default'};
|
|
41
|
-
pointer-events: all;
|
|
42
|
-
`);
|
|
43
|
-
// Init content
|
|
44
|
-
if (content) {
|
|
45
|
-
if (typeof content === 'string') {
|
|
46
|
-
this.content = document.createElement('div');
|
|
47
|
-
this.content.style.padding = `0.2em ${isMarker ? 0.2 : 0.4}em`;
|
|
48
|
-
this.content.textContent = content;
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
this.content = content;
|
|
52
|
-
}
|
|
53
|
-
this.content.setAttribute('part', 'region-content');
|
|
54
|
-
element.appendChild(this.content);
|
|
55
|
-
}
|
|
56
|
-
// Add resize handles
|
|
57
|
-
if (!isMarker) {
|
|
58
|
-
const leftHandle = document.createElement('div');
|
|
59
|
-
leftHandle.setAttribute('data-resize', 'left');
|
|
60
|
-
leftHandle.setAttribute('style', `
|
|
61
|
-
position: absolute;
|
|
62
|
-
z-index: 2;
|
|
63
|
-
width: 6px;
|
|
64
|
-
height: 100%;
|
|
65
|
-
top: 0;
|
|
66
|
-
left: 0;
|
|
67
|
-
border-left: 2px solid rgba(0, 0, 0, 0.5);
|
|
68
|
-
border-radius: 2px 0 0 2px;
|
|
69
|
-
cursor: ${this.resize ? 'ew-resize' : 'default'};
|
|
70
|
-
word-break: keep-all;
|
|
71
|
-
`);
|
|
72
|
-
leftHandle.setAttribute('part', 'region-handle region-handle-left');
|
|
73
|
-
const rightHandle = leftHandle.cloneNode();
|
|
74
|
-
rightHandle.setAttribute('data-resize', 'right');
|
|
75
|
-
rightHandle.style.left = '';
|
|
76
|
-
rightHandle.style.right = '0';
|
|
77
|
-
rightHandle.style.borderRight = rightHandle.style.borderLeft;
|
|
78
|
-
rightHandle.style.borderLeft = '';
|
|
79
|
-
rightHandle.style.borderRadius = '0 2px 2px 0';
|
|
80
|
-
rightHandle.setAttribute('part', 'region-handle region-handle-right');
|
|
81
|
-
element.appendChild(leftHandle);
|
|
82
|
-
element.appendChild(rightHandle);
|
|
83
|
-
}
|
|
84
|
-
return element;
|
|
85
|
-
}
|
|
86
|
-
renderPosition() {
|
|
87
|
-
const start = this.start / this.totalDuration;
|
|
88
|
-
const end = (this.totalDuration - this.end) / this.totalDuration;
|
|
89
|
-
this.element.style.left = `${start * 100}%`;
|
|
90
|
-
this.element.style.right = `${end * 100}%`;
|
|
91
|
-
}
|
|
92
|
-
initMouseEvents() {
|
|
93
|
-
const { element } = this;
|
|
94
|
-
if (!element)
|
|
95
|
-
return;
|
|
96
|
-
element.addEventListener('click', (e) => this.emit('click', e));
|
|
97
|
-
element.addEventListener('mouseenter', (e) => this.emit('over', e));
|
|
98
|
-
element.addEventListener('mouseleave', (e) => this.emit('leave', e));
|
|
99
|
-
element.addEventListener('dblclick', (e) => this.emit('dblclick', e));
|
|
100
|
-
// Drag
|
|
101
|
-
makeDraggable(element, (dx) => this.onMove(dx), () => this.onStartMoving(), () => this.onEndMoving());
|
|
102
|
-
// Resize
|
|
103
|
-
const resizeThreshold = 1;
|
|
104
|
-
makeDraggable(element.querySelector('[data-resize="left"]'), (dx) => this.onResize(dx, 'start'), () => null, () => this.onEndResizing(), resizeThreshold);
|
|
105
|
-
makeDraggable(element.querySelector('[data-resize="right"]'), (dx) => this.onResize(dx, 'end'), () => null, () => this.onEndResizing(), resizeThreshold);
|
|
106
|
-
}
|
|
107
|
-
onStartMoving() {
|
|
108
|
-
if (!this.drag)
|
|
109
|
-
return;
|
|
110
|
-
this.element.style.cursor = 'grabbing';
|
|
111
|
-
}
|
|
112
|
-
onEndMoving() {
|
|
113
|
-
if (!this.drag)
|
|
114
|
-
return;
|
|
115
|
-
this.element.style.cursor = 'grab';
|
|
116
|
-
this.emit('update-end');
|
|
117
|
-
}
|
|
118
|
-
_onUpdate(dx, side) {
|
|
119
|
-
if (!this.element.parentElement)
|
|
120
|
-
return;
|
|
121
|
-
const deltaSeconds = (dx / this.element.parentElement.clientWidth) * this.totalDuration;
|
|
122
|
-
const newStart = !side || side === 'start' ? this.start + deltaSeconds : this.start;
|
|
123
|
-
const newEnd = !side || side === 'end' ? this.end + deltaSeconds : this.end;
|
|
124
|
-
const length = newEnd - newStart;
|
|
125
|
-
if (newStart >= 0 &&
|
|
126
|
-
newEnd <= this.totalDuration &&
|
|
127
|
-
newStart <= newEnd &&
|
|
128
|
-
length >= this.minLength &&
|
|
129
|
-
length <= this.maxLength) {
|
|
130
|
-
this.start = newStart;
|
|
131
|
-
this.end = newEnd;
|
|
132
|
-
this.renderPosition();
|
|
133
|
-
this.emit('update');
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
onMove(dx) {
|
|
137
|
-
if (!this.drag)
|
|
138
|
-
return;
|
|
139
|
-
this._onUpdate(dx);
|
|
140
|
-
}
|
|
141
|
-
onResize(dx, side) {
|
|
142
|
-
if (!this.resize)
|
|
143
|
-
return;
|
|
144
|
-
this._onUpdate(dx, side);
|
|
145
|
-
}
|
|
146
|
-
onEndResizing() {
|
|
147
|
-
if (!this.resize)
|
|
148
|
-
return;
|
|
149
|
-
this.emit('update-end');
|
|
150
|
-
}
|
|
151
|
-
_setTotalDuration(totalDuration) {
|
|
152
|
-
this.totalDuration = totalDuration;
|
|
153
|
-
this.renderPosition();
|
|
154
|
-
}
|
|
155
|
-
/** Play the region from start to end */
|
|
156
|
-
play() {
|
|
157
|
-
this.emit('play');
|
|
158
|
-
}
|
|
159
|
-
/** Update the region's options */
|
|
160
|
-
setOptions(options) {
|
|
161
|
-
var _a, _b;
|
|
162
|
-
if (options.color) {
|
|
163
|
-
this.color = options.color;
|
|
164
|
-
this.element.style.backgroundColor = this.color;
|
|
165
|
-
}
|
|
166
|
-
if (options.drag !== undefined) {
|
|
167
|
-
this.drag = options.drag;
|
|
168
|
-
this.element.style.cursor = this.drag ? 'grab' : 'default';
|
|
169
|
-
}
|
|
170
|
-
if (options.resize !== undefined) {
|
|
171
|
-
this.resize = options.resize;
|
|
172
|
-
this.element.querySelectorAll('[data-resize]').forEach((handle) => {
|
|
173
|
-
;
|
|
174
|
-
handle.style.cursor = this.resize ? 'ew-resize' : 'default';
|
|
175
|
-
});
|
|
176
|
-
}
|
|
177
|
-
if (options.start !== undefined || options.end !== undefined) {
|
|
178
|
-
this.start = (_a = options.start) !== null && _a !== void 0 ? _a : this.start;
|
|
179
|
-
this.end = (_b = options.end) !== null && _b !== void 0 ? _b : this.end;
|
|
180
|
-
this.renderPosition();
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
/** Remove the region */
|
|
184
|
-
remove() {
|
|
185
|
-
this.emit('remove');
|
|
186
|
-
this.element.remove();
|
|
187
|
-
// This violates the type but we want to clean up the DOM reference
|
|
188
|
-
// w/o having to have a nullable type of the element
|
|
189
|
-
this.element = null;
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
class RegionsPlugin extends BasePlugin {
|
|
193
|
-
/** Create an instance of RegionsPlugin */
|
|
194
|
-
constructor(options) {
|
|
195
|
-
super(options);
|
|
196
|
-
this.regions = [];
|
|
197
|
-
this.regionsContainer = this.initRegionsContainer();
|
|
198
|
-
}
|
|
199
|
-
/** Create an instance of RegionsPlugin */
|
|
200
|
-
static create(options) {
|
|
201
|
-
return new RegionsPlugin(options);
|
|
202
|
-
}
|
|
203
|
-
/** Called by wavesurfer, don't call manually */
|
|
204
|
-
onInit() {
|
|
205
|
-
if (!this.wavesurfer) {
|
|
206
|
-
throw Error('WaveSurfer is not initialized');
|
|
207
|
-
}
|
|
208
|
-
this.wavesurfer.getWrapper().appendChild(this.regionsContainer);
|
|
209
|
-
// Detect when a region is being played
|
|
210
|
-
let activeRegion = null;
|
|
211
|
-
this.subscriptions.push(this.wavesurfer.on('timeupdate', (currentTime) => {
|
|
212
|
-
const playedRegion = this.regions.find((region) => region.start <= currentTime && region.end >= currentTime);
|
|
213
|
-
if (activeRegion && activeRegion !== playedRegion) {
|
|
214
|
-
this.emit('region-out', activeRegion);
|
|
215
|
-
activeRegion = null;
|
|
216
|
-
}
|
|
217
|
-
if (playedRegion && playedRegion !== activeRegion) {
|
|
218
|
-
activeRegion = playedRegion;
|
|
219
|
-
this.emit('region-in', playedRegion);
|
|
220
|
-
}
|
|
221
|
-
}));
|
|
222
|
-
}
|
|
223
|
-
initRegionsContainer() {
|
|
224
|
-
const div = document.createElement('div');
|
|
225
|
-
div.setAttribute('style', `
|
|
226
|
-
position: absolute;
|
|
227
|
-
top: 0;
|
|
228
|
-
left: 0;
|
|
229
|
-
width: 100%;
|
|
230
|
-
height: 100%;
|
|
231
|
-
z-index: 3;
|
|
232
|
-
pointer-events: none;
|
|
233
|
-
`);
|
|
234
|
-
return div;
|
|
235
|
-
}
|
|
236
|
-
/** Get all created regions */
|
|
237
|
-
getRegions() {
|
|
238
|
-
return this.regions;
|
|
239
|
-
}
|
|
240
|
-
avoidOverlapping(region) {
|
|
241
|
-
if (!region.content)
|
|
242
|
-
return;
|
|
243
|
-
// Check that the label doesn't overlap with other labels
|
|
244
|
-
// If it does, push it down until it doesn't
|
|
245
|
-
const div = region.content;
|
|
246
|
-
const labelLeft = div.getBoundingClientRect().left;
|
|
247
|
-
const labelWidth = region.element.scrollWidth;
|
|
248
|
-
const overlap = this.regions
|
|
249
|
-
.filter((reg) => {
|
|
250
|
-
if (reg === region || !reg.content)
|
|
251
|
-
return false;
|
|
252
|
-
const left = reg.content.getBoundingClientRect().left;
|
|
253
|
-
const width = reg.element.scrollWidth;
|
|
254
|
-
return labelLeft < left + width && left < labelLeft + labelWidth;
|
|
255
|
-
})
|
|
256
|
-
.map((reg) => { var _a; return ((_a = reg.content) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect().height) || 0; })
|
|
257
|
-
.reduce((sum, val) => sum + val, 0);
|
|
258
|
-
div.style.marginTop = `${overlap}px`;
|
|
259
|
-
}
|
|
260
|
-
saveRegion(region) {
|
|
261
|
-
this.regionsContainer.appendChild(region.element);
|
|
262
|
-
this.avoidOverlapping(region);
|
|
263
|
-
this.regions.push(region);
|
|
264
|
-
this.emit('region-created', region);
|
|
265
|
-
const regionSubscriptions = [
|
|
266
|
-
region.on('update-end', () => {
|
|
267
|
-
this.avoidOverlapping(region);
|
|
268
|
-
this.emit('region-updated', region);
|
|
269
|
-
}),
|
|
270
|
-
region.on('play', () => {
|
|
271
|
-
var _a, _b;
|
|
272
|
-
(_a = this.wavesurfer) === null || _a === void 0 ? void 0 : _a.play();
|
|
273
|
-
(_b = this.wavesurfer) === null || _b === void 0 ? void 0 : _b.setTime(region.start);
|
|
274
|
-
}),
|
|
275
|
-
region.on('click', (e) => {
|
|
276
|
-
this.emit('region-clicked', region, e);
|
|
277
|
-
}),
|
|
278
|
-
region.on('dblclick', (e) => {
|
|
279
|
-
this.emit('region-double-clicked', region, e);
|
|
280
|
-
}),
|
|
281
|
-
// Remove the region from the list when it's removed
|
|
282
|
-
region.once('remove', () => {
|
|
283
|
-
regionSubscriptions.forEach((unsubscribe) => unsubscribe());
|
|
284
|
-
this.regions = this.regions.filter((reg) => reg !== region);
|
|
285
|
-
}),
|
|
286
|
-
];
|
|
287
|
-
this.subscriptions.push(...regionSubscriptions);
|
|
288
|
-
}
|
|
289
|
-
/** Create a region with given parameters */
|
|
290
|
-
addRegion(options) {
|
|
291
|
-
if (!this.wavesurfer) {
|
|
292
|
-
throw Error('WaveSurfer is not initialized');
|
|
293
|
-
}
|
|
294
|
-
const duration = this.wavesurfer.getDuration();
|
|
295
|
-
const region = new SingleRegion(options, duration);
|
|
296
|
-
if (!duration) {
|
|
297
|
-
this.subscriptions.push(this.wavesurfer.once('ready', (duration) => {
|
|
298
|
-
region._setTotalDuration(duration);
|
|
299
|
-
this.saveRegion(region);
|
|
300
|
-
}));
|
|
301
|
-
}
|
|
302
|
-
else {
|
|
303
|
-
this.saveRegion(region);
|
|
304
|
-
}
|
|
305
|
-
return region;
|
|
306
|
-
}
|
|
307
|
-
/**
|
|
308
|
-
* Enable creation of regions by dragging on an empty space on the waveform.
|
|
309
|
-
* Returns a function to disable the drag selection.
|
|
310
|
-
*/
|
|
311
|
-
enableDragSelection(options) {
|
|
312
|
-
var _a, _b;
|
|
313
|
-
const wrapper = (_b = (_a = this.wavesurfer) === null || _a === void 0 ? void 0 : _a.getWrapper()) === null || _b === void 0 ? void 0 : _b.querySelector('div');
|
|
314
|
-
if (!wrapper)
|
|
315
|
-
return () => undefined;
|
|
316
|
-
const initialSize = 5;
|
|
317
|
-
let region = null;
|
|
318
|
-
let startX = 0;
|
|
319
|
-
return makeDraggable(wrapper,
|
|
320
|
-
// On drag move
|
|
321
|
-
(dx, _dy, x) => {
|
|
322
|
-
if (region) {
|
|
323
|
-
// Update the end position of the region
|
|
324
|
-
// If we're dragging to the left, we need to update the start instead
|
|
325
|
-
region._onUpdate(dx, x > startX ? 'end' : 'start');
|
|
326
|
-
}
|
|
327
|
-
},
|
|
328
|
-
// On drag start
|
|
329
|
-
(x) => {
|
|
330
|
-
startX = x;
|
|
331
|
-
if (!this.wavesurfer)
|
|
332
|
-
return;
|
|
333
|
-
const duration = this.wavesurfer.getDuration();
|
|
334
|
-
const width = this.wavesurfer.getWrapper().clientWidth;
|
|
335
|
-
// Calculate the start time of the region
|
|
336
|
-
const start = (x / width) * duration;
|
|
337
|
-
// Give the region a small initial size
|
|
338
|
-
const end = ((x + initialSize) / width) * duration;
|
|
339
|
-
// Create a region but don't save it until the drag ends
|
|
340
|
-
region = new SingleRegion(Object.assign(Object.assign({}, options), { start,
|
|
341
|
-
end }), duration);
|
|
342
|
-
// Just add it to the DOM for now
|
|
343
|
-
this.regionsContainer.appendChild(region.element);
|
|
344
|
-
},
|
|
345
|
-
// On drag end
|
|
346
|
-
() => {
|
|
347
|
-
if (region) {
|
|
348
|
-
this.saveRegion(region);
|
|
349
|
-
region = null;
|
|
350
|
-
}
|
|
351
|
-
});
|
|
352
|
-
}
|
|
353
|
-
/** Remove all regions */
|
|
354
|
-
clearRegions() {
|
|
355
|
-
this.regions.forEach((region) => region.remove());
|
|
356
|
-
}
|
|
357
|
-
/** Destroy the plugin and clean up */
|
|
358
|
-
destroy() {
|
|
359
|
-
this.clearRegions();
|
|
360
|
-
super.destroy();
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
export default RegionsPlugin;
|
|
1
|
+
class t{constructor(){this.listeners={}}on(t,e){return this.listeners[t]||(this.listeners[t]=new Set),this.listeners[t].add(e),()=>this.un(t,e)}once(t,e){const i=this.on(t,e),n=this.on(t,(()=>{i(),n()}));return i}un(t,e){this.listeners[t]&&(e?this.listeners[t].delete(e):delete this.listeners[t])}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.options=t}onInit(){}init(t){this.wavesurfer=t,this.onInit()}destroy(){this.emit("destroy"),this.subscriptions.forEach((t=>t()))}}function i(t,e,i,n,s=5){let r=()=>{};if(!t)return r;const o=o=>{if(2===o.button)return;o.preventDefault(),o.stopPropagation();let l=o.clientX,a=o.clientY,h=!1;const d=n=>{n.preventDefault(),n.stopPropagation();const r=n.clientX,o=n.clientY;if(h||Math.abs(r-l)>=s||Math.abs(o-a)>=s){const{left:n,top:s}=t.getBoundingClientRect();h||(h=!0,null==i||i(l-n,a-s)),e(r-l,o-a,r-n,o-s),l=r,a=o}},u=t=>{h&&(t.preventDefault(),t.stopPropagation())},c=()=>{h&&(null==n||n()),r()};document.addEventListener("pointermove",d),document.addEventListener("pointerup",c),document.addEventListener("pointerleave",c),document.addEventListener("click",u,!0),r=()=>{document.removeEventListener("pointermove",d),document.removeEventListener("pointerup",c),document.removeEventListener("pointerleave",c),setTimeout((()=>{document.removeEventListener("click",u,!0)}),10)}};return t.addEventListener("pointerdown",o),()=>{r(),t.removeEventListener("pointerdown",o)}}class n extends t{constructor(t,e){var i,n,s,r,o,l;super(),this.totalDuration=e,this.minLength=0,this.maxLength=1/0,this.id=t.id||`region-${Math.random().toString(32).slice(2)}`,this.start=t.start,this.end=null!==(i=t.end)&&void 0!==i?i:t.start,this.drag=null===(n=t.drag)||void 0===n||n,this.resize=null===(s=t.resize)||void 0===s||s,this.color=null!==(r=t.color)&&void 0!==r?r:"rgba(0, 0, 0, 0.1)",this.minLength=null!==(o=t.minLength)&&void 0!==o?o:this.minLength,this.maxLength=null!==(l=t.maxLength)&&void 0!==l?l:this.maxLength,this.element=this.initElement(t.content),this.renderPosition(),this.initMouseEvents()}initElement(t){const e=document.createElement("div"),i=this.start===this.end;if(e.setAttribute("part",`${i?"marker":"region"} ${this.id}`),e.setAttribute("style",`\n position: absolute;\n height: 100%;\n background-color: ${i?"none":this.color};\n border-left: ${i?"2px solid "+this.color:"none"};\n border-radius: 2px;\n box-sizing: border-box;\n transition: background-color 0.2s ease;\n cursor: ${this.drag?"grab":"default"};\n pointer-events: all;\n `),t&&("string"==typeof t?(this.content=document.createElement("div"),this.content.style.padding=`0.2em ${i?.2:.4}em`,this.content.textContent=t):this.content=t,this.content.setAttribute("part","region-content"),e.appendChild(this.content)),!i){const t=document.createElement("div");t.setAttribute("data-resize","left"),t.setAttribute("style",`\n position: absolute;\n z-index: 2;\n width: 6px;\n height: 100%;\n top: 0;\n left: 0;\n border-left: 2px solid rgba(0, 0, 0, 0.5);\n border-radius: 2px 0 0 2px;\n cursor: ${this.resize?"ew-resize":"default"};\n word-break: keep-all;\n `),t.setAttribute("part","region-handle region-handle-left");const i=t.cloneNode();i.setAttribute("data-resize","right"),i.style.left="",i.style.right="0",i.style.borderRight=i.style.borderLeft,i.style.borderLeft="",i.style.borderRadius="0 2px 2px 0",i.setAttribute("part","region-handle region-handle-right"),e.appendChild(t),e.appendChild(i)}return e}renderPosition(){const t=this.start/this.totalDuration,e=(this.totalDuration-this.end)/this.totalDuration;this.element.style.left=100*t+"%",this.element.style.right=100*e+"%"}initMouseEvents(){const{element:t}=this;if(!t)return;t.addEventListener("click",(t=>this.emit("click",t))),t.addEventListener("mouseenter",(t=>this.emit("over",t))),t.addEventListener("mouseleave",(t=>this.emit("leave",t))),t.addEventListener("dblclick",(t=>this.emit("dblclick",t))),i(t,(t=>this.onMove(t)),(()=>this.onStartMoving()),(()=>this.onEndMoving()));i(t.querySelector('[data-resize="left"]'),(t=>this.onResize(t,"start")),(()=>null),(()=>this.onEndResizing()),1),i(t.querySelector('[data-resize="right"]'),(t=>this.onResize(t,"end")),(()=>null),(()=>this.onEndResizing()),1)}onStartMoving(){this.drag&&(this.element.style.cursor="grabbing")}onEndMoving(){this.drag&&(this.element.style.cursor="grab",this.emit("update-end"))}_onUpdate(t,e){if(!this.element.parentElement)return;const i=t/this.element.parentElement.clientWidth*this.totalDuration,n=e&&"start"!==e?this.start:this.start+i,s=e&&"end"!==e?this.end:this.end+i,r=s-n;n>=0&&s<=this.totalDuration&&n<=s&&r>=this.minLength&&r<=this.maxLength&&(this.start=n,this.end=s,this.renderPosition(),this.emit("update"))}onMove(t){this.drag&&this._onUpdate(t)}onResize(t,e){this.resize&&this._onUpdate(t,e)}onEndResizing(){this.resize&&this.emit("update-end")}_setTotalDuration(t){this.totalDuration=t,this.renderPosition()}play(){this.emit("play")}setOptions(t){var e,i;if(t.color&&(this.color=t.color,this.element.style.backgroundColor=this.color),void 0!==t.drag&&(this.drag=t.drag,this.element.style.cursor=this.drag?"grab":"default"),void 0!==t.resize&&(this.resize=t.resize,this.element.querySelectorAll("[data-resize]").forEach((t=>{t.style.cursor=this.resize?"ew-resize":"default"}))),void 0!==t.start||void 0!==t.end){const n=this.start===this.end;this.start=null!==(e=t.start)&&void 0!==e?e:this.start,this.end=null!==(i=t.end)&&void 0!==i?i:n?this.start:this.end,this.renderPosition()}}remove(){this.emit("remove"),this.element.remove(),this.element=null}}class s extends e{constructor(t){super(t),this.regions=[],this.regionsContainer=this.initRegionsContainer()}static create(t){return new s(t)}onInit(){if(!this.wavesurfer)throw Error("WaveSurfer is not initialized");this.wavesurfer.getWrapper().appendChild(this.regionsContainer);let t=null;this.subscriptions.push(this.wavesurfer.on("timeupdate",(e=>{const i=this.regions.find((t=>t.start<=e&&t.end>=e));t&&t!==i&&(this.emit("region-out",t),t=null),i&&i!==t&&(t=i,this.emit("region-in",i))})))}initRegionsContainer(){const t=document.createElement("div");return t.setAttribute("style","\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n z-index: 3;\n pointer-events: none;\n "),t}getRegions(){return this.regions}avoidOverlapping(t){if(!t.content)return;const e=t.content,i=e.getBoundingClientRect().left,n=t.element.scrollWidth,s=this.regions.filter((e=>{if(e===t||!e.content)return!1;const s=e.content.getBoundingClientRect().left,r=e.element.scrollWidth;return i<s+r&&s<i+n})).map((t=>{var e;return(null===(e=t.content)||void 0===e?void 0:e.getBoundingClientRect().height)||0})).reduce(((t,e)=>t+e),0);e.style.marginTop=`${s}px`}saveRegion(t){this.regionsContainer.appendChild(t.element),this.avoidOverlapping(t),this.regions.push(t),this.emit("region-created",t);const e=[t.on("update-end",(()=>{this.avoidOverlapping(t),this.emit("region-updated",t)})),t.on("play",(()=>{var e,i;null===(e=this.wavesurfer)||void 0===e||e.play(),null===(i=this.wavesurfer)||void 0===i||i.setTime(t.start)})),t.on("click",(e=>{this.emit("region-clicked",t,e)})),t.on("dblclick",(e=>{this.emit("region-double-clicked",t,e)})),t.once("remove",(()=>{e.forEach((t=>t())),this.regions=this.regions.filter((e=>e!==t))}))];this.subscriptions.push(...e)}addRegion(t){if(!this.wavesurfer)throw Error("WaveSurfer is not initialized");const e=this.wavesurfer.getDuration(),i=new n(t,e);return e?this.saveRegion(i):this.subscriptions.push(this.wavesurfer.once("ready",(t=>{i._setTotalDuration(t),this.saveRegion(i)}))),i}enableDragSelection(t){var e,s;const r=null===(s=null===(e=this.wavesurfer)||void 0===e?void 0:e.getWrapper())||void 0===s?void 0:s.querySelector("div");if(!r)return()=>{};let o=null,l=0;return i(r,((t,e,i)=>{o&&o._onUpdate(t,i>l?"end":"start")}),(e=>{if(l=e,!this.wavesurfer)return;const i=this.wavesurfer.getDuration(),s=this.wavesurfer.getWrapper().clientWidth,r=e/s*i,a=(e+5)/s*i;o=new n(Object.assign(Object.assign({},t),{start:r,end:a}),i),this.regionsContainer.appendChild(o.element)}),(()=>{o&&(this.saveRegion(o),o=null)}))}clearRegions(){this.regions.forEach((t=>t.remove()))}destroy(){this.clearRegions(),super.destroy()}}export{s as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):((t="undefined"!=typeof globalThis?globalThis:t||self).WaveSurfer=t.WaveSurfer||{},t.WaveSurfer.Regions=e())}(this,(function(){"use strict";class t{constructor(){this.listeners={}}on(t,e){return this.listeners[t]||(this.listeners[t]=new Set),this.listeners[t].add(e),()=>this.un(t,e)}once(t,e){const i=this.on(t,e),n=this.on(t,(()=>{i(),n()}));return i}un(t,e){this.listeners[t]&&(e?this.listeners[t].delete(e):delete this.listeners[t])}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.options=t}onInit(){}init(t){this.wavesurfer=t,this.onInit()}destroy(){this.emit("destroy"),this.subscriptions.forEach((t=>t()))}}function i(t,e,i,n,s=5){let r=()=>{};if(!t)return r;const o=o=>{if(2===o.button)return;o.preventDefault(),o.stopPropagation();let l=o.clientX,a=o.clientY,h=!1;const d=n=>{n.preventDefault(),n.stopPropagation();const r=n.clientX,o=n.clientY;if(h||Math.abs(r-l)>=s||Math.abs(o-a)>=s){const{left:n,top:s}=t.getBoundingClientRect();h||(h=!0,null==i||i(l-n,a-s)),e(r-l,o-a,r-n,o-s),l=r,a=o}},u=t=>{h&&(t.preventDefault(),t.stopPropagation())},c=()=>{h&&(null==n||n()),r()};document.addEventListener("pointermove",d),document.addEventListener("pointerup",c),document.addEventListener("pointerleave",c),document.addEventListener("click",u,!0),r=()=>{document.removeEventListener("pointermove",d),document.removeEventListener("pointerup",c),document.removeEventListener("pointerleave",c),setTimeout((()=>{document.removeEventListener("click",u,!0)}),10)}};return t.addEventListener("pointerdown",o),()=>{r(),t.removeEventListener("pointerdown",o)}}class n extends t{constructor(t,e){var i,n,s,r,o,l;super(),this.totalDuration=e,this.minLength=0,this.maxLength=1/0,this.id=t.id||`region-${Math.random().toString(32).slice(2)}`,this.start=t.start,this.end=null!==(i=t.end)&&void 0!==i?i:t.start,this.drag=null===(n=t.drag)||void 0===n||n,this.resize=null===(s=t.resize)||void 0===s||s,this.color=null!==(r=t.color)&&void 0!==r?r:"rgba(0, 0, 0, 0.1)",this.minLength=null!==(o=t.minLength)&&void 0!==o?o:this.minLength,this.maxLength=null!==(l=t.maxLength)&&void 0!==l?l:this.maxLength,this.element=this.initElement(t.content),this.renderPosition(),this.initMouseEvents()}initElement(t){const e=document.createElement("div"),i=this.start===this.end;if(e.setAttribute("part",`${i?"marker":"region"} ${this.id}`),e.setAttribute("style",`\n position: absolute;\n height: 100%;\n background-color: ${i?"none":this.color};\n border-left: ${i?"2px solid "+this.color:"none"};\n border-radius: 2px;\n box-sizing: border-box;\n transition: background-color 0.2s ease;\n cursor: ${this.drag?"grab":"default"};\n pointer-events: all;\n `),t&&("string"==typeof t?(this.content=document.createElement("div"),this.content.style.padding=`0.2em ${i?.2:.4}em`,this.content.textContent=t):this.content=t,this.content.setAttribute("part","region-content"),e.appendChild(this.content)),!i){const t=document.createElement("div");t.setAttribute("data-resize","left"),t.setAttribute("style",`\n position: absolute;\n z-index: 2;\n width: 6px;\n height: 100%;\n top: 0;\n left: 0;\n border-left: 2px solid rgba(0, 0, 0, 0.5);\n border-radius: 2px 0 0 2px;\n cursor: ${this.resize?"ew-resize":"default"};\n word-break: keep-all;\n `),t.setAttribute("part","region-handle region-handle-left");const i=t.cloneNode();i.setAttribute("data-resize","right"),i.style.left="",i.style.right="0",i.style.borderRight=i.style.borderLeft,i.style.borderLeft="",i.style.borderRadius="0 2px 2px 0",i.setAttribute("part","region-handle region-handle-right"),e.appendChild(t),e.appendChild(i)}return e}renderPosition(){const t=this.start/this.totalDuration,e=(this.totalDuration-this.end)/this.totalDuration;this.element.style.left=100*t+"%",this.element.style.right=100*e+"%"}initMouseEvents(){const{element:t}=this;if(!t)return;t.addEventListener("click",(t=>this.emit("click",t))),t.addEventListener("mouseenter",(t=>this.emit("over",t))),t.addEventListener("mouseleave",(t=>this.emit("leave",t))),t.addEventListener("dblclick",(t=>this.emit("dblclick",t))),i(t,(t=>this.onMove(t)),(()=>this.onStartMoving()),(()=>this.onEndMoving()));i(t.querySelector('[data-resize="left"]'),(t=>this.onResize(t,"start")),(()=>null),(()=>this.onEndResizing()),1),i(t.querySelector('[data-resize="right"]'),(t=>this.onResize(t,"end")),(()=>null),(()=>this.onEndResizing()),1)}onStartMoving(){this.drag&&(this.element.style.cursor="grabbing")}onEndMoving(){this.drag&&(this.element.style.cursor="grab",this.emit("update-end"))}_onUpdate(t,e){if(!this.element.parentElement)return;const i=t/this.element.parentElement.clientWidth*this.totalDuration,n=e&&"start"!==e?this.start:this.start+i,s=e&&"end"!==e?this.end:this.end+i,r=s-n;n>=0&&s<=this.totalDuration&&n<=s&&r>=this.minLength&&r<=this.maxLength&&(this.start=n,this.end=s,this.renderPosition(),this.emit("update"))}onMove(t){this.drag&&this._onUpdate(t)}onResize(t,e){this.resize&&this._onUpdate(t,e)}onEndResizing(){this.resize&&this.emit("update-end")}_setTotalDuration(t){this.totalDuration=t,this.renderPosition()}play(){this.emit("play")}setOptions(t){var e,i;t.color&&(this.color=t.color,this.element.style.backgroundColor=this.color),void 0!==t.drag&&(this.drag=t.drag,this.element.style.cursor=this.drag?"grab":"default"),void 0!==t.resize&&(this.resize=t.resize,this.element.querySelectorAll("[data-resize]").forEach((t=>{t.style.cursor=this.resize?"ew-resize":"default"}))),void 0
|
|
1
|
+
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):((t="undefined"!=typeof globalThis?globalThis:t||self).WaveSurfer=t.WaveSurfer||{},t.WaveSurfer.Regions=e())}(this,(function(){"use strict";class t{constructor(){this.listeners={}}on(t,e){return this.listeners[t]||(this.listeners[t]=new Set),this.listeners[t].add(e),()=>this.un(t,e)}once(t,e){const i=this.on(t,e),n=this.on(t,(()=>{i(),n()}));return i}un(t,e){this.listeners[t]&&(e?this.listeners[t].delete(e):delete this.listeners[t])}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.options=t}onInit(){}init(t){this.wavesurfer=t,this.onInit()}destroy(){this.emit("destroy"),this.subscriptions.forEach((t=>t()))}}function i(t,e,i,n,s=5){let r=()=>{};if(!t)return r;const o=o=>{if(2===o.button)return;o.preventDefault(),o.stopPropagation();let l=o.clientX,a=o.clientY,h=!1;const d=n=>{n.preventDefault(),n.stopPropagation();const r=n.clientX,o=n.clientY;if(h||Math.abs(r-l)>=s||Math.abs(o-a)>=s){const{left:n,top:s}=t.getBoundingClientRect();h||(h=!0,null==i||i(l-n,a-s)),e(r-l,o-a,r-n,o-s),l=r,a=o}},u=t=>{h&&(t.preventDefault(),t.stopPropagation())},c=()=>{h&&(null==n||n()),r()};document.addEventListener("pointermove",d),document.addEventListener("pointerup",c),document.addEventListener("pointerleave",c),document.addEventListener("click",u,!0),r=()=>{document.removeEventListener("pointermove",d),document.removeEventListener("pointerup",c),document.removeEventListener("pointerleave",c),setTimeout((()=>{document.removeEventListener("click",u,!0)}),10)}};return t.addEventListener("pointerdown",o),()=>{r(),t.removeEventListener("pointerdown",o)}}class n extends t{constructor(t,e){var i,n,s,r,o,l;super(),this.totalDuration=e,this.minLength=0,this.maxLength=1/0,this.id=t.id||`region-${Math.random().toString(32).slice(2)}`,this.start=t.start,this.end=null!==(i=t.end)&&void 0!==i?i:t.start,this.drag=null===(n=t.drag)||void 0===n||n,this.resize=null===(s=t.resize)||void 0===s||s,this.color=null!==(r=t.color)&&void 0!==r?r:"rgba(0, 0, 0, 0.1)",this.minLength=null!==(o=t.minLength)&&void 0!==o?o:this.minLength,this.maxLength=null!==(l=t.maxLength)&&void 0!==l?l:this.maxLength,this.element=this.initElement(t.content),this.renderPosition(),this.initMouseEvents()}initElement(t){const e=document.createElement("div"),i=this.start===this.end;if(e.setAttribute("part",`${i?"marker":"region"} ${this.id}`),e.setAttribute("style",`\n position: absolute;\n height: 100%;\n background-color: ${i?"none":this.color};\n border-left: ${i?"2px solid "+this.color:"none"};\n border-radius: 2px;\n box-sizing: border-box;\n transition: background-color 0.2s ease;\n cursor: ${this.drag?"grab":"default"};\n pointer-events: all;\n `),t&&("string"==typeof t?(this.content=document.createElement("div"),this.content.style.padding=`0.2em ${i?.2:.4}em`,this.content.textContent=t):this.content=t,this.content.setAttribute("part","region-content"),e.appendChild(this.content)),!i){const t=document.createElement("div");t.setAttribute("data-resize","left"),t.setAttribute("style",`\n position: absolute;\n z-index: 2;\n width: 6px;\n height: 100%;\n top: 0;\n left: 0;\n border-left: 2px solid rgba(0, 0, 0, 0.5);\n border-radius: 2px 0 0 2px;\n cursor: ${this.resize?"ew-resize":"default"};\n word-break: keep-all;\n `),t.setAttribute("part","region-handle region-handle-left");const i=t.cloneNode();i.setAttribute("data-resize","right"),i.style.left="",i.style.right="0",i.style.borderRight=i.style.borderLeft,i.style.borderLeft="",i.style.borderRadius="0 2px 2px 0",i.setAttribute("part","region-handle region-handle-right"),e.appendChild(t),e.appendChild(i)}return e}renderPosition(){const t=this.start/this.totalDuration,e=(this.totalDuration-this.end)/this.totalDuration;this.element.style.left=100*t+"%",this.element.style.right=100*e+"%"}initMouseEvents(){const{element:t}=this;if(!t)return;t.addEventListener("click",(t=>this.emit("click",t))),t.addEventListener("mouseenter",(t=>this.emit("over",t))),t.addEventListener("mouseleave",(t=>this.emit("leave",t))),t.addEventListener("dblclick",(t=>this.emit("dblclick",t))),i(t,(t=>this.onMove(t)),(()=>this.onStartMoving()),(()=>this.onEndMoving()));i(t.querySelector('[data-resize="left"]'),(t=>this.onResize(t,"start")),(()=>null),(()=>this.onEndResizing()),1),i(t.querySelector('[data-resize="right"]'),(t=>this.onResize(t,"end")),(()=>null),(()=>this.onEndResizing()),1)}onStartMoving(){this.drag&&(this.element.style.cursor="grabbing")}onEndMoving(){this.drag&&(this.element.style.cursor="grab",this.emit("update-end"))}_onUpdate(t,e){if(!this.element.parentElement)return;const i=t/this.element.parentElement.clientWidth*this.totalDuration,n=e&&"start"!==e?this.start:this.start+i,s=e&&"end"!==e?this.end:this.end+i,r=s-n;n>=0&&s<=this.totalDuration&&n<=s&&r>=this.minLength&&r<=this.maxLength&&(this.start=n,this.end=s,this.renderPosition(),this.emit("update"))}onMove(t){this.drag&&this._onUpdate(t)}onResize(t,e){this.resize&&this._onUpdate(t,e)}onEndResizing(){this.resize&&this.emit("update-end")}_setTotalDuration(t){this.totalDuration=t,this.renderPosition()}play(){this.emit("play")}setOptions(t){var e,i;if(t.color&&(this.color=t.color,this.element.style.backgroundColor=this.color),void 0!==t.drag&&(this.drag=t.drag,this.element.style.cursor=this.drag?"grab":"default"),void 0!==t.resize&&(this.resize=t.resize,this.element.querySelectorAll("[data-resize]").forEach((t=>{t.style.cursor=this.resize?"ew-resize":"default"}))),void 0!==t.start||void 0!==t.end){const n=this.start===this.end;this.start=null!==(e=t.start)&&void 0!==e?e:this.start,this.end=null!==(i=t.end)&&void 0!==i?i:n?this.start:this.end,this.renderPosition()}}remove(){this.emit("remove"),this.element.remove(),this.element=null}}class s extends e{constructor(t){super(t),this.regions=[],this.regionsContainer=this.initRegionsContainer()}static create(t){return new s(t)}onInit(){if(!this.wavesurfer)throw Error("WaveSurfer is not initialized");this.wavesurfer.getWrapper().appendChild(this.regionsContainer);let t=null;this.subscriptions.push(this.wavesurfer.on("timeupdate",(e=>{const i=this.regions.find((t=>t.start<=e&&t.end>=e));t&&t!==i&&(this.emit("region-out",t),t=null),i&&i!==t&&(t=i,this.emit("region-in",i))})))}initRegionsContainer(){const t=document.createElement("div");return t.setAttribute("style","\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n z-index: 3;\n pointer-events: none;\n "),t}getRegions(){return this.regions}avoidOverlapping(t){if(!t.content)return;const e=t.content,i=e.getBoundingClientRect().left,n=t.element.scrollWidth,s=this.regions.filter((e=>{if(e===t||!e.content)return!1;const s=e.content.getBoundingClientRect().left,r=e.element.scrollWidth;return i<s+r&&s<i+n})).map((t=>{var e;return(null===(e=t.content)||void 0===e?void 0:e.getBoundingClientRect().height)||0})).reduce(((t,e)=>t+e),0);e.style.marginTop=`${s}px`}saveRegion(t){this.regionsContainer.appendChild(t.element),this.avoidOverlapping(t),this.regions.push(t),this.emit("region-created",t);const e=[t.on("update-end",(()=>{this.avoidOverlapping(t),this.emit("region-updated",t)})),t.on("play",(()=>{var e,i;null===(e=this.wavesurfer)||void 0===e||e.play(),null===(i=this.wavesurfer)||void 0===i||i.setTime(t.start)})),t.on("click",(e=>{this.emit("region-clicked",t,e)})),t.on("dblclick",(e=>{this.emit("region-double-clicked",t,e)})),t.once("remove",(()=>{e.forEach((t=>t())),this.regions=this.regions.filter((e=>e!==t))}))];this.subscriptions.push(...e)}addRegion(t){if(!this.wavesurfer)throw Error("WaveSurfer is not initialized");const e=this.wavesurfer.getDuration(),i=new n(t,e);return e?this.saveRegion(i):this.subscriptions.push(this.wavesurfer.once("ready",(t=>{i._setTotalDuration(t),this.saveRegion(i)}))),i}enableDragSelection(t){var e,s;const r=null===(s=null===(e=this.wavesurfer)||void 0===e?void 0:e.getWrapper())||void 0===s?void 0:s.querySelector("div");if(!r)return()=>{};let o=null,l=0;return i(r,((t,e,i)=>{o&&o._onUpdate(t,i>l?"end":"start")}),(e=>{if(l=e,!this.wavesurfer)return;const i=this.wavesurfer.getDuration(),s=this.wavesurfer.getWrapper().clientWidth,r=e/s*i,a=(e+5)/s*i;o=new n(Object.assign(Object.assign({},t),{start:r,end:a}),i),this.regionsContainer.appendChild(o.element)}),(()=>{o&&(this.saveRegion(o),o=null)}))}clearRegions(){this.regions.forEach((t=>t.remove()))}destroy(){this.clearRegions(),super.destroy()}}return s}));
|