UNPKG

17.2 kBJavaScriptView Raw
1/*!
2 * wavesurfer.js markers plugin 6.4.0 (2022-11-05)
3 * https://wavesurfer-js.org
4 * @license BSD-3-Clause
5 */
6(function webpackUniversalModuleDefinition(root, factory) {
7 if(typeof exports === 'object' && typeof module === 'object')
8 module.exports = factory();
9 else if(typeof define === 'function' && define.amd)
10 define("WaveSurfer", [], factory);
11 else if(typeof exports === 'object')
12 exports["WaveSurfer"] = factory();
13 else
14 root["WaveSurfer"] = root["WaveSurfer"] || {}, root["WaveSurfer"]["markers"] = factory();
15})(self, () => {
16return /******/ (() => { // webpackBootstrap
17/******/ "use strict";
18/******/ var __webpack_modules__ = ({
19
20/***/ "./src/plugin/markers/index.js":
21/*!*************************************!*\
22 !*** ./src/plugin/markers/index.js ***!
23 \*************************************/
24/***/ ((module, exports) => {
25
26
27
28Object.defineProperty(exports, "__esModule", ({
29 value: true
30}));
31exports["default"] = void 0;
32function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
33function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
34function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
35/**
36 * @typedef {Object} MarkerParams
37 * @desc The parameters used to describe a marker.
38 * @example wavesurfer.addMarker(regionParams);
39 * @property {number} time The time to set the marker at
40 * @property {?label} string An optional marker label
41 * @property {?tooltip} string An optional marker tooltip
42 * @property {?color} string Background color for marker
43 * @property {?position} string "top" or "bottom", defaults to "bottom"
44 * @property {?markerElement} element An HTML element to display instead of the default marker image
45 * @property {?draggable} boolean Set marker as draggable, defaults to false
46 * @property {?boolean} preventContextMenu Determines whether the context menu
47 * is prevented from being opened, defaults to false
48 */
49
50/**
51 * Markers are points in time in the audio that can be jumped to.
52 *
53 * @implements {PluginClass}
54 *
55 * @example
56 * import MarkersPlugin from 'wavesurfer.markers.js';
57 *
58 * // if you are using <script> tags
59 * var MarkerPlugin = window.WaveSurfer.markers;
60 *
61 * // ... initialising wavesurfer with the plugin
62 * var wavesurfer = WaveSurfer.create({
63 * // wavesurfer options ...
64 * plugins: [
65 * MarkersPlugin.create({
66 * // plugin options ...
67 * })
68 * ]
69 * });
70 */
71
72var DEFAULT_FILL_COLOR = "#D8D8D8";
73var DEFAULT_POSITION = "bottom";
74var MarkersPlugin = /*#__PURE__*/function () {
75 function MarkersPlugin(params, ws) {
76 var _this = this;
77 _classCallCheck(this, MarkersPlugin);
78 this.params = params;
79 this.wavesurfer = ws;
80 this.util = ws.util;
81 this.style = this.util.style;
82 this.markerLineWidth = 1;
83 this.markerWidth = 11;
84 this.markerHeight = 22;
85 this.dragging = false;
86 this._onResize = function () {
87 _this._updateMarkerPositions();
88 };
89 this._onBackendCreated = function () {
90 _this.wrapper = _this.wavesurfer.drawer.wrapper;
91 if (_this.params.markers) {
92 _this.params.markers.forEach(function (marker) {
93 return _this.add(marker);
94 });
95 }
96 window.addEventListener('resize', _this._onResize, true);
97 window.addEventListener('orientationchange', _this._onResize, true);
98 _this.wavesurfer.on('zoom', _this._onResize);
99 if (!_this.markers.find(function (marker) {
100 return marker.draggable;
101 })) {
102 return;
103 }
104 _this.onMouseMove = function (e) {
105 return _this._onMouseMove(e);
106 };
107 window.addEventListener('mousemove', _this.onMouseMove);
108 _this.onMouseUp = function (e) {
109 return _this._onMouseUp(e);
110 };
111 window.addEventListener("mouseup", _this.onMouseUp);
112 };
113 this.markers = [];
114 this._onReady = function () {
115 _this.wrapper = _this.wavesurfer.drawer.wrapper;
116 _this._updateMarkerPositions();
117 };
118 }
119 _createClass(MarkersPlugin, [{
120 key: "init",
121 value: function init() {
122 // Check if ws is ready
123 if (this.wavesurfer.isReady) {
124 this._onBackendCreated();
125 this._onReady();
126 } else {
127 this.wavesurfer.once('ready', this._onReady);
128 this.wavesurfer.once('backend-created', this._onBackendCreated);
129 }
130 }
131 }, {
132 key: "destroy",
133 value: function destroy() {
134 this.wavesurfer.un('ready', this._onReady);
135 this.wavesurfer.un('backend-created', this._onBackendCreated);
136 this.wavesurfer.un('zoom', this._onResize);
137 window.removeEventListener('resize', this._onResize, true);
138 window.removeEventListener('orientationchange', this._onResize, true);
139 if (this.onMouseMove) {
140 window.removeEventListener('mousemove', this.onMouseMove);
141 }
142 if (this.onMouseUp) {
143 window.removeEventListener("mouseup", this.onMouseUp);
144 }
145 this.clear();
146 }
147
148 /**
149 * Add a marker
150 *
151 * @param {MarkerParams} params Marker definition
152 * @return {object} The created marker
153 */
154 }, {
155 key: "add",
156 value: function add(params) {
157 var marker = {
158 time: params.time,
159 label: params.label,
160 tooltip: params.tooltip,
161 color: params.color || DEFAULT_FILL_COLOR,
162 position: params.position || DEFAULT_POSITION,
163 draggable: !!params.draggable,
164 preventContextMenu: !!params.preventContextMenu
165 };
166 marker.el = this._createMarkerElement(marker, params.markerElement);
167 this.wrapper.appendChild(marker.el);
168 this.markers.push(marker);
169 this._updateMarkerPositions();
170 this._registerEvents();
171 return marker;
172 }
173
174 /**
175 * Remove a marker
176 *
177 * @param {number} index Index of the marker to remove
178 */
179 }, {
180 key: "remove",
181 value: function remove(index) {
182 var marker = this.markers[index];
183 if (!marker) {
184 return;
185 }
186 var label = marker.el.getElementsByClassName("marker-label")[0];
187 if (label) {
188 if (label._onContextMenu) {
189 label.removeEventListener("contextmenu", label._onContextMenu);
190 }
191 if (label._onClick) {
192 label.removeEventListener("click", label._onClick);
193 }
194 if (label._onMouseDown) {
195 label.removeEventListener("mousedown", label._onMouseDown);
196 }
197 }
198 this.wrapper.removeChild(marker.el);
199 this.markers.splice(index, 1);
200 this._unregisterEvents();
201 }
202 }, {
203 key: "_createPointerSVG",
204 value: function _createPointerSVG(color, position) {
205 var svgNS = "http://www.w3.org/2000/svg";
206 var el = document.createElementNS(svgNS, "svg");
207 var polygon = document.createElementNS(svgNS, "polygon");
208 el.setAttribute("viewBox", "0 0 40 80");
209 polygon.setAttribute("id", "polygon");
210 polygon.setAttribute("stroke", "#979797");
211 polygon.setAttribute("fill", color);
212 polygon.setAttribute("points", "20 0 40 30 40 80 0 80 0 30");
213 if (position == "top") {
214 polygon.setAttribute("transform", "rotate(180, 20 40)");
215 }
216 el.appendChild(polygon);
217 this.style(el, {
218 width: this.markerWidth + "px",
219 height: this.markerHeight + "px",
220 "min-width": this.markerWidth + "px",
221 "margin-right": "5px",
222 "z-index": 4
223 });
224 return el;
225 }
226 }, {
227 key: "_createMarkerElement",
228 value: function _createMarkerElement(marker, markerElement) {
229 var _this2 = this;
230 var label = marker.label;
231 var tooltip = marker.tooltip;
232 var el = document.createElement('marker');
233 el.className = "wavesurfer-marker";
234 this.style(el, {
235 position: "absolute",
236 height: "100%",
237 display: "flex",
238 overflow: "hidden",
239 "flex-direction": marker.position == "top" ? "column-reverse" : "column"
240 });
241 var line = document.createElement('div');
242 var width = markerElement ? markerElement.width : this.markerWidth;
243 marker.offset = (width - this.markerLineWidth) / 2;
244 this.style(line, {
245 "flex-grow": 1,
246 "margin-left": marker.offset + "px",
247 background: "black",
248 width: this.markerLineWidth + "px",
249 opacity: 0.1
250 });
251 el.appendChild(line);
252 var labelDiv = document.createElement('div');
253 var point = markerElement || this._createPointerSVG(marker.color, marker.position);
254 if (marker.draggable) {
255 point.draggable = false;
256 }
257 labelDiv.appendChild(point);
258 if (label) {
259 var labelEl = document.createElement('span');
260 labelEl.innerText = label;
261 labelEl.setAttribute('title', tooltip);
262 this.style(labelEl, {
263 "font-family": "monospace",
264 "font-size": "90%"
265 });
266 labelDiv.appendChild(labelEl);
267 }
268 this.style(labelDiv, {
269 display: "flex",
270 "align-items": "center",
271 cursor: "pointer"
272 });
273 labelDiv.classList.add("marker-label");
274 el.appendChild(labelDiv);
275 labelDiv._onClick = function (e) {
276 e.stopPropagation();
277 // Click event is caught when the marker-drop event was dispatched.
278 // Drop event was dispatched at this moment, but this.dragging
279 // is waiting for the next tick to set as false
280 if (_this2.dragging) {
281 return;
282 }
283 _this2.wavesurfer.setCurrentTime(marker.time);
284 _this2.wavesurfer.fireEvent("marker-click", marker, e);
285 };
286 labelDiv.addEventListener("click", labelDiv._onClick);
287 labelDiv._onContextMenu = function (e) {
288 if (marker.preventContextMenu) {
289 e.preventDefault();
290 }
291 _this2.wavesurfer.fireEvent("marker-contextmenu", marker, e);
292 };
293 labelDiv.addEventListener("contextmenu", labelDiv._onContextMenu);
294 if (marker.draggable) {
295 labelDiv._onMouseDown = function () {
296 _this2.selectedMarker = marker;
297 };
298 labelDiv.addEventListener("mousedown", labelDiv._onMouseDown);
299 }
300 return el;
301 }
302 }, {
303 key: "_updateMarkerPositions",
304 value: function _updateMarkerPositions() {
305 for (var i = 0; i < this.markers.length; i++) {
306 var marker = this.markers[i];
307 this._updateMarkerPosition(marker);
308 }
309 }
310
311 /**
312 * Update a marker position based on its time property.
313 *
314 * @private
315 * @param {MarkerParams} params The marker to update.
316 * @returns {void}
317 */
318 }, {
319 key: "_updateMarkerPosition",
320 value: function _updateMarkerPosition(params) {
321 var duration = this.wavesurfer.getDuration();
322 var elementWidth = this.wavesurfer.drawer.width / this.wavesurfer.params.pixelRatio;
323 var positionPct = Math.min(params.time / duration, 1);
324 var leftPx = elementWidth * positionPct - params.offset;
325 this.style(params.el, {
326 "left": leftPx + "px",
327 "max-width": elementWidth - leftPx + "px"
328 });
329 }
330
331 /**
332 * Fires `marker-drag` event, update the `time` property for the
333 * selected marker based on the mouse position, and calls to update
334 * its position.
335 *
336 * @private
337 * @param {MouseEvent} event The mouse event.
338 * @returns {void}
339 */
340 }, {
341 key: "_onMouseMove",
342 value: function _onMouseMove(event) {
343 if (!this.selectedMarker) {
344 return;
345 }
346 if (!this.dragging) {
347 this.dragging = true;
348 this.wavesurfer.fireEvent("marker-drag", this.selectedMarker, event);
349 }
350 this.selectedMarker.time = this.wavesurfer.drawer.handleEvent(event) * this.wavesurfer.getDuration();
351 this._updateMarkerPositions();
352 }
353
354 /**
355 * Fires `marker-drop` event and unselect the dragged marker.
356 *
357 * @private
358 * @param {MouseEvent} event The mouse event.
359 * @returns {void}
360 */
361 }, {
362 key: "_onMouseUp",
363 value: function _onMouseUp(event) {
364 var _this3 = this;
365 if (this.selectedMarker) {
366 setTimeout(function () {
367 _this3.selectedMarker = false;
368 _this3.dragging = false;
369 }, 0);
370 }
371 if (!this.dragging) {
372 return;
373 }
374 event.stopPropagation();
375 var duration = this.wavesurfer.getDuration();
376 this.selectedMarker.time = this.wavesurfer.drawer.handleEvent(event) * duration;
377 this._updateMarkerPositions();
378 this.wavesurfer.fireEvent("marker-drop", this.selectedMarker, event);
379 }
380 }, {
381 key: "_registerEvents",
382 value: function _registerEvents() {
383 var _this4 = this;
384 if (!this.markers.find(function (marker) {
385 return marker.draggable;
386 })) {
387 return;
388 }
389 //we have some draggable markers, check for listeners
390 if (!this.onMouseMove) {
391 this.onMouseMove = function (e) {
392 return _this4._onMouseMove(e);
393 };
394 window.addEventListener('mousemove', this.onMouseMove);
395 }
396 if (!this.onMouseUp) {
397 this.onMouseUp = function (e) {
398 return _this4._onMouseUp(e);
399 };
400 window.addEventListener("mouseup", this.onMouseUp);
401 }
402 }
403 }, {
404 key: "_unregisterEvents",
405 value: function _unregisterEvents() {
406 if (this.markers.find(function (marker) {
407 return marker.draggable;
408 })) {
409 return;
410 }
411 //we don't have any draggable markers, unregister listeners
412 if (this.onMouseMove) {
413 window.removeEventListener('mousemove', this.onMouseMove);
414 this.onMouseMove = null;
415 }
416 if (this.onMouseUp) {
417 window.removeEventListener("mouseup", this.onMouseUp);
418 this.onMouseUp = null;
419 }
420 }
421
422 /**
423 * Remove all markers
424 */
425 }, {
426 key: "clear",
427 value: function clear() {
428 while (this.markers.length > 0) {
429 this.remove(0);
430 }
431 }
432 }], [{
433 key: "create",
434 value:
435 /**
436 * @typedef {Object} MarkersPluginParams
437 * @property {?MarkerParams[]} markers Initial set of markers
438 * @fires MarkersPlugin#marker-click
439 * @fires MarkersPlugin#marker-drag
440 * @fires MarkersPlugin#marker-drop
441 */
442
443 /**
444 * Markers plugin definition factory
445 *
446 * This function must be used to create a plugin definition which can be
447 * used by wavesurfer to correctly instantiate the plugin.
448 *
449 * @param {MarkersPluginParams} params parameters use to initialise the plugin
450 * @since 4.6.0
451 * @return {PluginDefinition} an object representing the plugin
452 */
453 function create(params) {
454 return {
455 name: 'markers',
456 deferInit: params && params.deferInit ? params.deferInit : false,
457 params: params,
458 staticProps: {
459 addMarker: function addMarker(options) {
460 if (!this.initialisedPluginList.markers) {
461 this.initPlugin('markers');
462 }
463 return this.markers.add(options);
464 },
465 clearMarkers: function clearMarkers() {
466 this.markers && this.markers.clear();
467 }
468 },
469 instance: MarkersPlugin
470 };
471 }
472 }]);
473 return MarkersPlugin;
474}();
475exports["default"] = MarkersPlugin;
476module.exports = exports.default;
477
478/***/ })
479
480/******/ });
481/************************************************************************/
482/******/ // The module cache
483/******/ var __webpack_module_cache__ = {};
484/******/
485/******/ // The require function
486/******/ function __webpack_require__(moduleId) {
487/******/ // Check if module is in cache
488/******/ var cachedModule = __webpack_module_cache__[moduleId];
489/******/ if (cachedModule !== undefined) {
490/******/ return cachedModule.exports;
491/******/ }
492/******/ // Create a new module (and put it into the cache)
493/******/ var module = __webpack_module_cache__[moduleId] = {
494/******/ // no module.id needed
495/******/ // no module.loaded needed
496/******/ exports: {}
497/******/ };
498/******/
499/******/ // Execute the module function
500/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
501/******/
502/******/ // Return the exports of the module
503/******/ return module.exports;
504/******/ }
505/******/
506/************************************************************************/
507/******/
508/******/ // startup
509/******/ // Load entry module and return exports
510/******/ // This entry module is referenced by other modules so it can't be inlined
511/******/ var __webpack_exports__ = __webpack_require__("./src/plugin/markers/index.js");
512/******/
513/******/ return __webpack_exports__;
514/******/ })()
515;
516});
517//# sourceMappingURL=wavesurfer.markers.js.map
\No newline at end of file