@checksub_team/peaks_timeline 2.2.0-alpha.0 → 2.2.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/peaks.js +36 -26
- package/src/components/mode-layer.js +4 -0
- package/src/components/waveform-shape.js +25 -38
- package/src/view.js +27 -5
package/package.json
CHANGED
package/peaks.js
CHANGED
|
@@ -16326,6 +16326,9 @@ module.exports = function (SourceGroup, Source, Utils, Konva) {
|
|
|
16326
16326
|
}
|
|
16327
16327
|
};
|
|
16328
16328
|
ModeLayer.prototype._onKeyboardDelete = function () {
|
|
16329
|
+
if (!this._view.isFocusedByClick()) {
|
|
16330
|
+
return;
|
|
16331
|
+
}
|
|
16329
16332
|
const selectedElements = Object.values(this._selectedElements);
|
|
16330
16333
|
if (selectedElements.length === 1) {
|
|
16331
16334
|
var selectedElement = selectedElements[0];
|
|
@@ -19828,21 +19831,16 @@ module.exports = function (Utils, Konva) {
|
|
|
19828
19831
|
WaveformShape.prototype._sceneFunc = function (context) {
|
|
19829
19832
|
var width = this._view.getWidth();
|
|
19830
19833
|
var waveformData = this._layer.getLoadedData(this._url).data;
|
|
19831
|
-
var
|
|
19832
|
-
var startPixel = 0, startOffset = 0;
|
|
19834
|
+
var startPixel = 0, startOffset = 0, endPixel = width, targetSpeed = 1;
|
|
19833
19835
|
if (this._source) {
|
|
19834
|
-
|
|
19836
|
+
targetSpeed = this._source.targetSpeed || 1;
|
|
19837
|
+
startPixel = Math.floor((this._view.timeToPixels(this._source.mediaStartTime) + Math.max(this._view.getFrameOffset() - this._view.timeToPixels(this._source.startTime), 0)) * targetSpeed);
|
|
19835
19838
|
startOffset = this._view.timeToPixels(this._source.mediaStartTime);
|
|
19839
|
+
endPixel = Math.min(Math.ceil((this._view.timeToPixels(this._source.mediaEndTime) - Math.max(this._view.timeToPixels(this._source.endTime) - this._view.getFrameOffset() - this._view.getWidth(), 0)) * targetSpeed), waveformData.length);
|
|
19836
19840
|
}
|
|
19837
|
-
|
|
19838
|
-
if (this._source) {
|
|
19839
|
-
var effectiveMediaDuration = (this._source.endTime - this._source.startTime) * targetSpeed;
|
|
19840
|
-
var effectiveMediaEndTime = Math.min(this._source.mediaStartTime + effectiveMediaDuration, this._source.duration || Infinity);
|
|
19841
|
-
endPixel = Math.min(this._view.timeToPixels(effectiveMediaEndTime) - Math.max(this._view.timeToPixels(this._source.endTime) - this._view.getFrameOffset() - this._view.getWidth(), 0), waveformData.length);
|
|
19842
|
-
}
|
|
19843
|
-
this._drawWaveform(context, waveformData, startPixel, startOffset, endPixel, this._height);
|
|
19841
|
+
this._drawWaveform(context, waveformData, startPixel, startOffset, endPixel, targetSpeed, this._height);
|
|
19844
19842
|
};
|
|
19845
|
-
WaveformShape.prototype._drawWaveform = function (context, waveformData, startPixel, startOffset, endPixel, height) {
|
|
19843
|
+
WaveformShape.prototype._drawWaveform = function (context, waveformData, startPixel, startOffset, endPixel, targetSpeed, height) {
|
|
19846
19844
|
var channels = waveformData.channels;
|
|
19847
19845
|
var waveformTop = 0;
|
|
19848
19846
|
var waveformHeight = Math.floor(height / channels);
|
|
@@ -19850,24 +19848,21 @@ module.exports = function (Utils, Konva) {
|
|
|
19850
19848
|
if (i === channels - 1) {
|
|
19851
19849
|
waveformHeight = height - (channels - 1) * waveformHeight;
|
|
19852
19850
|
}
|
|
19853
|
-
this._drawChannel(context, waveformData.channel(i), startPixel, startOffset, endPixel, waveformTop, waveformHeight);
|
|
19851
|
+
this._drawChannel(context, waveformData.channel(i), startPixel, startOffset, endPixel, waveformTop, waveformHeight, targetSpeed);
|
|
19854
19852
|
waveformTop += waveformHeight;
|
|
19855
19853
|
}
|
|
19856
19854
|
};
|
|
19857
|
-
WaveformShape.prototype._drawChannel = function (context, channel, startPixel, startOffset, endPixel, top, height) {
|
|
19858
|
-
var x, val
|
|
19855
|
+
WaveformShape.prototype._drawChannel = function (context, channel, startPixel, startOffset, endPixel, top, height, targetSpeed) {
|
|
19856
|
+
var x, val;
|
|
19859
19857
|
var amplitudeScale = this._view.getAmplitudeScale();
|
|
19860
|
-
var targetSpeed = this._source && this._source.targetSpeed ? this._source.targetSpeed : 1;
|
|
19861
19858
|
context.beginPath();
|
|
19862
|
-
for (x =
|
|
19859
|
+
for (x = startPixel; x < endPixel; x++) {
|
|
19863
19860
|
val = channel.min_sample(x);
|
|
19864
|
-
|
|
19865
|
-
context.lineTo(displayX - startOffset + 0.5, top + scaleY(val, height, amplitudeScale) + 0.5);
|
|
19861
|
+
context.lineTo(x / targetSpeed - startOffset + 0.5, top + scaleY(val, height, amplitudeScale) + 0.5);
|
|
19866
19862
|
}
|
|
19867
|
-
for (x =
|
|
19863
|
+
for (x = endPixel - 1; x >= startPixel; x--) {
|
|
19868
19864
|
val = channel.max_sample(x);
|
|
19869
|
-
|
|
19870
|
-
context.lineTo(displayX - startOffset + 0.5, top + scaleY(val, height, amplitudeScale) + 0.5);
|
|
19865
|
+
context.lineTo(x / targetSpeed - startOffset + 0.5, top + scaleY(val, height, amplitudeScale) + 0.5);
|
|
19871
19866
|
}
|
|
19872
19867
|
context.closePath();
|
|
19873
19868
|
context.fillShape(this);
|
|
@@ -22401,7 +22396,8 @@ module.exports = function (MouseDragHandler, PlayheadLayer, SourcesLayer, ModeLa
|
|
|
22401
22396
|
self._timelineLength = 0;
|
|
22402
22397
|
self._timeToPixelsScale = self._options.initialZoomLevel;
|
|
22403
22398
|
self._timeToPixelsMinScale = self._options.minScale;
|
|
22404
|
-
self.
|
|
22399
|
+
self._focusedByHover = false;
|
|
22400
|
+
self._focusedByClick = false;
|
|
22405
22401
|
self._isClickable = true;
|
|
22406
22402
|
self._width = container.clientWidth;
|
|
22407
22403
|
self._height = container.clientHeight || self._options.height;
|
|
@@ -22477,13 +22473,13 @@ module.exports = function (MouseDragHandler, PlayheadLayer, SourcesLayer, ModeLa
|
|
|
22477
22473
|
}
|
|
22478
22474
|
});
|
|
22479
22475
|
this._stage.on('mouseover', function () {
|
|
22480
|
-
self.
|
|
22476
|
+
self._focusedByHover = true;
|
|
22481
22477
|
});
|
|
22482
22478
|
this._stage.on('mouseout', function () {
|
|
22483
|
-
self.
|
|
22479
|
+
self._focusedByHover = false;
|
|
22484
22480
|
});
|
|
22485
22481
|
this._stage.on('click', function (event) {
|
|
22486
|
-
self.
|
|
22482
|
+
self._focusedByClick = true;
|
|
22487
22483
|
if (!self._isClickable) {
|
|
22488
22484
|
return;
|
|
22489
22485
|
}
|
|
@@ -22539,11 +22535,18 @@ module.exports = function (MouseDragHandler, PlayheadLayer, SourcesLayer, ModeLa
|
|
|
22539
22535
|
window.addEventListener('mouseup', this._mouseUp.bind(this), false);
|
|
22540
22536
|
window.addEventListener('touchend', this._mouseUp.bind(this), false);
|
|
22541
22537
|
window.addEventListener('blur', this._mouseUp.bind(this), false);
|
|
22538
|
+
this._onWindowClick = this._onWindowClick.bind(this);
|
|
22539
|
+
window.addEventListener('click', this._onWindowClick, false);
|
|
22542
22540
|
}
|
|
22543
22541
|
View.prototype._mouseUp = function () {
|
|
22544
22542
|
this.clearScrollingInterval();
|
|
22545
22543
|
this._peaks.emit('handler.view.mouseup');
|
|
22546
22544
|
};
|
|
22545
|
+
View.prototype._onWindowClick = function (event) {
|
|
22546
|
+
if (!this._container.contains(event.target)) {
|
|
22547
|
+
this._focusedByClick = false;
|
|
22548
|
+
}
|
|
22549
|
+
};
|
|
22547
22550
|
View.prototype.setClickable = function (clickable) {
|
|
22548
22551
|
this._isClickable = clickable;
|
|
22549
22552
|
};
|
|
@@ -22628,8 +22631,14 @@ module.exports = function (MouseDragHandler, PlayheadLayer, SourcesLayer, ModeLa
|
|
|
22628
22631
|
View.prototype.isListening = function () {
|
|
22629
22632
|
return this._stage.listening();
|
|
22630
22633
|
};
|
|
22634
|
+
View.prototype.isFocusedByHover = function () {
|
|
22635
|
+
return this._focusedByHover;
|
|
22636
|
+
};
|
|
22637
|
+
View.prototype.isFocusedByClick = function () {
|
|
22638
|
+
return this._focusedByClick;
|
|
22639
|
+
};
|
|
22631
22640
|
View.prototype.isFocused = function () {
|
|
22632
|
-
return this.
|
|
22641
|
+
return this._focusedByHover || this._focusedByClick;
|
|
22633
22642
|
};
|
|
22634
22643
|
View.prototype.batchDrawSourcesLayer = function () {
|
|
22635
22644
|
this._sourcesLayer.batchDraw();
|
|
@@ -22929,6 +22938,7 @@ module.exports = function (MouseDragHandler, PlayheadLayer, SourcesLayer, ModeLa
|
|
|
22929
22938
|
this._peaks.off('handler.keyboard.shiftright', this._onKeyboardShiftRight);
|
|
22930
22939
|
this._peaks.off('handler.view.defaultmode', this._onDefaultMode);
|
|
22931
22940
|
this._peaks.off('handler.view.cutmode', this._onCutMode);
|
|
22941
|
+
window.removeEventListener('click', this._onWindowClick, false);
|
|
22932
22942
|
if (this._stage) {
|
|
22933
22943
|
this._stage.destroy();
|
|
22934
22944
|
this._stage = null;
|
|
@@ -234,6 +234,10 @@ define([
|
|
|
234
234
|
};
|
|
235
235
|
|
|
236
236
|
ModeLayer.prototype._onKeyboardDelete = function() {
|
|
237
|
+
if (!this._view.isFocusedByClick()) {
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
|
|
237
241
|
const selectedElements = Object.values(this._selectedElements);
|
|
238
242
|
|
|
239
243
|
// We allow deletion if there is ONLY 1 element selected
|
|
@@ -72,36 +72,29 @@ define(['../utils', 'konva'], function(Utils, Konva) {
|
|
|
72
72
|
WaveformShape.prototype._sceneFunc = function(context) {
|
|
73
73
|
var width = this._view.getWidth();
|
|
74
74
|
var waveformData = this._layer.getLoadedData(this._url).data;
|
|
75
|
-
var targetSpeed = this._source.targetSpeed || 1.0;
|
|
76
75
|
|
|
77
|
-
var startPixel = 0, startOffset = 0;
|
|
76
|
+
var startPixel = 0, startOffset = 0, endPixel = width, targetSpeed = 1.0;
|
|
78
77
|
|
|
79
78
|
if (this._source) {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
79
|
+
targetSpeed = this._source.targetSpeed || 1.0;
|
|
80
|
+
|
|
81
|
+
startPixel = Math.floor(
|
|
82
|
+
(this._view.timeToPixels(this._source.mediaStartTime) + Math.max(
|
|
83
|
+
this._view.getFrameOffset() - this._view.timeToPixels(this._source.startTime),
|
|
84
|
+
0
|
|
85
|
+
)) * targetSpeed
|
|
83
86
|
);
|
|
84
87
|
|
|
85
88
|
startOffset = this._view.timeToPixels(this._source.mediaStartTime);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
var endPixel = width;
|
|
89
|
-
|
|
90
|
-
if (this._source) {
|
|
91
|
-
// Calculate the effective media end time based on targetSpeed
|
|
92
|
-
// If speed is 2.0, we can fit 2x more audio in the same visual space
|
|
93
|
-
var effectiveMediaDuration = (this._source.endTime - this._source.startTime) * targetSpeed;
|
|
94
|
-
var effectiveMediaEndTime = Math.min(
|
|
95
|
-
this._source.mediaStartTime + effectiveMediaDuration,
|
|
96
|
-
this._source.duration || Infinity
|
|
97
|
-
);
|
|
98
89
|
|
|
99
90
|
endPixel = Math.min(
|
|
100
|
-
|
|
101
|
-
this._view.timeToPixels(this._source.
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
91
|
+
Math.ceil(
|
|
92
|
+
(this._view.timeToPixels(this._source.mediaEndTime) - Math.max(
|
|
93
|
+
this._view.timeToPixels(this._source.endTime)
|
|
94
|
+
- this._view.getFrameOffset()
|
|
95
|
+
- this._view.getWidth(),
|
|
96
|
+
0
|
|
97
|
+
)) * targetSpeed
|
|
105
98
|
),
|
|
106
99
|
waveformData.length
|
|
107
100
|
);
|
|
@@ -113,6 +106,7 @@ define(['../utils', 'konva'], function(Utils, Konva) {
|
|
|
113
106
|
startPixel,
|
|
114
107
|
startOffset,
|
|
115
108
|
endPixel,
|
|
109
|
+
targetSpeed,
|
|
116
110
|
this._height
|
|
117
111
|
);
|
|
118
112
|
};
|
|
@@ -133,7 +127,7 @@ define(['../utils', 'konva'], function(Utils, Konva) {
|
|
|
133
127
|
*/
|
|
134
128
|
|
|
135
129
|
WaveformShape.prototype._drawWaveform = function(context, waveformData,
|
|
136
|
-
startPixel, startOffset, endPixel, height) {
|
|
130
|
+
startPixel, startOffset, endPixel, targetSpeed, height) {
|
|
137
131
|
var channels = waveformData.channels;
|
|
138
132
|
|
|
139
133
|
var waveformTop = 0;
|
|
@@ -151,7 +145,8 @@ define(['../utils', 'konva'], function(Utils, Konva) {
|
|
|
151
145
|
startOffset,
|
|
152
146
|
endPixel,
|
|
153
147
|
waveformTop,
|
|
154
|
-
waveformHeight
|
|
148
|
+
waveformHeight,
|
|
149
|
+
targetSpeed
|
|
155
150
|
);
|
|
156
151
|
|
|
157
152
|
waveformTop += waveformHeight;
|
|
@@ -159,31 +154,23 @@ define(['../utils', 'konva'], function(Utils, Konva) {
|
|
|
159
154
|
};
|
|
160
155
|
|
|
161
156
|
WaveformShape.prototype._drawChannel = function(context, channel,
|
|
162
|
-
startPixel, startOffset, endPixel, top, height) {
|
|
163
|
-
var x, val
|
|
157
|
+
startPixel, startOffset, endPixel, top, height, targetSpeed) {
|
|
158
|
+
var x, val;
|
|
164
159
|
|
|
165
160
|
var amplitudeScale = this._view.getAmplitudeScale();
|
|
166
|
-
var targetSpeed = this._source && this._source.targetSpeed ? this._source.targetSpeed : 1.0;
|
|
167
161
|
|
|
168
162
|
context.beginPath();
|
|
169
163
|
|
|
170
|
-
for (x =
|
|
164
|
+
for (x = startPixel; x < endPixel; x++) {
|
|
171
165
|
val = channel.min_sample(x);
|
|
172
166
|
|
|
173
|
-
|
|
174
|
-
// targetSpeed = 2.0 means the waveform is drawn at half width (compressed)
|
|
175
|
-
// targetSpeed = 0.5 means the waveform is drawn at double width (expanded)
|
|
176
|
-
displayX = (x - startPixel) / targetSpeed + startPixel;
|
|
177
|
-
|
|
178
|
-
context.lineTo(displayX - startOffset + 0.5, top + scaleY(val, height, amplitudeScale) + 0.5);
|
|
167
|
+
context.lineTo(x / targetSpeed - startOffset + 0.5, top + scaleY(val, height, amplitudeScale) + 0.5);
|
|
179
168
|
}
|
|
180
169
|
|
|
181
|
-
for (x =
|
|
170
|
+
for (x = endPixel - 1; x >= startPixel; x--) {
|
|
182
171
|
val = channel.max_sample(x);
|
|
183
172
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
context.lineTo(displayX - startOffset + 0.5, top + scaleY(val, height, amplitudeScale) + 0.5);
|
|
173
|
+
context.lineTo(x / targetSpeed - startOffset + 0.5, top + scaleY(val, height, amplitudeScale) + 0.5);
|
|
187
174
|
}
|
|
188
175
|
|
|
189
176
|
context.closePath();
|
package/src/view.js
CHANGED
|
@@ -79,7 +79,8 @@ define([
|
|
|
79
79
|
self._timeToPixelsScale = self._options.initialZoomLevel;
|
|
80
80
|
self._timeToPixelsMinScale = self._options.minScale;
|
|
81
81
|
|
|
82
|
-
self.
|
|
82
|
+
self._focusedByHover = false;
|
|
83
|
+
self._focusedByClick = false; // Track if focus was set by click
|
|
83
84
|
self._isClickable = true;
|
|
84
85
|
|
|
85
86
|
self._width = container.clientWidth;
|
|
@@ -205,15 +206,15 @@ define([
|
|
|
205
206
|
});
|
|
206
207
|
|
|
207
208
|
this._stage.on('mouseover', function() {
|
|
208
|
-
self.
|
|
209
|
+
self._focusedByHover = true;
|
|
209
210
|
});
|
|
210
211
|
|
|
211
212
|
this._stage.on('mouseout', function() {
|
|
212
|
-
self.
|
|
213
|
+
self._focusedByHover = false;
|
|
213
214
|
});
|
|
214
215
|
|
|
215
216
|
this._stage.on('click', function(event) {
|
|
216
|
-
self.
|
|
217
|
+
self._focusedByClick = true;
|
|
217
218
|
|
|
218
219
|
if (!self._isClickable) {
|
|
219
220
|
return;
|
|
@@ -307,6 +308,10 @@ define([
|
|
|
307
308
|
window.addEventListener('mouseup', this._mouseUp.bind(this), false);
|
|
308
309
|
window.addEventListener('touchend', this._mouseUp.bind(this), false);
|
|
309
310
|
window.addEventListener('blur', this._mouseUp.bind(this), false);
|
|
311
|
+
|
|
312
|
+
// Handle clicks outside the timeline to remove focus
|
|
313
|
+
this._onWindowClick = this._onWindowClick.bind(this);
|
|
314
|
+
window.addEventListener('click', this._onWindowClick, false);
|
|
310
315
|
}
|
|
311
316
|
|
|
312
317
|
View.prototype._mouseUp = function() {
|
|
@@ -314,6 +319,12 @@ define([
|
|
|
314
319
|
this._peaks.emit('handler.view.mouseup');
|
|
315
320
|
};
|
|
316
321
|
|
|
322
|
+
View.prototype._onWindowClick = function(event) {
|
|
323
|
+
if (!this._container.contains(event.target)) {
|
|
324
|
+
this._focusedByClick = false;
|
|
325
|
+
}
|
|
326
|
+
};
|
|
327
|
+
|
|
317
328
|
View.prototype.setClickable = function(clickable) {
|
|
318
329
|
this._isClickable = clickable;
|
|
319
330
|
};
|
|
@@ -430,8 +441,16 @@ define([
|
|
|
430
441
|
return this._stage.listening();
|
|
431
442
|
};
|
|
432
443
|
|
|
444
|
+
View.prototype.isFocusedByHover = function() {
|
|
445
|
+
return this._focusedByHover;
|
|
446
|
+
};
|
|
447
|
+
|
|
448
|
+
View.prototype.isFocusedByClick = function() {
|
|
449
|
+
return this._focusedByClick;
|
|
450
|
+
};
|
|
451
|
+
|
|
433
452
|
View.prototype.isFocused = function() {
|
|
434
|
-
return this.
|
|
453
|
+
return this._focusedByHover || this._focusedByClick;
|
|
435
454
|
};
|
|
436
455
|
|
|
437
456
|
View.prototype.batchDrawSourcesLayer = function() {
|
|
@@ -900,6 +919,9 @@ define([
|
|
|
900
919
|
this._peaks.off('handler.view.defaultmode', this._onDefaultMode);
|
|
901
920
|
this._peaks.off('handler.view.cutmode', this._onCutMode);
|
|
902
921
|
|
|
922
|
+
// Remove window click listener
|
|
923
|
+
window.removeEventListener('click', this._onWindowClick, false);
|
|
924
|
+
|
|
903
925
|
if (this._stage) {
|
|
904
926
|
this._stage.destroy();
|
|
905
927
|
this._stage = null;
|