@micromag/element-audio 0.4.71 → 0.4.77
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/es/index.js +242 -311
- package/package.json +10 -8
package/es/index.js
CHANGED
|
@@ -1,13 +1,8 @@
|
|
|
1
|
-
import _objectSpread from '@babel/runtime/helpers/objectSpread2';
|
|
2
|
-
import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProperties';
|
|
3
|
-
import _defineProperty from '@babel/runtime/helpers/defineProperty';
|
|
4
|
-
import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
|
|
5
1
|
import classNames from 'classnames';
|
|
6
2
|
import isFunction from 'lodash/isFunction';
|
|
7
3
|
import isNumber from 'lodash/isNumber';
|
|
8
4
|
import { useState, useMemo, useCallback, useRef, useEffect } from 'react';
|
|
9
5
|
import { useDimensionObserver, useMediaCurrentTime, useMediaReady, useMediaDuration, useMediaLoad, useProgressSteps, useDevicePixelRatio } from '@micromag/core/hooks';
|
|
10
|
-
import _toConsumableArray from '@babel/runtime/helpers/toConsumableArray';
|
|
11
6
|
import { useGesture } from '@use-gesture/react';
|
|
12
7
|
import { useIntl } from 'react-intl';
|
|
13
8
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
@@ -17,48 +12,38 @@ import { getContrastingColor } from '@micromag/core/utils';
|
|
|
17
12
|
|
|
18
13
|
var styles$2 = {"container":"micromag-element-audio-audio-bars-container","seekButton":"micromag-element-audio-audio-bars-seekButton"};
|
|
19
14
|
|
|
20
|
-
function AudioBars(
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
var current = progress * elWidth;
|
|
43
|
-
var _useState = useState(null),
|
|
44
|
-
_useState2 = _slicedToArray(_useState, 2),
|
|
45
|
-
currentSeek = _useState2[0],
|
|
46
|
-
setCurrentSeek = _useState2[1];
|
|
47
|
-
var items = useMemo(function () {
|
|
48
|
-
var count = Math.floor(elWidth / barSize);
|
|
49
|
-
return _toConsumableArray(Array(count).keys()).map(function () {
|
|
50
|
-
return Math.floor(Math.random() * 100);
|
|
51
|
-
});
|
|
15
|
+
function AudioBars({
|
|
16
|
+
progress = 0,
|
|
17
|
+
playing = false,
|
|
18
|
+
duration = 0,
|
|
19
|
+
seek = null,
|
|
20
|
+
play = null,
|
|
21
|
+
className = null
|
|
22
|
+
}) {
|
|
23
|
+
const intl = useIntl();
|
|
24
|
+
const {
|
|
25
|
+
ref: elRef,
|
|
26
|
+
width: elWidth = null,
|
|
27
|
+
height: elHeight
|
|
28
|
+
} = useDimensionObserver();
|
|
29
|
+
const barWidth = 1;
|
|
30
|
+
const barGap = 1;
|
|
31
|
+
const barSize = barWidth + barGap;
|
|
32
|
+
const current = progress * elWidth;
|
|
33
|
+
const [currentSeek, setCurrentSeek] = useState(null);
|
|
34
|
+
const items = useMemo(() => {
|
|
35
|
+
const count = Math.floor(elWidth / barSize);
|
|
36
|
+
return [...Array(count).keys()].map(() => Math.floor(Math.random() * 100));
|
|
52
37
|
}, [elWidth, barSize]);
|
|
53
|
-
|
|
54
|
-
var x = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
|
|
38
|
+
const seekFromX = useCallback((x = null) => {
|
|
55
39
|
if (x === null) {
|
|
56
40
|
return;
|
|
57
41
|
}
|
|
58
|
-
|
|
59
|
-
elX
|
|
60
|
-
width
|
|
61
|
-
|
|
42
|
+
const {
|
|
43
|
+
left: elX,
|
|
44
|
+
width
|
|
45
|
+
} = elRef.current.getBoundingClientRect();
|
|
46
|
+
const distance = Math.max(0, Math.min(1, (x - elX) / width));
|
|
62
47
|
if (seek !== null && duration !== null) {
|
|
63
48
|
seek(parseFloat(distance * duration, 10));
|
|
64
49
|
}
|
|
@@ -66,45 +51,46 @@ function AudioBars(_ref) {
|
|
|
66
51
|
play();
|
|
67
52
|
}
|
|
68
53
|
}, [elRef.current, elWidth, duration, playing, seek, play]);
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
width
|
|
73
|
-
|
|
74
|
-
|
|
54
|
+
const seekTemporary = useCallback(x_0 => {
|
|
55
|
+
const {
|
|
56
|
+
left: elX_0,
|
|
57
|
+
width: width_0
|
|
58
|
+
} = elRef.current.getBoundingClientRect();
|
|
59
|
+
const distance_0 = Math.max(0, Math.min(1, (x_0 - elX_0) / width_0));
|
|
60
|
+
setCurrentSeek(distance_0 * elWidth);
|
|
75
61
|
}, [elRef.current, elWidth, setCurrentSeek]);
|
|
76
|
-
|
|
62
|
+
const onClick = useCallback(e => {
|
|
77
63
|
if (e) {
|
|
78
64
|
seekFromX(e.clientX || null);
|
|
79
65
|
setCurrentSeek(null);
|
|
80
66
|
}
|
|
81
67
|
}, [seekFromX, setCurrentSeek]);
|
|
82
|
-
|
|
83
|
-
onDrag:
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
68
|
+
const bind = useGesture({
|
|
69
|
+
onDrag: ({
|
|
70
|
+
xy: [x_1],
|
|
71
|
+
elapsedTime,
|
|
72
|
+
active
|
|
73
|
+
}) => {
|
|
88
74
|
if (!active && elapsedTime > 300) {
|
|
89
75
|
return;
|
|
90
76
|
}
|
|
91
|
-
seekTemporary(
|
|
77
|
+
seekTemporary(x_1);
|
|
92
78
|
},
|
|
93
|
-
onDragStart:
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
if (!
|
|
79
|
+
onDragStart: ({
|
|
80
|
+
xy: [x_2],
|
|
81
|
+
elapsedTime: elapsedTime_0,
|
|
82
|
+
active: active_0
|
|
83
|
+
}) => {
|
|
84
|
+
if (!active_0 && elapsedTime_0 > 300) {
|
|
99
85
|
return;
|
|
100
86
|
}
|
|
101
|
-
seekTemporary(
|
|
87
|
+
seekTemporary(x_2);
|
|
102
88
|
},
|
|
103
|
-
onDragEnd:
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
seekFromX(
|
|
107
|
-
setTimeout(
|
|
89
|
+
onDragEnd: ({
|
|
90
|
+
xy: [x_3]
|
|
91
|
+
}) => {
|
|
92
|
+
seekFromX(x_3);
|
|
93
|
+
setTimeout(() => {
|
|
108
94
|
setCurrentSeek(null);
|
|
109
95
|
}, 1000);
|
|
110
96
|
}
|
|
@@ -123,130 +109,91 @@ function AudioBars(_ref) {
|
|
|
123
109
|
xmlnsXlink: "http://www.w3.org/1999/xlink",
|
|
124
110
|
x: "0",
|
|
125
111
|
y: "0",
|
|
126
|
-
width:
|
|
127
|
-
height:
|
|
128
|
-
viewBox:
|
|
112
|
+
width: `${elWidth}px`,
|
|
113
|
+
height: `${elHeight}px`,
|
|
114
|
+
viewBox: `0 0 ${elWidth} ${elHeight}`,
|
|
129
115
|
className: className,
|
|
130
116
|
xmlSpace: "preserve",
|
|
131
|
-
children: items.map(
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
}), /*#__PURE__*/jsx("button", _objectSpread(_objectSpread({}, bind()), {}, {
|
|
117
|
+
children: items.map((size, i) => /*#__PURE__*/jsx("rect", {
|
|
118
|
+
width: barWidth,
|
|
119
|
+
height: size,
|
|
120
|
+
x: i * barSize,
|
|
121
|
+
y: elHeight / 2 - size / 2,
|
|
122
|
+
fill: (currentSeek || current) > i * barSize ? 'white' : 'gray',
|
|
123
|
+
stroke: "black",
|
|
124
|
+
strokeWidth: "0px",
|
|
125
|
+
strokeLinejoin: "round",
|
|
126
|
+
strokeLinecap: "round"
|
|
127
|
+
}, `bar-${i + 1}`))
|
|
128
|
+
}), /*#__PURE__*/jsx("button", {
|
|
129
|
+
...bind(),
|
|
145
130
|
onClick: onClick,
|
|
146
131
|
type: "button",
|
|
147
132
|
className: styles$2.seekButton,
|
|
148
133
|
title: intl.formatMessage({
|
|
149
134
|
id: "G1Gyjn",
|
|
150
|
-
defaultMessage:
|
|
151
|
-
"type": 0,
|
|
152
|
-
"value": "Seek"
|
|
153
|
-
}]
|
|
135
|
+
defaultMessage: "Seek"
|
|
154
136
|
}),
|
|
155
137
|
"aria-label": intl.formatMessage({
|
|
156
138
|
id: "G1Gyjn",
|
|
157
|
-
defaultMessage:
|
|
158
|
-
"type": 0,
|
|
159
|
-
"value": "Seek"
|
|
160
|
-
}]
|
|
139
|
+
defaultMessage: "Seek"
|
|
161
140
|
})
|
|
162
|
-
})
|
|
141
|
+
})]
|
|
163
142
|
});
|
|
164
143
|
}
|
|
165
144
|
|
|
166
145
|
var styles$1 = {"container":"micromag-element-audio-container","wave":"micromag-element-audio-wave","withAutoHeight":"micromag-element-audio-withAutoHeight"};
|
|
167
146
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
onReady = _ref$onReady === void 0 ? null : _ref$onReady,
|
|
200
|
-
_ref$onPlay = _ref.onPlay,
|
|
201
|
-
onPlay = _ref$onPlay === void 0 ? null : _ref$onPlay,
|
|
202
|
-
_ref$onPause = _ref.onPause,
|
|
203
|
-
onPause = _ref$onPause === void 0 ? null : _ref$onPause,
|
|
204
|
-
_ref$onEnded = _ref.onEnded,
|
|
205
|
-
onEnded = _ref$onEnded === void 0 ? null : _ref$onEnded,
|
|
206
|
-
_ref$onSeeked = _ref.onSeeked,
|
|
207
|
-
onSeeked = _ref$onSeeked === void 0 ? null : _ref$onSeeked,
|
|
208
|
-
_ref$onTimeUpdate = _ref.onTimeUpdate,
|
|
209
|
-
onTimeUpdate = _ref$onTimeUpdate === void 0 ? null : _ref$onTimeUpdate,
|
|
210
|
-
_ref$onProgressStep = _ref.onProgressStep,
|
|
211
|
-
onProgressStep = _ref$onProgressStep === void 0 ? null : _ref$onProgressStep,
|
|
212
|
-
_ref$onDurationChange = _ref.onDurationChange,
|
|
213
|
-
customOnDurationChange = _ref$onDurationChange === void 0 ? null : _ref$onDurationChange,
|
|
214
|
-
_ref$onVolumeChange = _ref.onVolumeChange,
|
|
215
|
-
customOnVolumeChange = _ref$onVolumeChange === void 0 ? null : _ref$onVolumeChange,
|
|
216
|
-
_ref$onPlayError = _ref.onPlayError,
|
|
217
|
-
onPlayError = _ref$onPlayError === void 0 ? null : _ref$onPlayError;
|
|
218
|
-
var _ref2 = media || {},
|
|
219
|
-
_ref2$url = _ref2.url,
|
|
220
|
-
url = _ref2$url === void 0 ? null : _ref2$url,
|
|
221
|
-
_ref2$files = _ref2.files,
|
|
222
|
-
files = _ref2$files === void 0 ? null : _ref2$files;
|
|
223
|
-
var srcUrl = useMemo(function () {
|
|
147
|
+
function Audio({
|
|
148
|
+
media = null,
|
|
149
|
+
mediaRef = null,
|
|
150
|
+
muted = false,
|
|
151
|
+
autoPlay = false,
|
|
152
|
+
paused = false,
|
|
153
|
+
loop = false,
|
|
154
|
+
preload = 'auto',
|
|
155
|
+
shouldLoad = true,
|
|
156
|
+
waveFake = false,
|
|
157
|
+
withWave = false,
|
|
158
|
+
autoWaveHeight = false,
|
|
159
|
+
updateInterval = 1000,
|
|
160
|
+
className = null,
|
|
161
|
+
withoutSeek = false,
|
|
162
|
+
onReady = null,
|
|
163
|
+
onPlay = null,
|
|
164
|
+
onPause = null,
|
|
165
|
+
onEnded = null,
|
|
166
|
+
onSeeked = null,
|
|
167
|
+
onTimeUpdate = null,
|
|
168
|
+
onProgressStep = null,
|
|
169
|
+
onDurationChange: customOnDurationChange = null,
|
|
170
|
+
onVolumeChange: customOnVolumeChange = null,
|
|
171
|
+
onPlayError = null
|
|
172
|
+
}) {
|
|
173
|
+
const {
|
|
174
|
+
url = null,
|
|
175
|
+
files = null
|
|
176
|
+
} = media || {};
|
|
177
|
+
const srcUrl = useMemo(() => {
|
|
224
178
|
if (files) {
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
var _ref6 = _slicedToArray(_ref5, 1),
|
|
228
|
-
key = _ref6[0];
|
|
229
|
-
return key === 'mp3';
|
|
230
|
-
}) || [],
|
|
231
|
-
_ref4 = _slicedToArray(_ref3, 2),
|
|
232
|
-
_ref4$ = _ref4[1],
|
|
233
|
-
mp3File = _ref4$ === void 0 ? null : _ref4$;
|
|
179
|
+
const filesAsEntries = Object.entries(files);
|
|
180
|
+
const [, mp3File = null] = filesAsEntries.find(([key]) => key === 'mp3') || [];
|
|
234
181
|
if (mp3File) {
|
|
235
182
|
return mp3File.url;
|
|
236
183
|
}
|
|
237
184
|
}
|
|
238
185
|
return url;
|
|
239
186
|
}, [files, url]);
|
|
240
|
-
|
|
241
|
-
|
|
187
|
+
const ref = useRef(null);
|
|
188
|
+
const currentTime = useMediaCurrentTime(ref.current, {
|
|
242
189
|
id: srcUrl,
|
|
243
190
|
disabled: paused || !withWave && onProgressStep === null,
|
|
244
|
-
updateInterval
|
|
191
|
+
updateInterval
|
|
245
192
|
});
|
|
246
|
-
|
|
193
|
+
const ready = useMediaReady(ref.current, {
|
|
247
194
|
id: srcUrl
|
|
248
195
|
});
|
|
249
|
-
|
|
196
|
+
const duration = useMediaDuration(ref.current, {
|
|
250
197
|
id: srcUrl
|
|
251
198
|
});
|
|
252
199
|
|
|
@@ -255,60 +202,66 @@ function Audio(_ref) {
|
|
|
255
202
|
// reduceBufferFactor,
|
|
256
203
|
// });
|
|
257
204
|
|
|
258
|
-
useMediaLoad(
|
|
259
|
-
preload
|
|
260
|
-
shouldLoad
|
|
205
|
+
useMediaLoad(ref.current, {
|
|
206
|
+
preload,
|
|
207
|
+
shouldLoad
|
|
261
208
|
});
|
|
262
|
-
|
|
263
|
-
useEffect(
|
|
209
|
+
const waveReady = waveFake || ready;
|
|
210
|
+
useEffect(() => {
|
|
264
211
|
if (duration > 0 && customOnDurationChange !== null) {
|
|
265
212
|
customOnDurationChange(duration);
|
|
266
213
|
}
|
|
267
214
|
}, [duration, customOnDurationChange]);
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
element =
|
|
215
|
+
const onVolumeChange = useCallback(() => {
|
|
216
|
+
const {
|
|
217
|
+
current: element = null
|
|
218
|
+
} = ref;
|
|
271
219
|
if (element === null) {
|
|
272
220
|
return;
|
|
273
221
|
}
|
|
274
222
|
if (customOnVolumeChange !== null) {
|
|
275
223
|
customOnVolumeChange(element.volume);
|
|
276
224
|
}
|
|
277
|
-
}, [
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
225
|
+
}, [ref.current, customOnVolumeChange]);
|
|
226
|
+
const onWavePlay = useCallback(() => {
|
|
227
|
+
const {
|
|
228
|
+
current: element_0 = null
|
|
229
|
+
} = ref;
|
|
230
|
+
if (element_0 === null) {
|
|
282
231
|
return;
|
|
283
232
|
}
|
|
284
|
-
|
|
285
|
-
}, [
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
233
|
+
element_0.play();
|
|
234
|
+
}, [ref.current]);
|
|
235
|
+
const onWaveSeek = useCallback(newTime => {
|
|
236
|
+
const {
|
|
237
|
+
current: element_1 = null
|
|
238
|
+
} = ref;
|
|
239
|
+
if (element_1 === null) {
|
|
290
240
|
return;
|
|
291
241
|
}
|
|
292
242
|
if (isNumber(newTime)) {
|
|
293
|
-
|
|
243
|
+
element_1.currentTime = newTime;
|
|
294
244
|
}
|
|
295
|
-
}, [
|
|
296
|
-
useEffect(
|
|
245
|
+
}, [ref.current]);
|
|
246
|
+
useEffect(() => {
|
|
297
247
|
if (waveReady && onReady !== null) {
|
|
298
248
|
onReady();
|
|
299
249
|
}
|
|
300
250
|
}, [waveReady, onReady]);
|
|
301
|
-
useEffect(
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
251
|
+
useEffect(() => {
|
|
252
|
+
const {
|
|
253
|
+
current: element_2 = null
|
|
254
|
+
} = ref;
|
|
255
|
+
if (element_2 === null) {
|
|
305
256
|
return;
|
|
306
257
|
}
|
|
307
|
-
|
|
258
|
+
const {
|
|
259
|
+
paused: isPaused
|
|
260
|
+
} = element_2;
|
|
308
261
|
if (paused && !isPaused) {
|
|
309
|
-
|
|
262
|
+
element_2.pause();
|
|
310
263
|
} else if (!paused && isPaused) {
|
|
311
|
-
|
|
264
|
+
element_2.play().catch(e => {
|
|
312
265
|
if (onPlayError !== null) {
|
|
313
266
|
onPlayError(e);
|
|
314
267
|
}
|
|
@@ -316,17 +269,17 @@ function Audio(_ref) {
|
|
|
316
269
|
}
|
|
317
270
|
}, [paused, media, onPlayError]);
|
|
318
271
|
useProgressSteps({
|
|
319
|
-
currentTime
|
|
320
|
-
duration
|
|
272
|
+
currentTime,
|
|
273
|
+
duration,
|
|
321
274
|
disabled: paused,
|
|
322
275
|
onStep: onProgressStep
|
|
323
276
|
});
|
|
324
|
-
|
|
277
|
+
const progress = currentTime !== null && duration > 0 ? currentTime / duration : 0;
|
|
325
278
|
return /*#__PURE__*/jsxs("div", {
|
|
326
279
|
className: classNames([styles$1.container, className]),
|
|
327
280
|
children: [/*#__PURE__*/jsx("audio", {
|
|
328
|
-
ref:
|
|
329
|
-
|
|
281
|
+
ref: newRef => {
|
|
282
|
+
ref.current = newRef;
|
|
330
283
|
if (mediaRef !== null && isFunction(mediaRef)) {
|
|
331
284
|
mediaRef(newRef);
|
|
332
285
|
} else if (mediaRef !== null) {
|
|
@@ -346,7 +299,9 @@ function Audio(_ref) {
|
|
|
346
299
|
onTimeUpdate: onTimeUpdate,
|
|
347
300
|
onVolumeChange: onVolumeChange
|
|
348
301
|
}, srcUrl), withWave ? /*#__PURE__*/jsx(AudioBars, {
|
|
349
|
-
className: classNames([styles$1.wave,
|
|
302
|
+
className: classNames([styles$1.wave, {
|
|
303
|
+
[styles$1.withAutoHeight]: autoWaveHeight
|
|
304
|
+
}]),
|
|
350
305
|
progress: progress
|
|
351
306
|
// {...waveProps}
|
|
352
307
|
,
|
|
@@ -357,82 +312,63 @@ function Audio(_ref) {
|
|
|
357
312
|
}) : null]
|
|
358
313
|
});
|
|
359
314
|
}
|
|
360
|
-
var Audio_default = (
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
315
|
+
var Audio_default = ({
|
|
316
|
+
ref,
|
|
317
|
+
...props
|
|
318
|
+
}) => /*#__PURE__*/jsx(Audio, {
|
|
319
|
+
mediaRef: ref,
|
|
320
|
+
...props
|
|
366
321
|
});
|
|
367
322
|
|
|
368
323
|
var styles = {"container":"micromag-element-audio-audio-wave-container","canvasBackground":"micromag-element-audio-audio-wave-canvasBackground","canvasProgress":"micromag-element-audio-audio-wave-canvasProgress"};
|
|
369
324
|
|
|
370
|
-
function AudioWave(
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
_ref$onSeek = _ref.onSeek,
|
|
392
|
-
onSeek = _ref$onSeek === void 0 ? null : _ref$onSeek,
|
|
393
|
-
_ref$onResume = _ref.onResume,
|
|
394
|
-
onResume = _ref$onResume === void 0 ? null : _ref$onResume,
|
|
395
|
-
_ref$onReady = _ref.onReady,
|
|
396
|
-
onReady = _ref$onReady === void 0 ? null : _ref$onReady;
|
|
397
|
-
var canvasBackgroundRef = useRef(null);
|
|
398
|
-
var canvasProgressRef = useRef(null);
|
|
399
|
-
var mainColor = useMemo(function () {
|
|
400
|
-
var _ref2 = backgroundColor || {},
|
|
401
|
-
_ref2$color = _ref2.color,
|
|
402
|
-
color = _ref2$color === void 0 ? 'white' : _ref2$color;
|
|
325
|
+
function AudioWave({
|
|
326
|
+
currentTime = null,
|
|
327
|
+
duration = null,
|
|
328
|
+
playing = false,
|
|
329
|
+
sampleWidth = 3,
|
|
330
|
+
sampleMargin = 1,
|
|
331
|
+
minSampleHeight = 2,
|
|
332
|
+
backgroundColor = 'white',
|
|
333
|
+
progressColor = null,
|
|
334
|
+
audioLevels = null,
|
|
335
|
+
className = null,
|
|
336
|
+
onSeek = null,
|
|
337
|
+
onResume = null,
|
|
338
|
+
onReady = null
|
|
339
|
+
}) {
|
|
340
|
+
const canvasBackgroundRef = useRef(null);
|
|
341
|
+
const canvasProgressRef = useRef(null);
|
|
342
|
+
const mainColor = useMemo(() => {
|
|
343
|
+
const {
|
|
344
|
+
color = 'white'
|
|
345
|
+
} = backgroundColor || {};
|
|
403
346
|
return color;
|
|
404
347
|
}, [backgroundColor]);
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
elWidth = _useDimensionObserver2 === void 0 ? null : _useDimensionObserver2,
|
|
412
|
-
elHeight = _useDimensionObserver.height;
|
|
348
|
+
const alternateColor = useMemo(() => getContrastingColor(backgroundColor, progressColor), [progressColor, backgroundColor]);
|
|
349
|
+
const {
|
|
350
|
+
ref: elRef,
|
|
351
|
+
width: elWidth = null,
|
|
352
|
+
height: elHeight
|
|
353
|
+
} = useDimensionObserver();
|
|
413
354
|
|
|
414
355
|
// Linear animation for progress bar
|
|
415
356
|
|
|
416
357
|
// In react-spring v10, useSpring(fn) without deps resets the spring on every render
|
|
417
358
|
// via a layout effect. Passing a SpringRef prevents this reset behavior.
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
}),
|
|
428
|
-
_useSpring2 = _slicedToArray(_useSpring, 2),
|
|
429
|
-
springProps = _useSpring2[0],
|
|
430
|
-
setSpringProps = _useSpring2[1];
|
|
431
|
-
useEffect(function () {
|
|
359
|
+
const springRef = useSpringRef();
|
|
360
|
+
const [springProps, setSpringProps] = useSpring(() => ({
|
|
361
|
+
ref: springRef,
|
|
362
|
+
x: 0,
|
|
363
|
+
config: {
|
|
364
|
+
duration: 0
|
|
365
|
+
}
|
|
366
|
+
}));
|
|
367
|
+
useEffect(() => {
|
|
432
368
|
if (currentTime === null || duration === null) {
|
|
433
369
|
return;
|
|
434
370
|
}
|
|
435
|
-
|
|
371
|
+
const progress = currentTime / duration;
|
|
436
372
|
setSpringProps.start({
|
|
437
373
|
reset: true,
|
|
438
374
|
immediate: !playing,
|
|
@@ -450,28 +386,26 @@ function AudioWave(_ref) {
|
|
|
450
386
|
|
|
451
387
|
// draw canvas
|
|
452
388
|
|
|
453
|
-
useEffect(
|
|
389
|
+
useEffect(() => {
|
|
454
390
|
if (audioLevels === null || audioLevels.length === 0 || elRef.current === null) {
|
|
455
391
|
return;
|
|
456
392
|
}
|
|
457
|
-
|
|
458
|
-
|
|
393
|
+
const sampleOuterWidth = sampleWidth + sampleMargin * 2;
|
|
394
|
+
const samplesCount = Math.floor(elWidth / sampleOuterWidth);
|
|
459
395
|
|
|
460
396
|
// const amplitudes = [];
|
|
461
397
|
|
|
462
398
|
// get samples
|
|
463
399
|
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
for (
|
|
400
|
+
const levelsBySamples = audioLevels.length / samplesCount;
|
|
401
|
+
const amplitudes = [...Array(samplesCount).keys()].reduce((newAmplitudes, index) => {
|
|
402
|
+
const levelStartIndex = index * levelsBySamples;
|
|
403
|
+
const levelEndIndex = levelStartIndex + levelsBySamples;
|
|
404
|
+
const newValues = [];
|
|
405
|
+
for (let i = Math.floor(levelStartIndex); i < Math.round(levelEndIndex); i += 1) {
|
|
470
406
|
newValues.push(audioLevels[i]);
|
|
471
407
|
}
|
|
472
|
-
return levelsBySamples >= 1 ? [
|
|
473
|
-
return total + value;
|
|
474
|
-
}, 0) / newValues.length]) : [].concat(_toConsumableArray(newAmplitudes), newValues);
|
|
408
|
+
return levelsBySamples >= 1 ? [...newAmplitudes, newValues.reduce((total, value) => total + value, 0) / newValues.length] : [...newAmplitudes, ...newValues];
|
|
475
409
|
}, []);
|
|
476
410
|
|
|
477
411
|
// for (let sampleI = 0; sampleI < samplesCount; sampleI += levelsBySamples) {
|
|
@@ -492,33 +426,31 @@ function AudioWave(_ref) {
|
|
|
492
426
|
// // }
|
|
493
427
|
// // }
|
|
494
428
|
// }
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
return (n - minAmplitude) / delta;
|
|
500
|
-
});
|
|
429
|
+
const minAmplitude = Math.min(...amplitudes);
|
|
430
|
+
const maxAmplitude = Math.max(...amplitudes);
|
|
431
|
+
const delta = maxAmplitude - minAmplitude;
|
|
432
|
+
const normalizedAmplitudes = amplitudes.map(n => (n - minAmplitude) / delta);
|
|
501
433
|
|
|
502
434
|
// draw samples
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
435
|
+
const canvasBg = canvasBackgroundRef.current;
|
|
436
|
+
const canvasProgress = canvasProgressRef.current;
|
|
437
|
+
const devicePixelRatio = useDevicePixelRatio();
|
|
438
|
+
const scale = devicePixelRatio;
|
|
507
439
|
canvasBg.width = canvasProgress.width = Math.floor(elWidth * scale);
|
|
508
440
|
canvasBg.height = canvasProgress.height = Math.floor(elHeight * scale);
|
|
509
|
-
|
|
510
|
-
|
|
441
|
+
const ctxBG = canvasBg.getContext('2d');
|
|
442
|
+
const ctxProgress = canvasProgress.getContext('2d');
|
|
511
443
|
ctxBG.scale(scale, scale);
|
|
512
444
|
ctxProgress.scale(scale, scale);
|
|
513
445
|
ctxBG.clearRect(0, 0, elWidth, elHeight);
|
|
514
446
|
ctxProgress.clearRect(0, 0, elWidth, elHeight);
|
|
515
447
|
ctxBG.fillStyle = mainColor;
|
|
516
448
|
ctxProgress.fillStyle = alternateColor;
|
|
517
|
-
|
|
518
|
-
normalizedAmplitudes.forEach(
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
449
|
+
const offsetLeft = (elWidth - samplesCount * sampleOuterWidth) / 2;
|
|
450
|
+
normalizedAmplitudes.forEach((amplitude, amplitudeI) => {
|
|
451
|
+
const sampleHeight = Math.max(minSampleHeight, amplitude * elHeight);
|
|
452
|
+
const sampleX = sampleOuterWidth * amplitudeI + offsetLeft + sampleMargin;
|
|
453
|
+
const sampleY = elHeight / 2 - sampleHeight / 2;
|
|
522
454
|
ctxBG.fillRect(Math.round(sampleX), Math.round(sampleY), sampleWidth, Math.round(sampleHeight));
|
|
523
455
|
ctxProgress.fillRect(Math.round(sampleX), Math.round(sampleY), sampleWidth, Math.round(sampleHeight));
|
|
524
456
|
});
|
|
@@ -528,28 +460,29 @@ function AudioWave(_ref) {
|
|
|
528
460
|
}, [audioLevels, sampleWidth, sampleMargin, minSampleHeight, elWidth, elHeight, mainColor, alternateColor, onReady]);
|
|
529
461
|
|
|
530
462
|
// User events
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
elX
|
|
534
|
-
width
|
|
535
|
-
|
|
463
|
+
const seekFromX = useCallback(x => {
|
|
464
|
+
const {
|
|
465
|
+
left: elX,
|
|
466
|
+
width
|
|
467
|
+
} = elRef.current.getBoundingClientRect();
|
|
468
|
+
const progress_0 = Math.max(0, Math.min(1, (x - elX) / width));
|
|
536
469
|
if (onSeek !== null && duration !== null) {
|
|
537
|
-
onSeek(
|
|
470
|
+
onSeek(progress_0 * duration);
|
|
538
471
|
}
|
|
539
472
|
if (!playing) {
|
|
540
473
|
onResume();
|
|
541
474
|
}
|
|
542
475
|
}, [duration, playing, onSeek, onResume]);
|
|
543
|
-
|
|
544
|
-
onDrag:
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
476
|
+
const bind = useGesture({
|
|
477
|
+
onDrag: ({
|
|
478
|
+
xy: [x_0],
|
|
479
|
+
elapsedTime,
|
|
480
|
+
active
|
|
481
|
+
}) => {
|
|
549
482
|
if (!active && elapsedTime > 300) {
|
|
550
483
|
return;
|
|
551
484
|
}
|
|
552
|
-
seekFromX(
|
|
485
|
+
seekFromX(x_0);
|
|
553
486
|
}
|
|
554
487
|
}, {
|
|
555
488
|
drag: {
|
|
@@ -557,10 +490,10 @@ function AudioWave(_ref) {
|
|
|
557
490
|
filterTaps: true
|
|
558
491
|
}
|
|
559
492
|
});
|
|
560
|
-
return /*#__PURE__*/jsxs("div",
|
|
493
|
+
return /*#__PURE__*/jsxs("div", {
|
|
561
494
|
className: classNames([styles.container, className]),
|
|
562
|
-
ref: elRef
|
|
563
|
-
|
|
495
|
+
ref: elRef,
|
|
496
|
+
...bind(),
|
|
564
497
|
children: [/*#__PURE__*/jsx("canvas", {
|
|
565
498
|
ref: canvasBackgroundRef,
|
|
566
499
|
className: styles.canvasBackground
|
|
@@ -568,12 +501,10 @@ function AudioWave(_ref) {
|
|
|
568
501
|
ref: canvasProgressRef,
|
|
569
502
|
className: styles.canvasProgress,
|
|
570
503
|
style: {
|
|
571
|
-
clipPath: springProps.x.to(
|
|
572
|
-
return "polygon(0 0, ".concat(x * 100, "% 0, ").concat(x * 100, "% 100%, 0 100%)");
|
|
573
|
-
})
|
|
504
|
+
clipPath: springProps.x.to(x_1 => `polygon(0 0, ${x_1 * 100}% 0, ${x_1 * 100}% 100%, 0 100%)`)
|
|
574
505
|
}
|
|
575
506
|
})]
|
|
576
|
-
})
|
|
507
|
+
});
|
|
577
508
|
}
|
|
578
509
|
|
|
579
510
|
export { AudioWave, Audio_default as default };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@micromag/element-audio",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.77",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "",
|
|
6
6
|
"keywords": [
|
|
@@ -33,9 +33,11 @@
|
|
|
33
33
|
"type": "module",
|
|
34
34
|
"module": "es/index.js",
|
|
35
35
|
"types": "es/index.d.ts",
|
|
36
|
+
"style": "./assets/css/styles.css",
|
|
36
37
|
"exports": {
|
|
37
38
|
".": {
|
|
38
39
|
"import": "./es/index.js",
|
|
40
|
+
"style": "./assets/css/styles.css",
|
|
39
41
|
"types": "./es/index.d.ts"
|
|
40
42
|
},
|
|
41
43
|
"./assets/css/styles": "./assets/css/styles.css",
|
|
@@ -52,17 +54,17 @@
|
|
|
52
54
|
"build": "../../scripts/prepare-package.sh --types"
|
|
53
55
|
},
|
|
54
56
|
"devDependencies": {
|
|
55
|
-
"react": "^
|
|
56
|
-
"react-dom": "^
|
|
57
|
+
"react": "^19.0.0",
|
|
58
|
+
"react-dom": "^19.0.0"
|
|
57
59
|
},
|
|
58
60
|
"peerDependencies": {
|
|
59
|
-
"react": "^
|
|
60
|
-
"react-dom": "^
|
|
61
|
+
"react": "^19.0.0",
|
|
62
|
+
"react-dom": "^19.0.0"
|
|
61
63
|
},
|
|
62
64
|
"dependencies": {
|
|
63
65
|
"@babel/runtime": "^7.28.6",
|
|
64
|
-
"@micromag/core": "^0.4.
|
|
65
|
-
"@micromag/element-closed-captions": "^0.4.
|
|
66
|
+
"@micromag/core": "^0.4.77",
|
|
67
|
+
"@micromag/element-closed-captions": "^0.4.77",
|
|
66
68
|
"@react-spring/core": "^10.0.3",
|
|
67
69
|
"@react-spring/web": "^10.0.3",
|
|
68
70
|
"@use-gesture/react": "^10.3.0",
|
|
@@ -75,5 +77,5 @@
|
|
|
75
77
|
"access": "public",
|
|
76
78
|
"registry": "https://registry.npmjs.org/"
|
|
77
79
|
},
|
|
78
|
-
"gitHead": "
|
|
80
|
+
"gitHead": "b55c2c748383d30c8ff0ca7594e499dbdc8d1c10"
|
|
79
81
|
}
|