wavesurfer.js 6.5.0 → 7.0.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/.eslintrc.json +24 -0
  2. package/.prettierrc +8 -0
  3. package/README.md +26 -117
  4. package/dist/base-plugin.d.ts +10 -0
  5. package/dist/base-plugin.js +13 -0
  6. package/dist/decoder.d.ts +10 -0
  7. package/dist/decoder.js +43 -0
  8. package/dist/event-emitter.d.ts +11 -0
  9. package/dist/event-emitter.js +21 -0
  10. package/dist/fetcher.d.ts +4 -0
  11. package/dist/fetcher.js +17 -0
  12. package/dist/index.d.ts +92 -0
  13. package/dist/index.js +166 -0
  14. package/dist/player-webaudio.d.ts +8 -0
  15. package/dist/player-webaudio.js +31 -0
  16. package/dist/player.d.ts +16 -0
  17. package/dist/player.js +40 -0
  18. package/dist/plugins/regions.d.ts +48 -0
  19. package/dist/plugins/regions.js +183 -0
  20. package/dist/renderer.d.ts +34 -0
  21. package/dist/renderer.js +193 -0
  22. package/dist/timer.d.ts +10 -0
  23. package/dist/timer.js +17 -0
  24. package/examples/audio.ogg +0 -0
  25. package/examples/bars.js +19 -0
  26. package/examples/basic.js +8 -0
  27. package/examples/gradient.js +28 -0
  28. package/examples/regions.js +63 -0
  29. package/examples/video.js +19 -0
  30. package/examples/webaudio.js +14 -0
  31. package/package.json +19 -99
  32. package/src/base-plugin.ts +20 -0
  33. package/src/decoder.ts +41 -0
  34. package/src/event-emitter.ts +35 -0
  35. package/src/fetcher.ts +7 -0
  36. package/src/index.ts +252 -0
  37. package/src/player-webaudio.ts +34 -0
  38. package/src/player.ts +50 -0
  39. package/src/plugins/regions.ts +240 -0
  40. package/src/renderer.ts +250 -0
  41. package/src/timer.ts +27 -0
  42. package/tsconfig.json +105 -0
  43. package/tutorial/index.html +47 -0
  44. package/tutorial/src/editor.js +70 -0
  45. package/tutorial/src/init.js +66 -0
  46. package/tutorial/src/url.js +25 -0
  47. package/tutorial/style.css +211 -0
  48. package/yarn-error.log +1049 -0
  49. package/LICENSE +0 -29
  50. package/dist/plugin/wavesurfer.cursor.js +0 -418
  51. package/dist/plugin/wavesurfer.cursor.js.map +0 -1
  52. package/dist/plugin/wavesurfer.cursor.min.js +0 -7
  53. package/dist/plugin/wavesurfer.cursor.min.js.map +0 -1
  54. package/dist/plugin/wavesurfer.elan.js +0 -381
  55. package/dist/plugin/wavesurfer.elan.js.map +0 -1
  56. package/dist/plugin/wavesurfer.elan.min.js +0 -7
  57. package/dist/plugin/wavesurfer.elan.min.js.map +0 -1
  58. package/dist/plugin/wavesurfer.markers.js +0 -520
  59. package/dist/plugin/wavesurfer.markers.js.map +0 -1
  60. package/dist/plugin/wavesurfer.markers.min.js +0 -7
  61. package/dist/plugin/wavesurfer.markers.min.js.map +0 -1
  62. package/dist/plugin/wavesurfer.mediasession.js +0 -181
  63. package/dist/plugin/wavesurfer.mediasession.js.map +0 -1
  64. package/dist/plugin/wavesurfer.mediasession.min.js +0 -7
  65. package/dist/plugin/wavesurfer.mediasession.min.js.map +0 -1
  66. package/dist/plugin/wavesurfer.microphone.js +0 -466
  67. package/dist/plugin/wavesurfer.microphone.js.map +0 -1
  68. package/dist/plugin/wavesurfer.microphone.min.js +0 -7
  69. package/dist/plugin/wavesurfer.microphone.min.js.map +0 -1
  70. package/dist/plugin/wavesurfer.minimap.js +0 -440
  71. package/dist/plugin/wavesurfer.minimap.js.map +0 -1
  72. package/dist/plugin/wavesurfer.minimap.min.js +0 -7
  73. package/dist/plugin/wavesurfer.minimap.min.js.map +0 -1
  74. package/dist/plugin/wavesurfer.playhead.js +0 -300
  75. package/dist/plugin/wavesurfer.playhead.js.map +0 -1
  76. package/dist/plugin/wavesurfer.playhead.min.js +0 -7
  77. package/dist/plugin/wavesurfer.playhead.min.js.map +0 -1
  78. package/dist/plugin/wavesurfer.regions.js +0 -1342
  79. package/dist/plugin/wavesurfer.regions.js.map +0 -1
  80. package/dist/plugin/wavesurfer.regions.min.js +0 -7
  81. package/dist/plugin/wavesurfer.regions.min.js.map +0 -1
  82. package/dist/plugin/wavesurfer.spectrogram.js +0 -736
  83. package/dist/plugin/wavesurfer.spectrogram.js.map +0 -1
  84. package/dist/plugin/wavesurfer.spectrogram.min.js +0 -7
  85. package/dist/plugin/wavesurfer.spectrogram.min.js.map +0 -1
  86. package/dist/plugin/wavesurfer.timeline.js +0 -649
  87. package/dist/plugin/wavesurfer.timeline.js.map +0 -1
  88. package/dist/plugin/wavesurfer.timeline.min.js +0 -7
  89. package/dist/plugin/wavesurfer.timeline.min.js.map +0 -1
  90. package/dist/wavesurfer-html-init.js +0 -381
  91. package/dist/wavesurfer-html-init.js.map +0 -1
  92. package/dist/wavesurfer-html-init.min.js +0 -7
  93. package/dist/wavesurfer-html-init.min.js.map +0 -1
  94. package/dist/wavesurfer.js +0 -6145
  95. package/dist/wavesurfer.js.map +0 -1
  96. package/dist/wavesurfer.min.js +0 -7
  97. package/dist/wavesurfer.min.js.map +0 -1
  98. package/src/drawer.canvasentry.js +0 -427
  99. package/src/drawer.js +0 -413
  100. package/src/drawer.multicanvas.js +0 -617
  101. package/src/html-init.js +0 -241
  102. package/src/mediaelement-webaudio.js +0 -77
  103. package/src/mediaelement.js +0 -443
  104. package/src/peakcache.js +0 -127
  105. package/src/plugin/cursor/index.js +0 -350
  106. package/src/plugin/elan/index.js +0 -307
  107. package/src/plugin/markers/index.js +0 -436
  108. package/src/plugin/mediasession/index.js +0 -94
  109. package/src/plugin/microphone/index.js +0 -415
  110. package/src/plugin/minimap/index.js +0 -403
  111. package/src/plugin/playhead/index.js +0 -226
  112. package/src/plugin/regions/index.js +0 -478
  113. package/src/plugin/regions/region.js +0 -883
  114. package/src/plugin/spectrogram/fft.js +0 -222
  115. package/src/plugin/spectrogram/index.js +0 -522
  116. package/src/plugin/timeline/index.js +0 -600
  117. package/src/util/absMax.js +0 -16
  118. package/src/util/clamp.js +0 -11
  119. package/src/util/fetch.js +0 -222
  120. package/src/util/frame.js +0 -13
  121. package/src/util/get-id.js +0 -22
  122. package/src/util/index.js +0 -14
  123. package/src/util/max.js +0 -16
  124. package/src/util/min.js +0 -16
  125. package/src/util/observer.js +0 -144
  126. package/src/util/orientation.js +0 -98
  127. package/src/util/prevent-click.js +0 -19
  128. package/src/util/request-animation-frame.js +0 -15
  129. package/src/util/silence-mode.js +0 -42
  130. package/src/util/style.js +0 -16
  131. package/src/wavesurfer.js +0 -1797
  132. package/src/webaudio.js +0 -779
@@ -1,617 +0,0 @@
1
- import Drawer from './drawer';
2
- import * as util from './util';
3
- import CanvasEntry from './drawer.canvasentry';
4
-
5
- /**
6
- * MultiCanvas renderer for wavesurfer. Is currently the default and sole
7
- * builtin renderer.
8
- *
9
- * A `MultiCanvas` consists of one or more `CanvasEntry` instances, depending
10
- * on the zoom level.
11
- */
12
- export default class MultiCanvas extends Drawer {
13
- /**
14
- * @param {HTMLElement} container The container node of the wavesurfer instance
15
- * @param {WavesurferParams} params The wavesurfer initialisation options
16
- */
17
- constructor(container, params) {
18
- super(container, params);
19
-
20
- /**
21
- * @type {number}
22
- */
23
- this.maxCanvasWidth = params.maxCanvasWidth;
24
-
25
- /**
26
- * @type {number}
27
- */
28
- this.maxCanvasElementWidth = Math.round(
29
- params.maxCanvasWidth / params.pixelRatio
30
- );
31
-
32
- /**
33
- * Whether or not the progress wave is rendered. If the `waveColor`
34
- * and `progressColor` are the same color it is not.
35
- *
36
- * @type {boolean}
37
- */
38
- this.hasProgressCanvas = params.waveColor != params.progressColor;
39
-
40
- /**
41
- * @type {number}
42
- */
43
- this.halfPixel = 0.5 / params.pixelRatio;
44
-
45
- /**
46
- * List of `CanvasEntry` instances.
47
- *
48
- * @type {Array}
49
- */
50
- this.canvases = [];
51
-
52
- /**
53
- * @type {HTMLElement}
54
- */
55
- this.progressWave = null;
56
-
57
- /**
58
- * Class used to generate entries.
59
- *
60
- * @type {function}
61
- */
62
- this.EntryClass = CanvasEntry;
63
-
64
- /**
65
- * Canvas 2d context attributes.
66
- *
67
- * @type {object}
68
- */
69
- this.canvasContextAttributes = params.drawingContextAttributes;
70
-
71
- /**
72
- * Overlap added between entries to prevent vertical white stripes
73
- * between `canvas` elements.
74
- *
75
- * @type {number}
76
- */
77
- this.overlap = 2 * Math.ceil(params.pixelRatio / 2);
78
-
79
- /**
80
- * The radius of the wave bars. Makes bars rounded
81
- *
82
- * @type {number}
83
- */
84
- this.barRadius = params.barRadius || 0;
85
-
86
- /**
87
- * Whether to render the waveform vertically. Defaults to false.
88
- *
89
- * @type {boolean}
90
- */
91
- this.vertical = params.vertical;
92
- }
93
-
94
- /**
95
- * Initialize the drawer
96
- */
97
- init() {
98
- this.createWrapper();
99
- this.createElements();
100
- }
101
-
102
- /**
103
- * Create the canvas elements and style them
104
- *
105
- */
106
- createElements() {
107
- this.progressWave = util.withOrientation(
108
- this.wrapper.appendChild(document.createElement('wave')),
109
- this.params.vertical
110
- );
111
- this.style(this.progressWave, {
112
- position: 'absolute',
113
- zIndex: 3,
114
- left: 0,
115
- top: 0,
116
- bottom: 0,
117
- overflow: 'hidden',
118
- width: '0',
119
- display: 'none',
120
- boxSizing: 'border-box',
121
- borderRightStyle: 'solid',
122
- pointerEvents: 'none'
123
- });
124
-
125
- this.addCanvas();
126
- this.updateCursor();
127
- }
128
-
129
- /**
130
- * Update cursor style
131
- */
132
- updateCursor() {
133
- this.style(this.progressWave, {
134
- borderRightWidth: this.params.cursorWidth + 'px',
135
- borderRightColor: this.params.cursorColor
136
- });
137
- }
138
-
139
- /**
140
- * Adjust to the updated size by adding or removing canvases
141
- */
142
- updateSize() {
143
- const totalWidth = Math.round(this.width / this.params.pixelRatio);
144
- const requiredCanvases = Math.ceil(
145
- totalWidth / (this.maxCanvasElementWidth + this.overlap)
146
- );
147
-
148
- // add required canvases
149
- while (this.canvases.length < requiredCanvases) {
150
- this.addCanvas();
151
- }
152
-
153
- // remove older existing canvases, if any
154
- while (this.canvases.length > requiredCanvases) {
155
- this.removeCanvas();
156
- }
157
-
158
- let canvasWidth = this.maxCanvasWidth + this.overlap;
159
- const lastCanvas = this.canvases.length - 1;
160
- this.canvases.forEach((entry, i) => {
161
- if (i == lastCanvas) {
162
- canvasWidth = this.width - this.maxCanvasWidth * lastCanvas;
163
- }
164
- this.updateDimensions(entry, canvasWidth, this.height);
165
-
166
- entry.clearWave();
167
- });
168
- }
169
-
170
- /**
171
- * Add a canvas to the canvas list
172
- *
173
- */
174
- addCanvas() {
175
- const entry = new this.EntryClass();
176
- entry.canvasContextAttributes = this.canvasContextAttributes;
177
- entry.hasProgressCanvas = this.hasProgressCanvas;
178
- entry.halfPixel = this.halfPixel;
179
- const leftOffset = this.maxCanvasElementWidth * this.canvases.length;
180
-
181
- // wave
182
- let wave = util.withOrientation(
183
- this.wrapper.appendChild(document.createElement('canvas')),
184
- this.params.vertical
185
- );
186
- this.style(wave, {
187
- position: 'absolute',
188
- zIndex: 2,
189
- left: leftOffset + 'px',
190
- top: 0,
191
- bottom: 0,
192
- height: '100%',
193
- pointerEvents: 'none'
194
- });
195
- entry.initWave(wave);
196
-
197
- // progress
198
- if (this.hasProgressCanvas) {
199
- let progress = util.withOrientation(
200
- this.progressWave.appendChild(document.createElement('canvas')),
201
- this.params.vertical
202
- );
203
- this.style(progress, {
204
- position: 'absolute',
205
- left: leftOffset + 'px',
206
- top: 0,
207
- bottom: 0,
208
- height: '100%'
209
- });
210
- entry.initProgress(progress);
211
- }
212
-
213
- this.canvases.push(entry);
214
- }
215
-
216
- /**
217
- * Pop single canvas from the list
218
- *
219
- */
220
- removeCanvas() {
221
- let lastEntry = this.canvases[this.canvases.length - 1];
222
-
223
- // wave
224
- lastEntry.wave.parentElement.removeChild(lastEntry.wave.domElement);
225
-
226
- // progress
227
- if (this.hasProgressCanvas) {
228
- lastEntry.progress.parentElement.removeChild(lastEntry.progress.domElement);
229
- }
230
-
231
- // cleanup
232
- if (lastEntry) {
233
- lastEntry.destroy();
234
- lastEntry = null;
235
- }
236
-
237
- this.canvases.pop();
238
- }
239
-
240
- /**
241
- * Update the dimensions of a canvas element
242
- *
243
- * @param {CanvasEntry} entry Target entry
244
- * @param {number} width The new width of the element
245
- * @param {number} height The new height of the element
246
- */
247
- updateDimensions(entry, width, height) {
248
- const elementWidth = Math.round(width / this.params.pixelRatio);
249
- const totalWidth = Math.round(this.width / this.params.pixelRatio);
250
-
251
- // update canvas dimensions
252
- entry.updateDimensions(elementWidth, totalWidth, width, height);
253
-
254
- // style element
255
- this.style(this.progressWave, { display: 'block' });
256
- }
257
-
258
- /**
259
- * Clear the whole multi-canvas
260
- */
261
- clearWave() {
262
- util.frame(() => {
263
- this.canvases.forEach(entry => entry.clearWave());
264
- })();
265
- }
266
-
267
- /**
268
- * Draw a waveform with bars
269
- *
270
- * @param {number[]|Number.<Array[]>} peaks Can also be an array of arrays
271
- * for split channel rendering
272
- * @param {number} channelIndex The index of the current channel. Normally
273
- * should be 0. Must be an integer.
274
- * @param {number} start The x-offset of the beginning of the area that
275
- * should be rendered
276
- * @param {number} end The x-offset of the end of the area that should be
277
- * rendered
278
- * @returns {void}
279
- */
280
- drawBars(peaks, channelIndex, start, end) {
281
- return this.prepareDraw(
282
- peaks,
283
- channelIndex,
284
- start,
285
- end,
286
- ({ absmax, hasMinVals, height, offsetY, halfH, peaks, channelIndex: ch }) => {
287
- // if drawBars was called within ws.empty we don't pass a start and
288
- // don't want anything to happen
289
- if (start === undefined) {
290
- return;
291
- }
292
- // Skip every other value if there are negatives.
293
- const peakIndexScale = hasMinVals ? 2 : 1;
294
- const length = peaks.length / peakIndexScale;
295
- const bar = this.params.barWidth * this.params.pixelRatio;
296
- const gap =
297
- this.params.barGap === null
298
- ? Math.max(this.params.pixelRatio, ~~(bar / 2))
299
- : Math.max(
300
- this.params.pixelRatio,
301
- this.params.barGap * this.params.pixelRatio
302
- );
303
- const step = bar + gap;
304
-
305
- const scale = length / this.width;
306
- const first = start;
307
- const last = end;
308
- let peakIndex = first;
309
- for (peakIndex; peakIndex < last; peakIndex += step) {
310
-
311
- // search for the highest peak in the range this bar falls into
312
- let peak = 0;
313
- let peakIndexRange = Math.floor(peakIndex * scale) * peakIndexScale; // start index
314
- const peakIndexEnd = Math.floor((peakIndex + step) * scale) * peakIndexScale;
315
- do { // do..while makes sure at least one peak is always evaluated
316
- const newPeak = Math.abs(peaks[peakIndexRange]); // for arrays starting with negative values
317
- if (newPeak > peak) {
318
- peak = newPeak; // higher
319
- }
320
- peakIndexRange += peakIndexScale; // skip every other value for negatives
321
- } while (peakIndexRange < peakIndexEnd);
322
-
323
- // calculate the height of this bar according to the highest peak found
324
- let h = Math.round((peak / absmax) * halfH);
325
-
326
- // raise the bar height to the specified minimum height
327
- // Math.max is used to replace any value smaller than barMinHeight (not just 0) with barMinHeight
328
- if (this.params.barMinHeight) {
329
- h = Math.max(h, this.params.barMinHeight);
330
- }
331
-
332
- this.fillRect(
333
- peakIndex + this.halfPixel,
334
- halfH - h + offsetY,
335
- bar + this.halfPixel,
336
- h * 2,
337
- this.barRadius,
338
- ch
339
- );
340
- }
341
- }
342
- );
343
- }
344
-
345
- /**
346
- * Draw a waveform
347
- *
348
- * @param {number[]|Number.<Array[]>} peaks Can also be an array of arrays
349
- * for split channel rendering
350
- * @param {number} channelIndex The index of the current channel. Normally
351
- * should be 0
352
- * @param {number?} start The x-offset of the beginning of the area that
353
- * should be rendered (If this isn't set only a flat line is rendered)
354
- * @param {number?} end The x-offset of the end of the area that should be
355
- * rendered
356
- * @returns {void}
357
- */
358
- drawWave(peaks, channelIndex, start, end) {
359
- return this.prepareDraw(
360
- peaks,
361
- channelIndex,
362
- start,
363
- end,
364
- ({ absmax, hasMinVals, height, offsetY, halfH, peaks, channelIndex }) => {
365
- if (!hasMinVals) {
366
- const reflectedPeaks = [];
367
- const len = peaks.length;
368
- let i = 0;
369
- for (i; i < len; i++) {
370
- reflectedPeaks[2 * i] = peaks[i];
371
- reflectedPeaks[2 * i + 1] = -peaks[i];
372
- }
373
- peaks = reflectedPeaks;
374
- }
375
-
376
- // if drawWave was called within ws.empty we don't pass a start and
377
- // end and simply want a flat line
378
- if (start !== undefined) {
379
- this.drawLine(peaks, absmax, halfH, offsetY, start, end, channelIndex);
380
- }
381
-
382
- // always draw a median line
383
- this.fillRect(
384
- 0,
385
- halfH + offsetY - this.halfPixel,
386
- this.width,
387
- this.halfPixel,
388
- this.barRadius,
389
- channelIndex
390
- );
391
- }
392
- );
393
- }
394
-
395
- /**
396
- * Tell the canvas entries to render their portion of the waveform
397
- *
398
- * @param {number[]} peaks Peaks data
399
- * @param {number} absmax Maximum peak value (absolute)
400
- * @param {number} halfH Half the height of the waveform
401
- * @param {number} offsetY Offset to the top
402
- * @param {number} start The x-offset of the beginning of the area that
403
- * should be rendered
404
- * @param {number} end The x-offset of the end of the area that
405
- * should be rendered
406
- * @param {channelIndex} channelIndex The channel index of the line drawn
407
- */
408
- drawLine(peaks, absmax, halfH, offsetY, start, end, channelIndex) {
409
- const { waveColor, progressColor } = this.params.splitChannelsOptions.channelColors[channelIndex] || {};
410
- this.canvases.forEach((entry, i) => {
411
- this.setFillStyles(entry, waveColor, progressColor);
412
- this.applyCanvasTransforms(entry, this.params.vertical);
413
- entry.drawLines(peaks, absmax, halfH, offsetY, start, end);
414
- });
415
- }
416
-
417
- /**
418
- * Draw a rectangle on the multi-canvas
419
- *
420
- * @param {number} x X-position of the rectangle
421
- * @param {number} y Y-position of the rectangle
422
- * @param {number} width Width of the rectangle
423
- * @param {number} height Height of the rectangle
424
- * @param {number} radius Radius of the rectangle
425
- * @param {channelIndex} channelIndex The channel index of the bar drawn
426
- */
427
- fillRect(x, y, width, height, radius, channelIndex) {
428
- const startCanvas = Math.floor(x / this.maxCanvasWidth);
429
- const endCanvas = Math.min(
430
- Math.ceil((x + width) / this.maxCanvasWidth) + 1,
431
- this.canvases.length
432
- );
433
- let i = startCanvas;
434
- for (i; i < endCanvas; i++) {
435
- const entry = this.canvases[i];
436
- const leftOffset = i * this.maxCanvasWidth;
437
-
438
- const intersection = {
439
- x1: Math.max(x, i * this.maxCanvasWidth),
440
- y1: y,
441
- x2: Math.min(
442
- x + width,
443
- i * this.maxCanvasWidth + entry.wave.width
444
- ),
445
- y2: y + height
446
- };
447
-
448
- if (intersection.x1 < intersection.x2) {
449
- const { waveColor, progressColor } = this.params.splitChannelsOptions.channelColors[channelIndex] || {};
450
- this.setFillStyles(entry, waveColor, progressColor);
451
- this.applyCanvasTransforms(entry, this.params.vertical);
452
-
453
- entry.fillRects(
454
- intersection.x1 - leftOffset,
455
- intersection.y1,
456
- intersection.x2 - intersection.x1,
457
- intersection.y2 - intersection.y1,
458
- radius
459
- );
460
- }
461
- }
462
- }
463
-
464
- /**
465
- * Returns whether to hide the channel from being drawn based on params.
466
- *
467
- * @param {number} channelIndex The index of the current channel.
468
- * @returns {bool} True to hide the channel, false to draw.
469
- */
470
- hideChannel(channelIndex) {
471
- return this.params.splitChannels && this.params.splitChannelsOptions.filterChannels.includes(channelIndex);
472
- }
473
-
474
- /**
475
- * Performs preparation tasks and calculations which are shared by `drawBars`
476
- * and `drawWave`
477
- *
478
- * @param {number[]|Number.<Array[]>} peaks Can also be an array of arrays for
479
- * split channel rendering
480
- * @param {number} channelIndex The index of the current channel. Normally
481
- * should be 0
482
- * @param {number?} start The x-offset of the beginning of the area that
483
- * should be rendered. If this isn't set only a flat line is rendered
484
- * @param {number?} end The x-offset of the end of the area that should be
485
- * rendered
486
- * @param {function} fn The render function to call, e.g. `drawWave`
487
- * @param {number} drawIndex The index of the current channel after filtering.
488
- * @param {number?} normalizedMax Maximum modulation value across channels for use with relativeNormalization. Ignored when undefined
489
- * @returns {void}
490
- */
491
- prepareDraw(peaks, channelIndex, start, end, fn, drawIndex, normalizedMax) {
492
- return util.frame(() => {
493
- // Split channels and call this function with the channelIndex set
494
- if (peaks[0] instanceof Array) {
495
- const channels = peaks;
496
-
497
- if (this.params.splitChannels) {
498
- const filteredChannels = channels.filter((c, i) => !this.hideChannel(i));
499
- if (!this.params.splitChannelsOptions.overlay) {
500
- this.setHeight(
501
- Math.max(filteredChannels.length, 1) *
502
- this.params.height *
503
- this.params.pixelRatio
504
- );
505
- }
506
-
507
- let overallAbsMax;
508
- if (this.params.splitChannelsOptions && this.params.splitChannelsOptions.relativeNormalization) {
509
- // calculate maximum peak across channels to use for normalization
510
- overallAbsMax = util.max(channels.map((channelPeaks => util.absMax(channelPeaks))));
511
- }
512
-
513
-
514
- return channels.forEach((channelPeaks, i) =>
515
- this.prepareDraw(channelPeaks, i, start, end, fn, filteredChannels.indexOf(channelPeaks), overallAbsMax)
516
- );
517
- }
518
- peaks = channels[0];
519
- }
520
-
521
- // Return and do not draw channel peaks if hidden.
522
- if (this.hideChannel(channelIndex)) {
523
- return;
524
- }
525
-
526
- // calculate maximum modulation value, either from the barHeight
527
- // parameter or if normalize=true from the largest value in the peak
528
- // set
529
- let absmax = 1 / this.params.barHeight;
530
- if (this.params.normalize) {
531
- absmax = normalizedMax === undefined ? util.absMax(peaks) : normalizedMax;
532
- }
533
-
534
- // Bar wave draws the bottom only as a reflection of the top,
535
- // so we don't need negative values
536
- const hasMinVals = [].some.call(peaks, val => val < 0);
537
- const height = this.params.height * this.params.pixelRatio;
538
- const halfH = height / 2;
539
-
540
- let offsetY = height * drawIndex || 0;
541
-
542
- // Override offsetY if overlay is true
543
- if (this.params.splitChannelsOptions && this.params.splitChannelsOptions.overlay) {
544
- offsetY = 0;
545
- }
546
-
547
- return fn({
548
- absmax: absmax,
549
- hasMinVals: hasMinVals,
550
- height: height,
551
- offsetY: offsetY,
552
- halfH: halfH,
553
- peaks: peaks,
554
- channelIndex: channelIndex
555
- });
556
- })();
557
- }
558
-
559
- /**
560
- * Set the fill styles for a certain entry (wave and progress)
561
- *
562
- * @param {CanvasEntry} entry Target entry
563
- * @param {string} waveColor Wave color to draw this entry
564
- * @param {string} progressColor Progress color to draw this entry
565
- */
566
- setFillStyles(entry, waveColor = this.params.waveColor, progressColor = this.params.progressColor) {
567
- entry.setFillStyles(waveColor, progressColor);
568
- }
569
-
570
- /**
571
- * Set the canvas transforms for a certain entry (wave and progress)
572
- *
573
- * @param {CanvasEntry} entry Target entry
574
- * @param {boolean} vertical Whether to render the waveform vertically
575
- */
576
- applyCanvasTransforms(entry, vertical = false) {
577
- entry.applyCanvasTransforms(vertical);
578
- }
579
-
580
- /**
581
- * Return image data of the multi-canvas
582
- *
583
- * When using a `type` of `'blob'`, this will return a `Promise`.
584
- *
585
- * @param {string} format='image/png' An optional value of a format type.
586
- * @param {number} quality=0.92 An optional value between 0 and 1.
587
- * @param {string} type='dataURL' Either 'dataURL' or 'blob'.
588
- * @return {string|string[]|Promise} When using the default `'dataURL'`
589
- * `type` this returns a single data URL or an array of data URLs,
590
- * one for each canvas. When using the `'blob'` `type` this returns a
591
- * `Promise` that resolves with an array of `Blob` instances, one for each
592
- * canvas.
593
- */
594
- getImage(format, quality, type) {
595
- if (type === 'blob') {
596
- return Promise.all(
597
- this.canvases.map(entry => {
598
- return entry.getImage(format, quality, type);
599
- })
600
- );
601
- } else if (type === 'dataURL') {
602
- let images = this.canvases.map(entry =>
603
- entry.getImage(format, quality, type)
604
- );
605
- return images.length > 1 ? images : images[0];
606
- }
607
- }
608
-
609
- /**
610
- * Render the new progress
611
- *
612
- * @param {number} position X-offset of progress position in pixels
613
- */
614
- updateProgress(position) {
615
- this.style(this.progressWave, { width: position + 'px' });
616
- }
617
- }