@checksub_team/peaks_timeline 2.2.1 → 2.3.0-alpha.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/package.json +1 -1
- package/peaks.js +780 -175
- package/src/components/axis.js +24 -13
- package/src/components/invoker.js +218 -2
- package/src/components/line-group.js +6 -6
- package/src/components/line-groups.js +8 -3
- package/src/components/line-indicator.js +11 -2
- package/src/components/mode-layer.js +50 -7
- package/src/components/playhead-layer.js +13 -3
- package/src/components/source-group.js +303 -65
- package/src/components/sources-layer.js +305 -42
- package/src/components/waveform-builder.js +27 -9
- package/src/utils.js +90 -0
- package/src/view.js +152 -44
package/src/view.js
CHANGED
|
@@ -120,8 +120,6 @@ define([
|
|
|
120
120
|
height: self._height
|
|
121
121
|
});
|
|
122
122
|
|
|
123
|
-
self._tempGroup = new Konva.Group({ listening: false });
|
|
124
|
-
|
|
125
123
|
self._width -= self._peaks.options.lineIndicatorWidth;
|
|
126
124
|
|
|
127
125
|
self._axis = new Axis(self._peaks, self, {
|
|
@@ -134,8 +132,6 @@ define([
|
|
|
134
132
|
self._sourcesLayer = new SourcesLayer(peaks, self, true);
|
|
135
133
|
self._sourcesLayer.addToStage(self._stage);
|
|
136
134
|
|
|
137
|
-
self._sourcesLayer.add(self._tempGroup);
|
|
138
|
-
|
|
139
135
|
self._axis.addFrontToStage(self._stage);
|
|
140
136
|
|
|
141
137
|
self._playheadLayer = new PlayheadLayer(
|
|
@@ -315,7 +311,7 @@ define([
|
|
|
315
311
|
}
|
|
316
312
|
|
|
317
313
|
View.prototype._mouseUp = function() {
|
|
318
|
-
this.
|
|
314
|
+
this.stopAutoScroll();
|
|
319
315
|
this._peaks.emit('handler.view.mouseup');
|
|
320
316
|
};
|
|
321
317
|
|
|
@@ -329,68 +325,180 @@ define([
|
|
|
329
325
|
this._isClickable = clickable;
|
|
330
326
|
};
|
|
331
327
|
|
|
332
|
-
View.prototype.getTempGroup = function() {
|
|
333
|
-
return this._tempGroup;
|
|
334
|
-
};
|
|
335
|
-
|
|
336
328
|
View.prototype.getSelectedElements = function() {
|
|
337
329
|
return Object.values(this._modeLayer.getSelectedElements());
|
|
338
330
|
};
|
|
339
331
|
|
|
340
|
-
|
|
341
|
-
|
|
332
|
+
/**
|
|
333
|
+
* Updates the view with auto-scroll behavior during drag operations.
|
|
334
|
+
*
|
|
335
|
+
* Auto-scroll activates when the pointer is within `autoScrollThreshold` of
|
|
336
|
+
* the left/right edges. While scrolling, we call `updateWhileScrolling` on
|
|
337
|
+
* every animation frame after updating the timeline offset.
|
|
338
|
+
*
|
|
339
|
+
* If auto-scroll is not active, we stop any pending auto-scroll loop and call
|
|
340
|
+
* `updateWhileNotScrolling` (or fall back to `updateWhileScrolling`).
|
|
341
|
+
*
|
|
342
|
+
* Uses requestAnimationFrame for smooth, consistent scrolling.
|
|
343
|
+
*
|
|
344
|
+
* @param {Function} updateWhileScrolling Called after each scroll step.
|
|
345
|
+
* @param {Function} [updateWhileNotScrolling] Called when not scrolling.
|
|
346
|
+
*/
|
|
347
|
+
View.prototype.updateWithAutoScroll = function(updateWhileScrolling,
|
|
348
|
+
updateWhileNotScrolling,
|
|
349
|
+
enableVerticalAutoScroll) {
|
|
342
350
|
var self = this;
|
|
343
|
-
var posX = this.getPointerPosition().x;
|
|
344
|
-
var threshold = Math.round(this._peaks.options.autoScrollThreshold * this.getWidth());
|
|
345
351
|
|
|
346
|
-
|
|
352
|
+
var pointer = this.getPointerPosition();
|
|
353
|
+
var pointerX = pointer ? pointer.x : null;
|
|
354
|
+
var pointerY = pointer ? pointer.y : null;
|
|
355
|
+
var viewWidth = this.getWidth();
|
|
356
|
+
var viewHeight = this.getHeight();
|
|
357
|
+
var thresholdPx = Math.round(this._peaks.options.autoScrollThreshold * viewWidth);
|
|
358
|
+
var thresholdPy = Math.round(this._peaks.options.autoScrollThreshold * viewHeight);
|
|
359
|
+
|
|
360
|
+
var MAX_AUTO_SCROLL_PX_PER_FRAME = 30;
|
|
361
|
+
var NOMINAL_FRAME_MS = 16.67; // ~60fps
|
|
347
362
|
|
|
348
|
-
|
|
349
|
-
|
|
363
|
+
function getAutoScrollVelocity(pointerValue, threshold, size) {
|
|
364
|
+
if (typeof pointerValue !== 'number' || threshold <= 0 || size <= 0) {
|
|
365
|
+
return 0;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
if (pointerValue < threshold) {
|
|
369
|
+
return Math.round(
|
|
370
|
+
-MAX_AUTO_SCROLL_PX_PER_FRAME * Math.min(1, (threshold - pointerValue) / threshold)
|
|
371
|
+
);
|
|
372
|
+
}
|
|
373
|
+
if (pointerValue > size - threshold) {
|
|
374
|
+
return Math.round(
|
|
375
|
+
MAX_AUTO_SCROLL_PX_PER_FRAME
|
|
376
|
+
* Math.min(1, (pointerValue - (size - threshold)) / threshold)
|
|
377
|
+
);
|
|
378
|
+
}
|
|
379
|
+
return 0;
|
|
350
380
|
}
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
381
|
+
|
|
382
|
+
var velocityXPerFrame = getAutoScrollVelocity(pointerX, thresholdPx, viewWidth);
|
|
383
|
+
|
|
384
|
+
var verticalScrollingEnabled = Boolean(enableVerticalAutoScroll
|
|
385
|
+
&& this._peaks.options.enableVerticalScrolling);
|
|
386
|
+
|
|
387
|
+
var maxFrameOffsetY = 0;
|
|
388
|
+
|
|
389
|
+
if (verticalScrollingEnabled) {
|
|
390
|
+
maxFrameOffsetY = this.getFullHeight() - viewHeight;
|
|
391
|
+
if (!Number.isFinite(maxFrameOffsetY) || maxFrameOffsetY < 0) {
|
|
392
|
+
maxFrameOffsetY = 0;
|
|
393
|
+
}
|
|
355
394
|
}
|
|
356
395
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
396
|
+
var velocityYPerFrame = verticalScrollingEnabled && maxFrameOffsetY > 0 ?
|
|
397
|
+
getAutoScrollVelocity(pointerY, thresholdPy, viewHeight) :
|
|
398
|
+
0;
|
|
399
|
+
|
|
400
|
+
// For left scroll (negative), only scroll if we can actually move left.
|
|
401
|
+
// For right scroll (positive), allow scrolling (timeline can extend).
|
|
402
|
+
var canScrollX = velocityXPerFrame > 0 || (velocityXPerFrame < 0 && self.getFrameOffset() > 0);
|
|
403
|
+
var canScrollY = verticalScrollingEnabled && maxFrameOffsetY > 0 && (
|
|
404
|
+
(velocityYPerFrame > 0 && self.getFrameOffsetY() < maxFrameOffsetY)
|
|
405
|
+
|| (velocityYPerFrame < 0 && self.getFrameOffsetY() > 0)
|
|
406
|
+
);
|
|
407
|
+
|
|
408
|
+
// Keep the current velocities on the instance for debugging/inspection.
|
|
409
|
+
this._autoScrollVelocityX = velocityXPerFrame;
|
|
410
|
+
this._autoScrollVelocityY = velocityYPerFrame;
|
|
411
|
+
|
|
412
|
+
if ((velocityXPerFrame !== 0 && canScrollX)
|
|
413
|
+
|| (velocityYPerFrame !== 0 && canScrollY)) {
|
|
414
|
+
if (!this._scrollingRafId) {
|
|
415
|
+
var lastTime = performance.now();
|
|
416
|
+
|
|
417
|
+
function scrollFrame(currentTime) {
|
|
418
|
+
if (!self._scrollingRafId) {
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
var xVel = self._autoScrollVelocityX || 0;
|
|
423
|
+
var yVel = self._autoScrollVelocityY || 0;
|
|
424
|
+
|
|
425
|
+
var canContinueX = xVel > 0 || (xVel < 0 && self.getFrameOffset() > 0);
|
|
426
|
+
var maxY = 0;
|
|
427
|
+
var canContinueY = false;
|
|
428
|
+
|
|
429
|
+
if (verticalScrollingEnabled) {
|
|
430
|
+
maxY = self.getFullHeight() - self.getHeight();
|
|
431
|
+
if (!Number.isFinite(maxY) || maxY < 0) {
|
|
432
|
+
maxY = 0;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
canContinueY = maxY > 0 && (
|
|
436
|
+
(yVel > 0 && self.getFrameOffsetY() < maxY)
|
|
437
|
+
|| (yVel < 0 && self.getFrameOffsetY() > 0)
|
|
438
|
+
);
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
if ((xVel === 0 || !canContinueX)
|
|
442
|
+
&& (yVel === 0 || !canContinueY)) {
|
|
443
|
+
self.stopAutoScroll();
|
|
444
|
+
updateWhileScrolling();
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
// Calculate time delta for consistent scroll speed regardless of frame rate
|
|
449
|
+
var deltaTime = currentTime - lastTime;
|
|
450
|
+
var scrollAmountX = Math.round(xVel * deltaTime / NOMINAL_FRAME_MS);
|
|
451
|
+
var scrollAmountY = Math.round(yVel * deltaTime / NOMINAL_FRAME_MS);
|
|
452
|
+
|
|
453
|
+
lastTime = currentTime;
|
|
454
|
+
|
|
455
|
+
var newOffsetX = self.getFrameOffset() + scrollAmountX;
|
|
456
|
+
var newOffsetY = self.getFrameOffsetY() + scrollAmountY;
|
|
362
457
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
458
|
+
if (newOffsetX < 0) {
|
|
459
|
+
newOffsetX = 0;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
if (verticalScrollingEnabled) {
|
|
463
|
+
if (newOffsetY < 0) {
|
|
464
|
+
newOffsetY = 0;
|
|
367
465
|
}
|
|
368
|
-
else {
|
|
369
|
-
|
|
466
|
+
else if (newOffsetY > maxY) {
|
|
467
|
+
newOffsetY = maxY;
|
|
370
468
|
}
|
|
469
|
+
}
|
|
371
470
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
471
|
+
if (!verticalScrollingEnabled) {
|
|
472
|
+
self.updateTimeline(newOffsetX);
|
|
473
|
+
}
|
|
474
|
+
else {
|
|
475
|
+
self.updateTimeline(newOffsetX, newOffsetY);
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
updateWhileScrolling();
|
|
479
|
+
self._scrollingRafId = requestAnimationFrame(scrollFrame);
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
self._scrollingRafId = requestAnimationFrame(scrollFrame);
|
|
376
483
|
}
|
|
377
484
|
}
|
|
378
485
|
else {
|
|
379
|
-
this.
|
|
486
|
+
this.stopAutoScroll();
|
|
380
487
|
|
|
381
|
-
if (
|
|
382
|
-
|
|
488
|
+
if (updateWhileNotScrolling) {
|
|
489
|
+
updateWhileNotScrolling();
|
|
383
490
|
}
|
|
384
491
|
else {
|
|
385
|
-
|
|
492
|
+
updateWhileScrolling();
|
|
386
493
|
}
|
|
387
494
|
}
|
|
388
495
|
};
|
|
389
496
|
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
this.
|
|
497
|
+
// Clear/stop any active auto-scroll loop.
|
|
498
|
+
View.prototype.stopAutoScroll = function() {
|
|
499
|
+
if (this._scrollingRafId) {
|
|
500
|
+
cancelAnimationFrame(this._scrollingRafId);
|
|
501
|
+
this._scrollingRafId = null;
|
|
394
502
|
}
|
|
395
503
|
};
|
|
396
504
|
|
|
@@ -663,7 +771,7 @@ define([
|
|
|
663
771
|
|
|
664
772
|
this.updateTimeline(this._frameOffset);
|
|
665
773
|
|
|
666
|
-
this._sourcesLayer.rescale(
|
|
774
|
+
this._sourcesLayer.rescale();
|
|
667
775
|
|
|
668
776
|
// Update the playhead position after zooming.
|
|
669
777
|
this._playheadLayer.updatePlayheadTime(currentTime);
|