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
package/dist/plugins/zoom.min.js
CHANGED
|
@@ -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.Zoom=e())}(this,(function(){"use strict";class t{constructor(){this.listeners={}}on(t,e,
|
|
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.Zoom=e())}(this,(function(){"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}}const i={scale:.5,deltaThreshold:5,exponentialZooming:!1,iterations:20};class s extends e{constructor(t){super(t||{}),this.wrapper=void 0,this.container=null,this.accumulatedDelta=0,this.pointerTime=0,this.oldX=0,this.endZoom=0,this.startZoom=0,this.isPinching=!1,this.initialPinchDistance=0,this.initialZoom=0,this.onWheel=t=>{if(this.wavesurfer&&this.container&&!(Math.abs(t.deltaX)>=Math.abs(t.deltaY))&&(t.preventDefault(),this.accumulatedDelta+=-t.deltaY,0===this.startZoom&&this.options.exponentialZooming&&(this.startZoom=this.wavesurfer.getWrapper().clientWidth/this.wavesurfer.getDuration()),0===this.options.deltaThreshold||Math.abs(this.accumulatedDelta)>=this.options.deltaThreshold)){const e=this.wavesurfer.getDuration(),i=0===this.wavesurfer.options.minPxPerSec?this.wavesurfer.getWrapper().scrollWidth/e:this.wavesurfer.options.minPxPerSec,s=t.clientX-this.container.getBoundingClientRect().left,n=this.container.clientWidth,o=this.wavesurfer.getScroll();s===this.oldX&&0!==this.oldX||(this.pointerTime=(o+s)/i),this.oldX=s;const h=this.calculateNewZoom(i,this.accumulatedDelta),r=n/h*(s/n);h*e<n?(this.wavesurfer.zoom(n/e),this.container.scrollLeft=0):(this.wavesurfer.zoom(h),this.container.scrollLeft=(this.pointerTime-r)*h),this.accumulatedDelta=0}},this.calculateNewZoom=(t,e)=>{let i;if(this.options.exponentialZooming){const s=e>0?Math.pow(this.endZoom/this.startZoom,1/(this.options.iterations-1)):Math.pow(this.startZoom/this.endZoom,1/(this.options.iterations-1));i=Math.max(0,t*s)}else i=Math.max(0,t+e*this.options.scale);return Math.min(i,this.options.maxZoom)},this.onTouchStart=t=>{if(this.wavesurfer&&this.container&&2===t.touches.length){t.preventDefault(),this.isPinching=!0,this.initialPinchDistance=this.getTouchDistance(t);const e=this.wavesurfer.getDuration();this.initialZoom=0===this.wavesurfer.options.minPxPerSec?this.wavesurfer.getWrapper().scrollWidth/e:this.wavesurfer.options.minPxPerSec;const i=this.getTouchCenterX(t)-this.container.getBoundingClientRect().left,s=this.wavesurfer.getScroll();this.pointerTime=(s+i)/this.initialZoom,this.oldX=i}},this.onTouchMove=t=>{if(!this.isPinching||2!==t.touches.length||!this.wavesurfer||!this.container)return;t.preventDefault();const e=this.getTouchDistance(t)/this.initialPinchDistance;let i=this.initialZoom*e;i=Math.min(i,this.options.maxZoom);const s=this.wavesurfer.getDuration(),n=this.container.clientWidth,o=n/s;i<o&&(i=o);const h=n/i*(this.oldX/n);i===o?(this.wavesurfer.zoom(o),this.container.scrollLeft=0):(this.wavesurfer.zoom(i),this.container.scrollLeft=(this.pointerTime-h)*i)},this.onTouchEnd=t=>{this.isPinching&&t.touches.length<2&&(this.isPinching=!1,this.initialPinchDistance=0,this.initialZoom=0)},this.options=Object.assign({},i,t)}static create(t){return new s(t)}onInit(){var t;this.wrapper=null===(t=this.wavesurfer)||void 0===t?void 0:t.getWrapper(),this.wrapper&&(this.container=this.wrapper.parentElement,this.container.addEventListener("wheel",this.onWheel),this.container.addEventListener("touchstart",this.onTouchStart,{passive:!1,capture:!0}),this.container.addEventListener("touchmove",this.onTouchMove,{passive:!1,capture:!0}),this.container.addEventListener("touchend",this.onTouchEnd,{passive:!1,capture:!0}),this.container.addEventListener("touchcancel",this.onTouchEnd,{passive:!1,capture:!0}),void 0===this.options.maxZoom&&(this.options.maxZoom=this.container.clientWidth),this.endZoom=this.options.maxZoom)}getTouchDistance(t){const e=t.touches[0],i=t.touches[1];return Math.sqrt(Math.pow(i.clientX-e.clientX,2)+Math.pow(i.clientY-e.clientY,2))}getTouchCenterX(t){const e=t.touches[0],i=t.touches[1];return(e.clientX+i.clientX)/2}destroy(){this.container&&(this.container.removeEventListener("wheel",this.onWheel),this.container.removeEventListener("touchstart",this.onTouchStart),this.container.removeEventListener("touchmove",this.onTouchMove),this.container.removeEventListener("touchend",this.onTouchEnd),this.container.removeEventListener("touchcancel",this.onTouchEnd)),super.destroy()}}return s}));
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import type { WaveSurferOptions } from './wavesurfer.js';
|
|
2
|
+
export type ChannelData = Array<Float32Array | number[]>;
|
|
3
|
+
export type BarSegment = {
|
|
4
|
+
x: number;
|
|
5
|
+
y: number;
|
|
6
|
+
width: number;
|
|
7
|
+
height: number;
|
|
8
|
+
};
|
|
9
|
+
export type LinePath = Array<{
|
|
10
|
+
x: number;
|
|
11
|
+
y: number;
|
|
12
|
+
}>;
|
|
13
|
+
export declare const DEFAULT_HEIGHT = 128;
|
|
14
|
+
export declare const MAX_CANVAS_WIDTH = 8000;
|
|
15
|
+
export declare const MAX_NODES = 10;
|
|
16
|
+
export declare function clampToUnit(value: number): number;
|
|
17
|
+
export declare function calculateBarRenderConfig({ width, height, length, options, pixelRatio, }: {
|
|
18
|
+
width: number;
|
|
19
|
+
height: number;
|
|
20
|
+
length: number;
|
|
21
|
+
options: WaveSurferOptions;
|
|
22
|
+
pixelRatio: number;
|
|
23
|
+
}): {
|
|
24
|
+
halfHeight: number;
|
|
25
|
+
barWidth: number;
|
|
26
|
+
barGap: number;
|
|
27
|
+
barRadius: number;
|
|
28
|
+
barIndexScale: number;
|
|
29
|
+
barSpacing: number;
|
|
30
|
+
};
|
|
31
|
+
export declare function calculateBarHeights({ maxTop, maxBottom, halfHeight, vScale, }: {
|
|
32
|
+
maxTop: number;
|
|
33
|
+
maxBottom: number;
|
|
34
|
+
halfHeight: number;
|
|
35
|
+
vScale: number;
|
|
36
|
+
}): {
|
|
37
|
+
topHeight: number;
|
|
38
|
+
totalHeight: number;
|
|
39
|
+
};
|
|
40
|
+
export declare function resolveBarYPosition({ barAlign, halfHeight, topHeight, totalHeight, canvasHeight, }: {
|
|
41
|
+
barAlign: WaveSurferOptions['barAlign'];
|
|
42
|
+
halfHeight: number;
|
|
43
|
+
topHeight: number;
|
|
44
|
+
totalHeight: number;
|
|
45
|
+
canvasHeight: number;
|
|
46
|
+
}): number;
|
|
47
|
+
export declare function calculateBarSegments({ channelData, barIndexScale, barSpacing, barWidth, halfHeight, vScale, canvasHeight, barAlign, }: {
|
|
48
|
+
channelData: ChannelData;
|
|
49
|
+
barIndexScale: number;
|
|
50
|
+
barSpacing: number;
|
|
51
|
+
barWidth: number;
|
|
52
|
+
halfHeight: number;
|
|
53
|
+
vScale: number;
|
|
54
|
+
canvasHeight: number;
|
|
55
|
+
barAlign: WaveSurferOptions['barAlign'];
|
|
56
|
+
}): BarSegment[];
|
|
57
|
+
export declare function getRelativePointerPosition(rect: DOMRect, clientX: number, clientY: number): [number, number];
|
|
58
|
+
export declare function resolveChannelHeight({ optionsHeight, optionsSplitChannels, parentHeight, numberOfChannels, defaultHeight, }: {
|
|
59
|
+
optionsHeight?: WaveSurferOptions['height'];
|
|
60
|
+
optionsSplitChannels?: WaveSurferOptions['splitChannels'];
|
|
61
|
+
parentHeight: number;
|
|
62
|
+
numberOfChannels: number;
|
|
63
|
+
defaultHeight?: number;
|
|
64
|
+
}): number;
|
|
65
|
+
export declare function getPixelRatio(devicePixelRatio?: number): number;
|
|
66
|
+
export declare function shouldRenderBars(options: WaveSurferOptions): boolean;
|
|
67
|
+
export declare function resolveColorValue(color: WaveSurferOptions['waveColor'], devicePixelRatio: number): string | CanvasGradient;
|
|
68
|
+
export declare function calculateWaveformLayout({ duration, minPxPerSec, parentWidth, fillParent, pixelRatio, }: {
|
|
69
|
+
duration: number;
|
|
70
|
+
minPxPerSec?: number;
|
|
71
|
+
parentWidth: number;
|
|
72
|
+
fillParent?: boolean;
|
|
73
|
+
pixelRatio: number;
|
|
74
|
+
}): {
|
|
75
|
+
scrollWidth: number;
|
|
76
|
+
isScrollable: boolean;
|
|
77
|
+
useParentWidth: boolean;
|
|
78
|
+
width: number;
|
|
79
|
+
};
|
|
80
|
+
export declare function clampWidthToBarGrid(width: number, options: WaveSurferOptions): number;
|
|
81
|
+
export declare function calculateSingleCanvasWidth({ clientWidth, totalWidth, options, }: {
|
|
82
|
+
clientWidth: number;
|
|
83
|
+
totalWidth: number;
|
|
84
|
+
options: WaveSurferOptions;
|
|
85
|
+
}): number;
|
|
86
|
+
export declare function sliceChannelData({ channelData, offset, clampedWidth, totalWidth, }: {
|
|
87
|
+
channelData: ChannelData;
|
|
88
|
+
offset: number;
|
|
89
|
+
clampedWidth: number;
|
|
90
|
+
totalWidth: number;
|
|
91
|
+
}): ChannelData;
|
|
92
|
+
export declare function shouldClearCanvases(currentNodeCount: number): boolean;
|
|
93
|
+
export declare function getLazyRenderRange({ scrollLeft, totalWidth, numCanvases, }: {
|
|
94
|
+
scrollLeft: number;
|
|
95
|
+
totalWidth: number;
|
|
96
|
+
numCanvases: number;
|
|
97
|
+
}): number[];
|
|
98
|
+
export declare function calculateVerticalScale({ channelData, barHeight, normalize, }: {
|
|
99
|
+
channelData: ChannelData;
|
|
100
|
+
barHeight?: WaveSurferOptions['barHeight'];
|
|
101
|
+
normalize?: WaveSurferOptions['normalize'];
|
|
102
|
+
}): number;
|
|
103
|
+
export declare function calculateLinePaths({ channelData, width, height, vScale, }: {
|
|
104
|
+
channelData: ChannelData;
|
|
105
|
+
width: number;
|
|
106
|
+
height: number;
|
|
107
|
+
vScale: number;
|
|
108
|
+
}): LinePath[];
|
|
109
|
+
export declare function calculateScrollPercentages({ scrollLeft, clientWidth, scrollWidth, }: {
|
|
110
|
+
scrollLeft: number;
|
|
111
|
+
clientWidth: number;
|
|
112
|
+
scrollWidth: number;
|
|
113
|
+
}): {
|
|
114
|
+
startX: number;
|
|
115
|
+
endX: number;
|
|
116
|
+
};
|
|
117
|
+
export declare function roundToHalfAwayFromZero(value: number): number;
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
export const DEFAULT_HEIGHT = 128;
|
|
2
|
+
export const MAX_CANVAS_WIDTH = 8000;
|
|
3
|
+
export const MAX_NODES = 10;
|
|
4
|
+
export function clampToUnit(value) {
|
|
5
|
+
if (value < 0)
|
|
6
|
+
return 0;
|
|
7
|
+
if (value > 1)
|
|
8
|
+
return 1;
|
|
9
|
+
return value;
|
|
10
|
+
}
|
|
11
|
+
export function calculateBarRenderConfig({ width, height, length, options, pixelRatio, }) {
|
|
12
|
+
const halfHeight = height / 2;
|
|
13
|
+
const barWidth = options.barWidth ? options.barWidth * pixelRatio : 1;
|
|
14
|
+
const barGap = options.barGap ? options.barGap * pixelRatio : options.barWidth ? barWidth / 2 : 0;
|
|
15
|
+
const barRadius = options.barRadius || 0;
|
|
16
|
+
const spacing = barWidth + barGap || 1;
|
|
17
|
+
const barIndexScale = length > 0 ? width / spacing / length : 0;
|
|
18
|
+
return {
|
|
19
|
+
halfHeight,
|
|
20
|
+
barWidth,
|
|
21
|
+
barGap,
|
|
22
|
+
barRadius,
|
|
23
|
+
barIndexScale,
|
|
24
|
+
barSpacing: spacing,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
export function calculateBarHeights({ maxTop, maxBottom, halfHeight, vScale, }) {
|
|
28
|
+
const topHeight = Math.round(maxTop * halfHeight * vScale);
|
|
29
|
+
const bottomHeight = Math.round(maxBottom * halfHeight * vScale);
|
|
30
|
+
const totalHeight = topHeight + bottomHeight || 1;
|
|
31
|
+
return { topHeight, totalHeight };
|
|
32
|
+
}
|
|
33
|
+
export function resolveBarYPosition({ barAlign, halfHeight, topHeight, totalHeight, canvasHeight, }) {
|
|
34
|
+
if (barAlign === 'top')
|
|
35
|
+
return 0;
|
|
36
|
+
if (barAlign === 'bottom')
|
|
37
|
+
return canvasHeight - totalHeight;
|
|
38
|
+
return halfHeight - topHeight;
|
|
39
|
+
}
|
|
40
|
+
export function calculateBarSegments({ channelData, barIndexScale, barSpacing, barWidth, halfHeight, vScale, canvasHeight, barAlign, }) {
|
|
41
|
+
const topChannel = channelData[0] || [];
|
|
42
|
+
const bottomChannel = channelData[1] || topChannel;
|
|
43
|
+
const length = topChannel.length;
|
|
44
|
+
const segments = [];
|
|
45
|
+
let prevX = 0;
|
|
46
|
+
let maxTop = 0;
|
|
47
|
+
let maxBottom = 0;
|
|
48
|
+
for (let i = 0; i <= length; i++) {
|
|
49
|
+
const x = Math.round(i * barIndexScale);
|
|
50
|
+
if (x > prevX) {
|
|
51
|
+
const { topHeight, totalHeight } = calculateBarHeights({
|
|
52
|
+
maxTop,
|
|
53
|
+
maxBottom,
|
|
54
|
+
halfHeight,
|
|
55
|
+
vScale,
|
|
56
|
+
});
|
|
57
|
+
const y = resolveBarYPosition({
|
|
58
|
+
barAlign,
|
|
59
|
+
halfHeight,
|
|
60
|
+
topHeight,
|
|
61
|
+
totalHeight,
|
|
62
|
+
canvasHeight,
|
|
63
|
+
});
|
|
64
|
+
segments.push({
|
|
65
|
+
x: prevX * barSpacing,
|
|
66
|
+
y,
|
|
67
|
+
width: barWidth,
|
|
68
|
+
height: totalHeight,
|
|
69
|
+
});
|
|
70
|
+
prevX = x;
|
|
71
|
+
maxTop = 0;
|
|
72
|
+
maxBottom = 0;
|
|
73
|
+
}
|
|
74
|
+
const magnitudeTop = Math.abs(topChannel[i] || 0);
|
|
75
|
+
const magnitudeBottom = Math.abs(bottomChannel[i] || 0);
|
|
76
|
+
if (magnitudeTop > maxTop)
|
|
77
|
+
maxTop = magnitudeTop;
|
|
78
|
+
if (magnitudeBottom > maxBottom)
|
|
79
|
+
maxBottom = magnitudeBottom;
|
|
80
|
+
}
|
|
81
|
+
return segments;
|
|
82
|
+
}
|
|
83
|
+
export function getRelativePointerPosition(rect, clientX, clientY) {
|
|
84
|
+
const x = clientX - rect.left;
|
|
85
|
+
const y = clientY - rect.top;
|
|
86
|
+
const relativeX = x / rect.width;
|
|
87
|
+
const relativeY = y / rect.height;
|
|
88
|
+
return [relativeX, relativeY];
|
|
89
|
+
}
|
|
90
|
+
export function resolveChannelHeight({ optionsHeight, optionsSplitChannels, parentHeight, numberOfChannels, defaultHeight = DEFAULT_HEIGHT, }) {
|
|
91
|
+
if (optionsHeight == null)
|
|
92
|
+
return defaultHeight;
|
|
93
|
+
const numericHeight = Number(optionsHeight);
|
|
94
|
+
if (!isNaN(numericHeight))
|
|
95
|
+
return numericHeight;
|
|
96
|
+
if (optionsHeight === 'auto') {
|
|
97
|
+
const height = parentHeight || defaultHeight;
|
|
98
|
+
if (optionsSplitChannels === null || optionsSplitChannels === void 0 ? void 0 : optionsSplitChannels.every((channel) => !channel.overlay)) {
|
|
99
|
+
return height / numberOfChannels;
|
|
100
|
+
}
|
|
101
|
+
return height;
|
|
102
|
+
}
|
|
103
|
+
return defaultHeight;
|
|
104
|
+
}
|
|
105
|
+
export function getPixelRatio(devicePixelRatio) {
|
|
106
|
+
return Math.max(1, devicePixelRatio || 1);
|
|
107
|
+
}
|
|
108
|
+
export function shouldRenderBars(options) {
|
|
109
|
+
return Boolean(options.barWidth || options.barGap || options.barAlign);
|
|
110
|
+
}
|
|
111
|
+
export function resolveColorValue(color, devicePixelRatio) {
|
|
112
|
+
if (!Array.isArray(color))
|
|
113
|
+
return color || '';
|
|
114
|
+
if (color.length === 0)
|
|
115
|
+
return '#999';
|
|
116
|
+
if (color.length < 2)
|
|
117
|
+
return color[0] || '';
|
|
118
|
+
const canvasElement = document.createElement('canvas');
|
|
119
|
+
const ctx = canvasElement.getContext('2d');
|
|
120
|
+
const gradientHeight = canvasElement.height * devicePixelRatio;
|
|
121
|
+
const gradient = ctx.createLinearGradient(0, 0, 0, gradientHeight || devicePixelRatio);
|
|
122
|
+
const colorStopPercentage = 1 / (color.length - 1);
|
|
123
|
+
color.forEach((value, index) => {
|
|
124
|
+
gradient.addColorStop(index * colorStopPercentage, value);
|
|
125
|
+
});
|
|
126
|
+
return gradient;
|
|
127
|
+
}
|
|
128
|
+
export function calculateWaveformLayout({ duration, minPxPerSec = 0, parentWidth, fillParent, pixelRatio, }) {
|
|
129
|
+
const scrollWidth = Math.ceil(duration * minPxPerSec);
|
|
130
|
+
const isScrollable = scrollWidth > parentWidth;
|
|
131
|
+
const useParentWidth = Boolean(fillParent && !isScrollable);
|
|
132
|
+
const width = (useParentWidth ? parentWidth : scrollWidth) * pixelRatio;
|
|
133
|
+
return {
|
|
134
|
+
scrollWidth,
|
|
135
|
+
isScrollable,
|
|
136
|
+
useParentWidth,
|
|
137
|
+
width,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
export function clampWidthToBarGrid(width, options) {
|
|
141
|
+
if (!shouldRenderBars(options))
|
|
142
|
+
return width;
|
|
143
|
+
const barWidth = options.barWidth || 0.5;
|
|
144
|
+
const barGap = options.barGap || barWidth / 2;
|
|
145
|
+
const totalBarWidth = barWidth + barGap;
|
|
146
|
+
if (totalBarWidth === 0)
|
|
147
|
+
return width;
|
|
148
|
+
return Math.floor(width / totalBarWidth) * totalBarWidth;
|
|
149
|
+
}
|
|
150
|
+
export function calculateSingleCanvasWidth({ clientWidth, totalWidth, options, }) {
|
|
151
|
+
const baseWidth = Math.min(MAX_CANVAS_WIDTH, clientWidth, totalWidth);
|
|
152
|
+
return clampWidthToBarGrid(baseWidth, options);
|
|
153
|
+
}
|
|
154
|
+
export function sliceChannelData({ channelData, offset, clampedWidth, totalWidth, }) {
|
|
155
|
+
return channelData.map((channel) => {
|
|
156
|
+
const start = Math.floor((offset / totalWidth) * channel.length);
|
|
157
|
+
const end = Math.floor(((offset + clampedWidth) / totalWidth) * channel.length);
|
|
158
|
+
return channel.slice(start, end);
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
export function shouldClearCanvases(currentNodeCount) {
|
|
162
|
+
return currentNodeCount > MAX_NODES;
|
|
163
|
+
}
|
|
164
|
+
export function getLazyRenderRange({ scrollLeft, totalWidth, numCanvases, }) {
|
|
165
|
+
if (totalWidth === 0)
|
|
166
|
+
return [0];
|
|
167
|
+
const viewPosition = scrollLeft / totalWidth;
|
|
168
|
+
const startCanvas = Math.floor(viewPosition * numCanvases);
|
|
169
|
+
return [startCanvas - 1, startCanvas, startCanvas + 1];
|
|
170
|
+
}
|
|
171
|
+
export function calculateVerticalScale({ channelData, barHeight, normalize, }) {
|
|
172
|
+
var _a;
|
|
173
|
+
const baseScale = barHeight || 1;
|
|
174
|
+
if (!normalize)
|
|
175
|
+
return baseScale;
|
|
176
|
+
const firstChannel = channelData[0];
|
|
177
|
+
if (!firstChannel || firstChannel.length === 0)
|
|
178
|
+
return baseScale;
|
|
179
|
+
let max = 0;
|
|
180
|
+
for (let i = 0; i < firstChannel.length; i++) {
|
|
181
|
+
const value = (_a = firstChannel[i]) !== null && _a !== void 0 ? _a : 0;
|
|
182
|
+
const magnitude = Math.abs(value);
|
|
183
|
+
if (magnitude > max)
|
|
184
|
+
max = magnitude;
|
|
185
|
+
}
|
|
186
|
+
if (!max)
|
|
187
|
+
return baseScale;
|
|
188
|
+
return baseScale / max;
|
|
189
|
+
}
|
|
190
|
+
export function calculateLinePaths({ channelData, width, height, vScale, }) {
|
|
191
|
+
const halfHeight = height / 2;
|
|
192
|
+
const primaryChannel = channelData[0] || [];
|
|
193
|
+
const secondaryChannel = channelData[1] || primaryChannel;
|
|
194
|
+
const channels = [primaryChannel, secondaryChannel];
|
|
195
|
+
return channels.map((channel, index) => {
|
|
196
|
+
const length = channel.length;
|
|
197
|
+
const hScale = length ? width / length : 0;
|
|
198
|
+
const baseY = halfHeight;
|
|
199
|
+
const direction = index === 0 ? -1 : 1;
|
|
200
|
+
const path = [{ x: 0, y: baseY }];
|
|
201
|
+
let prevX = 0;
|
|
202
|
+
let max = 0;
|
|
203
|
+
for (let i = 0; i <= length; i++) {
|
|
204
|
+
const x = Math.round(i * hScale);
|
|
205
|
+
if (x > prevX) {
|
|
206
|
+
const heightDelta = Math.round(max * halfHeight * vScale) || 1;
|
|
207
|
+
const y = baseY + heightDelta * direction;
|
|
208
|
+
path.push({ x: prevX, y });
|
|
209
|
+
prevX = x;
|
|
210
|
+
max = 0;
|
|
211
|
+
}
|
|
212
|
+
const value = Math.abs(channel[i] || 0);
|
|
213
|
+
if (value > max)
|
|
214
|
+
max = value;
|
|
215
|
+
}
|
|
216
|
+
path.push({ x: prevX, y: baseY });
|
|
217
|
+
return path;
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
export function calculateScrollPercentages({ scrollLeft, clientWidth, scrollWidth, }) {
|
|
221
|
+
if (scrollWidth === 0) {
|
|
222
|
+
return { startX: 0, endX: 0 };
|
|
223
|
+
}
|
|
224
|
+
const startX = scrollLeft / scrollWidth;
|
|
225
|
+
const endX = (scrollLeft + clientWidth) / scrollWidth;
|
|
226
|
+
return { startX, endX };
|
|
227
|
+
}
|
|
228
|
+
export function roundToHalfAwayFromZero(value) {
|
|
229
|
+
const scaled = value * 2;
|
|
230
|
+
const rounded = scaled < 0 ? Math.floor(scaled) : Math.ceil(scaled);
|
|
231
|
+
return rounded / 2;
|
|
232
|
+
}
|
package/dist/renderer.d.ts
CHANGED
|
@@ -9,10 +9,9 @@ type RendererEvents = {
|
|
|
9
9
|
scroll: [relativeStart: number, relativeEnd: number, scrollLeft: number, scrollRight: number];
|
|
10
10
|
render: [];
|
|
11
11
|
rendered: [];
|
|
12
|
+
resize: [];
|
|
12
13
|
};
|
|
13
14
|
declare class Renderer extends EventEmitter<RendererEvents> {
|
|
14
|
-
private static MAX_CANVAS_WIDTH;
|
|
15
|
-
private static MAX_NODES;
|
|
16
15
|
private options;
|
|
17
16
|
private parent;
|
|
18
17
|
private container;
|
|
@@ -29,12 +28,12 @@ declare class Renderer extends EventEmitter<RendererEvents> {
|
|
|
29
28
|
private isDragging;
|
|
30
29
|
private subscriptions;
|
|
31
30
|
private unsubscribeOnScroll;
|
|
31
|
+
private dragUnsubscribe;
|
|
32
32
|
constructor(options: WaveSurferOptions, audioElement?: HTMLElement);
|
|
33
33
|
private parentFromOptionsContainer;
|
|
34
34
|
private initEvents;
|
|
35
35
|
private onContainerResize;
|
|
36
36
|
private initDrag;
|
|
37
|
-
private getHeight;
|
|
38
37
|
private initHtml;
|
|
39
38
|
/** Wavesurfer itself calls this method. Do not call it manually. */
|
|
40
39
|
setOptions(options: WaveSurferOptions): void;
|
|
@@ -45,6 +44,7 @@ declare class Renderer extends EventEmitter<RendererEvents> {
|
|
|
45
44
|
setScrollPercentage(percent: number): void;
|
|
46
45
|
destroy(): void;
|
|
47
46
|
private createDelay;
|
|
47
|
+
private getHeight;
|
|
48
48
|
private convertColorValues;
|
|
49
49
|
private getPixelRatio;
|
|
50
50
|
private renderBarWaveform;
|