@checksub_team/peaks_timeline 2.2.1 → 2.3.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.
package/peaks.js CHANGED
@@ -14760,8 +14760,17 @@ module.exports = function (Utils, Konva) {
14760
14760
  },{"../utils":116,"konva":43}],90:[function(_dereq_,module,exports){
14761
14761
  module.exports = function () {
14762
14762
  'use strict';
14763
+ var raf = typeof window !== 'undefined' && window.requestAnimationFrame || function (fn) {
14764
+ return setTimeout(fn, 16);
14765
+ };
14766
+ var caf = typeof window !== 'undefined' && window.cancelAnimationFrame || function (id) {
14767
+ clearTimeout(id);
14768
+ };
14763
14769
  function Invoker() {
14764
14770
  this._throttledFunc = {};
14771
+ this._rafThrottled = {};
14772
+ this._frameCallbacks = [];
14773
+ this._frameScheduled = false;
14765
14774
  }
14766
14775
  Invoker.prototype.throttle = function (id, func, wait) {
14767
14776
  var self = this;
@@ -14785,6 +14794,52 @@ module.exports = function () {
14785
14794
  }, wait);
14786
14795
  }
14787
14796
  };
14797
+ Invoker.prototype.throttleRAF = function (id, func) {
14798
+ var self = this;
14799
+ if (this._rafThrottled[id]) {
14800
+ this._rafThrottled[id].func = func;
14801
+ this._rafThrottled[id].pending = true;
14802
+ return;
14803
+ }
14804
+ this._rafThrottled[id] = {
14805
+ func: func,
14806
+ pending: true,
14807
+ rafId: null
14808
+ };
14809
+ function frame() {
14810
+ if (self._rafThrottled[id] && self._rafThrottled[id].pending) {
14811
+ self._rafThrottled[id].pending = false;
14812
+ self._rafThrottled[id].func();
14813
+ self._rafThrottled[id].rafId = raf(frame);
14814
+ } else if (self._rafThrottled[id]) {
14815
+ delete self._rafThrottled[id];
14816
+ }
14817
+ }
14818
+ this._rafThrottled[id].rafId = raf(frame);
14819
+ };
14820
+ Invoker.prototype.cancelThrottleRAF = function (id) {
14821
+ if (this._rafThrottled[id]) {
14822
+ if (this._rafThrottled[id].rafId) {
14823
+ caf(this._rafThrottled[id].rafId);
14824
+ }
14825
+ delete this._rafThrottled[id];
14826
+ }
14827
+ };
14828
+ Invoker.prototype.scheduleFrame = function (callback) {
14829
+ var self = this;
14830
+ this._frameCallbacks.push(callback);
14831
+ if (!this._frameScheduled) {
14832
+ this._frameScheduled = true;
14833
+ raf(function () {
14834
+ self._frameScheduled = false;
14835
+ var callbacks = self._frameCallbacks;
14836
+ self._frameCallbacks = [];
14837
+ for (var i = 0; i < callbacks.length; i++) {
14838
+ callbacks[i]();
14839
+ }
14840
+ });
14841
+ }
14842
+ };
14788
14843
  Invoker.prototype.debounce = function (func, wait, immediate) {
14789
14844
  var timeout;
14790
14845
  return function executedFunction() {
@@ -14804,6 +14859,96 @@ module.exports = function () {
14804
14859
  }
14805
14860
  };
14806
14861
  };
14862
+ Invoker.prototype.throttleLeading = function (func) {
14863
+ var scheduled = false;
14864
+ var savedArgs = null;
14865
+ var savedThis = null;
14866
+ return function throttled() {
14867
+ if (scheduled) {
14868
+ savedArgs = arguments;
14869
+ savedThis = this;
14870
+ return;
14871
+ }
14872
+ func.apply(this, arguments);
14873
+ scheduled = true;
14874
+ raf(function () {
14875
+ scheduled = false;
14876
+ if (savedArgs) {
14877
+ func.apply(savedThis, savedArgs);
14878
+ savedArgs = null;
14879
+ savedThis = null;
14880
+ }
14881
+ });
14882
+ };
14883
+ };
14884
+ Invoker.prototype.throttleTrailing = function (func) {
14885
+ var rafId = null;
14886
+ var savedArgs = null;
14887
+ var savedThis = null;
14888
+ return function throttled() {
14889
+ savedArgs = arguments;
14890
+ savedThis = this;
14891
+ if (rafId === null) {
14892
+ rafId = raf(function () {
14893
+ rafId = null;
14894
+ func.apply(savedThis, savedArgs);
14895
+ });
14896
+ }
14897
+ };
14898
+ };
14899
+ Invoker.prototype.createBatcher = function (processFn, options) {
14900
+ options = options || {};
14901
+ var maxWait = options.maxWait || 100;
14902
+ var items = [];
14903
+ var timeout = null;
14904
+ var lastFlush = 0;
14905
+ function flush() {
14906
+ if (items.length === 0) {
14907
+ return;
14908
+ }
14909
+ var batch = items;
14910
+ items = [];
14911
+ timeout = null;
14912
+ lastFlush = Date.now();
14913
+ processFn(batch);
14914
+ }
14915
+ return {
14916
+ add: function (item) {
14917
+ items.push(item);
14918
+ if (timeout === null) {
14919
+ var timeSinceLastFlush = Date.now() - lastFlush;
14920
+ if (timeSinceLastFlush >= maxWait) {
14921
+ raf(flush);
14922
+ } else {
14923
+ timeout = setTimeout(flush, Math.min(16, maxWait - timeSinceLastFlush));
14924
+ }
14925
+ }
14926
+ },
14927
+ flush: flush,
14928
+ size: function () {
14929
+ return items.length;
14930
+ }
14931
+ };
14932
+ };
14933
+ Invoker.prototype.destroy = function () {
14934
+ var id;
14935
+ for (id in this._throttledFunc) {
14936
+ if (Object.prototype.hasOwnProperty.call(this._throttledFunc, id)) {
14937
+ clearInterval(this._throttledFunc[id].timer);
14938
+ }
14939
+ }
14940
+ this._throttledFunc = {};
14941
+ for (id in this._rafThrottled) {
14942
+ if (Object.prototype.hasOwnProperty.call(this._rafThrottled, id)) {
14943
+ if (this._rafThrottled[id].rafId) {
14944
+ caf(this._rafThrottled[id].rafId);
14945
+ }
14946
+ }
14947
+ }
14948
+ this._rafThrottled = {};
14949
+ this._frameCallbacks = [];
14950
+ this._frameScheduled = false;
14951
+ };
14807
14952
  return Invoker;
14808
14953
  }();
14809
14954
  },{}],91:[function(_dereq_,module,exports){
@@ -14937,8 +15082,10 @@ module.exports = function (SourceGroup, Utils, Konva) {
14937
15082
  LineGroup.prototype.addSource = function (source, sourceGroup, sourcesAround) {
14938
15083
  if (sourceGroup) {
14939
15084
  this._sourcesGroup[source.id] = sourceGroup;
14940
- if (!sourceGroup.getParent() || !sourceGroup.isDescendantOf(this._group)) {
14941
- sourceGroup.moveTo(this._group);
15085
+ if (!sourceGroup.isActive()) {
15086
+ if (!sourceGroup.getParent() || !sourceGroup.isDescendantOf(this._group)) {
15087
+ sourceGroup.moveTo(this._group);
15088
+ }
14942
15089
  }
14943
15090
  }
14944
15091
  if (!this._sources[source.id]) {
@@ -15042,9 +15189,6 @@ module.exports = function (SourceGroup, Utils, Konva) {
15042
15189
  LineGroup.prototype.removeSourceGroup = function (source) {
15043
15190
  const sourceGroup = this._sourcesGroup[source.id];
15044
15191
  delete this._sourcesGroup[source.id];
15045
- if (sourceGroup) {
15046
- sourceGroup.hideButKeepFocus();
15047
- }
15048
15192
  return sourceGroup;
15049
15193
  };
15050
15194
  LineGroup.prototype.removeSource = function (source) {
@@ -15359,6 +15503,7 @@ module.exports = function (SegmentsGroup, LineGroup, LineIndicator, Utils) {
15359
15503
  this._areSegmentInteractionsAllowed = true;
15360
15504
  this._automaticallyCreatedLineId = null;
15361
15505
  this._automaticLineCreationPosition = null;
15506
+ this._automaticLineCreationMouseY = null;
15362
15507
  this._automaticLineCreationTimeout = null;
15363
15508
  this._segmentsGroups = {};
15364
15509
  this._segmentsGroupToLine = {};
@@ -15438,7 +15583,6 @@ module.exports = function (SegmentsGroup, LineGroup, LineIndicator, Utils) {
15438
15583
  };
15439
15584
  LineGroups.prototype._onLineHeightChanged = function () {
15440
15585
  this.refreshLineYs();
15441
- this._view.updateTimeline();
15442
15586
  };
15443
15587
  LineGroups.prototype._onSourcesWrappingChanged = function (sources) {
15444
15588
  sources.forEach(function (source) {
@@ -15544,9 +15688,10 @@ module.exports = function (SegmentsGroup, LineGroup, LineIndicator, Utils) {
15544
15688
  }
15545
15689
  this._automaticLineCreationTimeout = null;
15546
15690
  this._automaticLineCreationPosition = null;
15691
+ this._automaticLineCreationMouseY = null;
15547
15692
  this._automaticallyCreatedLineId = null;
15548
15693
  };
15549
- LineGroups.prototype.manageAutomaticLineCreation = function (newLinePosition, initialPosition, sources) {
15694
+ LineGroups.prototype.manageAutomaticLineCreation = function (newLinePosition, initialPosition, sources, mouseY) {
15550
15695
  if (!Utils.isNullOrUndefined(this._automaticallyCreatedLineId)) {
15551
15696
  return;
15552
15697
  } else if (!Utils.isNullOrUndefined(this._automaticLineCreationPosition) && this._automaticLineCreationPosition !== newLinePosition) {
@@ -15556,6 +15701,7 @@ module.exports = function (SegmentsGroup, LineGroup, LineIndicator, Utils) {
15556
15701
  return;
15557
15702
  }
15558
15703
  this._automaticLineCreationPosition = newLinePosition;
15704
+ this._automaticLineCreationMouseY = mouseY;
15559
15705
  this._automaticLineCreationTimeout = setTimeout(function () {
15560
15706
  this._automaticLineCreationTimeout = null;
15561
15707
  const currentLine = this._lineGroupsByPosition[initialPosition];
@@ -15586,8 +15732,30 @@ module.exports = function (SegmentsGroup, LineGroup, LineIndicator, Utils) {
15586
15732
  }
15587
15733
  this._automaticallyCreatedLineId = automaticallyCreatedLineGroup.getId();
15588
15734
  this._moveSourcesToPositionIfPossible(sources, newLinePosition);
15735
+ this._nudgeFrameOffsetYToLineCenter(newLinePosition, this._automaticLineCreationMouseY);
15736
+ this._peaks.emit('sources.delayedLineChange', sources);
15589
15737
  }.bind(this), this._peaks.options.automaticLineCreationDelay);
15590
15738
  };
15739
+ LineGroups.prototype._nudgeFrameOffsetYToLineCenter = function (linePosition, mouseY) {
15740
+ if (!this._peaks.options.enableVerticalScrolling) {
15741
+ return;
15742
+ }
15743
+ if (Utils.isNullOrUndefined(mouseY)) {
15744
+ return;
15745
+ }
15746
+ const lineGroup = this._lineGroupsByPosition[linePosition];
15747
+ if (!lineGroup) {
15748
+ return;
15749
+ }
15750
+ const targetCenterY = lineGroup.y() + lineGroup.lineHeight() / 2;
15751
+ const deltaY = targetCenterY - mouseY;
15752
+ if (deltaY === 0) {
15753
+ return;
15754
+ }
15755
+ const maxOffsetY = Math.max(0, this._view.getFullHeight() - this._view.getHeight());
15756
+ const nextOffsetY = Utils.clamp(this._view.getFrameOffsetY() + deltaY, 0, maxOffsetY);
15757
+ this._view.updateTimeline(null, nextOffsetY);
15758
+ };
15591
15759
  LineGroups.prototype.manageVerticalPosition = function (sources, startTime, endTime, mouseX, mouseY) {
15592
15760
  if (Utils.isNullOrUndefined(mouseX)) {
15593
15761
  return;
@@ -15599,7 +15767,7 @@ module.exports = function (SegmentsGroup, LineGroup, LineIndicator, Utils) {
15599
15767
  return;
15600
15768
  }
15601
15769
  if (linePos[0] !== linePos[1]) {
15602
- this.manageAutomaticLineCreation(linePos[0] + 1, position, sources);
15770
+ this.manageAutomaticLineCreation(linePos[0] + 1, position, sources, mouseY);
15603
15771
  } else {
15604
15772
  this.stopAutomaticLineCreation();
15605
15773
  const targetLineGroup = this._lineGroupsByPosition[linePos[0]];
@@ -17910,13 +18078,14 @@ module.exports = function (SegmentShape, Utils, Konva) {
17910
18078
  return SegmentsGroup;
17911
18079
  }(_dereq_('./segment-shape'), _dereq_('../utils'), _dereq_('konva'));
17912
18080
  },{"../utils":116,"./segment-shape":100,"konva":43}],102:[function(_dereq_,module,exports){
17913
- module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva) {
18081
+ module.exports = function (WaveformBuilder, WaveformShape, Loader, Invoker, Utils, Konva) {
17914
18082
  'use strict';
17915
18083
  var SPACING_BETWEEN_PREVIEW_AND_BORDER_RATIO = 0.15;
17916
18084
  var SPACING_BETWEEN_PREVIEWS = 1.5;
17917
18085
  var CORNER_RADIUS = 8;
17918
18086
  var INDICATOR_RADIUS = 4;
17919
- var PREVIEW_CREATE_CHUNK = 8;
18087
+ var PREVIEW_CREATE_CHUNK = 12;
18088
+ var sharedInvoker = new Invoker();
17920
18089
  function SourceGroup(source, peaks, layer, view) {
17921
18090
  this._source = source;
17922
18091
  this._peaks = peaks;
@@ -17924,7 +18093,6 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
17924
18093
  this._view = view;
17925
18094
  this._indicators = {};
17926
18095
  var self = this;
17927
- this._x = this._view.timeToPixels(source.startTime);
17928
18096
  this._width = this._view.timeToPixels(source.endTime - source.startTime);
17929
18097
  var heights = SourceGroup.getHeights(source, peaks);
17930
18098
  this._unwrappedHeight = heights.unwrapped;
@@ -17935,12 +18103,15 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
17935
18103
  this._selected = this._source.selected;
17936
18104
  this._hovered = false;
17937
18105
  this._isDragged = false;
18106
+ this._isHandleDragging = false;
17938
18107
  this._destroyed = false;
18108
+ this._drawScheduled = false;
17939
18109
  this._previewList = [];
17940
18110
  this._previewBuildQueue = new Set();
18111
+ this._pendingIdleCallbacks = new Set();
17941
18112
  this._markersGroup = this._createMarkers();
17942
18113
  this._group = new Konva.Group({
17943
- x: this._x,
18114
+ x: this._view.timeToPixels(source.startTime),
17944
18115
  sourceId: this._source.id,
17945
18116
  draggable: this._source.draggable,
17946
18117
  dragBoundFunc: function () {
@@ -17995,14 +18166,14 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
17995
18166
  if (!this._source.loading) {
17996
18167
  this._showButtons();
17997
18168
  }
17998
- this._batchDraw();
18169
+ this._scheduleBatchDraw();
17999
18170
  };
18000
18171
  SourceGroup.prototype._onHoverEnd = function () {
18001
18172
  this._hovered = false;
18002
18173
  this._manualHover = false;
18003
18174
  this._view.setHoveredElement(null);
18004
18175
  this._hideButtons();
18005
- this._batchDraw();
18176
+ this._scheduleBatchDraw();
18006
18177
  };
18007
18178
  SourceGroup.prototype._onDragStart = function (element) {
18008
18179
  this._isDragged = true;
@@ -18030,7 +18201,7 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
18030
18201
  return this._hovered;
18031
18202
  };
18032
18203
  SourceGroup.prototype.isActive = function () {
18033
- return this._isDragged;
18204
+ return this._isDragged || this._isHandleDragging;
18034
18205
  };
18035
18206
  SourceGroup.prototype.addToContent = function (newChild) {
18036
18207
  if (this._source.wrapped) {
@@ -18045,11 +18216,13 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
18045
18216
  this._rightHandle.width(handleWidth);
18046
18217
  this._rightHandle.x(this._width - handleWidth);
18047
18218
  };
18048
- SourceGroup.prototype._onSourceGroupHandleDrag = function (draggedElement, dragPos, leftHandle) {
18049
- const diff = this._view.pixelsToTime(dragPos.x - this._mouseDownX);
18050
- const timeOffsetDiff = this._view.getTimeOffset() - this._initialTimeOffset;
18219
+ SourceGroup.prototype._onSourceGroupHandleDrag = function (draggedElement, leftHandle) {
18051
18220
  const {start, end} = this._initialTimes;
18052
18221
  this._view.updateWithAutoScroll(function () {
18222
+ var pointer = this._view.getPointerPosition();
18223
+ var pointerX = pointer ? pointer.x : this._mouseDownX;
18224
+ const diff = this._view.pixelsToTime(pointerX - this._mouseDownX);
18225
+ const timeOffsetDiff = this._view.getTimeOffset() - this._initialTimeOffset;
18053
18226
  if (this._layer.manageSourceMovements([this._source], leftHandle ? start + diff + timeOffsetDiff : null, leftHandle ? null : end + diff + timeOffsetDiff)) {
18054
18227
  this._layer.batchDraw();
18055
18228
  }
@@ -18064,8 +18237,9 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
18064
18237
  const endPixel = this._view.timeToPixels(this._source.endTime);
18065
18238
  const frameOffset = this._view.timeToPixels(this._view.getTimeOffset());
18066
18239
  const newTimeToPixelsScale = this._view.getTimeToPixelsScale();
18067
- this._group.x(startPixel - frameOffset);
18068
- this._x = startPixel;
18240
+ if (!this._isDragged) {
18241
+ this._group.x(startPixel - frameOffset);
18242
+ }
18069
18243
  const newWidth = endPixel - startPixel;
18070
18244
  if (newWidth !== this._width) {
18071
18245
  this._width = newWidth;
@@ -18119,12 +18293,14 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
18119
18293
  start: this._source.startTime,
18120
18294
  end: this._source.endTime
18121
18295
  };
18122
- this._isDragged = true;
18296
+ this._isHandleDragging = true;
18123
18297
  this._hideButtons();
18124
18298
  };
18125
18299
  SourceGroup.prototype._onHandleDragEnd = function () {
18126
- this._isDragged = false;
18300
+ this._isHandleDragging = false;
18127
18301
  this._showButtons();
18302
+ this.update();
18303
+ this.prepareDragEnd();
18128
18304
  };
18129
18305
  SourceGroup.prototype._addHandles = function (forceCreate) {
18130
18306
  var self = this;
@@ -18136,12 +18312,18 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
18136
18312
  height: this._unwrappedHeight,
18137
18313
  visible: true,
18138
18314
  draggable: this._source.resizable,
18139
- dragBoundFunc: function (pos) {
18140
- return self._onSourceGroupHandleDrag(this, pos, true);
18315
+ dragBoundFunc: function () {
18316
+ return self._onSourceGroupHandleDrag(this, true);
18141
18317
  }
18142
18318
  });
18143
- this._leftHandle.on('dragstart', this._onHandleDragStart.bind(this));
18144
- this._leftHandle.on('dragend', this._onHandleDragEnd.bind(this));
18319
+ this._leftHandle.on('dragstart', function (event) {
18320
+ event.cancelBubble = true;
18321
+ self._onHandleDragStart(event);
18322
+ });
18323
+ this._leftHandle.on('dragend', function (event) {
18324
+ event.cancelBubble = true;
18325
+ self._onHandleDragEnd(event);
18326
+ });
18145
18327
  if (this._source.resizable) {
18146
18328
  this._leftHandle.on('mouseover', function () {
18147
18329
  self._cursor = 'ew-resize';
@@ -18158,12 +18340,18 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
18158
18340
  height: this._unwrappedHeight,
18159
18341
  visible: true,
18160
18342
  draggable: this._source.resizable,
18161
- dragBoundFunc: function (pos) {
18162
- return self._onSourceGroupHandleDrag(this, pos, false);
18343
+ dragBoundFunc: function () {
18344
+ return self._onSourceGroupHandleDrag(this, false);
18163
18345
  }
18164
18346
  });
18165
- this._rightHandle.on('dragstart', this._onHandleDragStart.bind(this));
18166
- this._rightHandle.on('dragend', this._onHandleDragEnd.bind(this));
18347
+ this._rightHandle.on('dragstart', function (event) {
18348
+ event.cancelBubble = true;
18349
+ self._onHandleDragStart(event);
18350
+ });
18351
+ this._rightHandle.on('dragend', function (event) {
18352
+ event.cancelBubble = true;
18353
+ self._onHandleDragEnd(event);
18354
+ });
18167
18355
  if (this._source.resizable) {
18168
18356
  this._rightHandle.on('mouseover', function () {
18169
18357
  self._cursor = 'ew-resize';
@@ -18206,8 +18394,9 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
18206
18394
  SourceGroup.prototype.drawSourceShape = function (ctx, shape, addBorderWidth, fill) {
18207
18395
  var offset = addBorderWidth ? this._borderWidth : 0;
18208
18396
  var radius = !Utils.isNullOrUndefined(this._source.borderRadius) ? this._source.borderRadius : Math.max(1, Math.min(this._width / 2, Math.min(CORNER_RADIUS, this._height / 2)));
18209
- var x = Math.max(0, this._view.getFrameOffset() - this._x - 2 * radius);
18210
- var width = Math.min(this._width - x, this._view.getWidth() + 4 * radius - Math.max(0, this._x - this._view.getFrameOffset()));
18397
+ var actualX = this._group.x() + this._view.getFrameOffset();
18398
+ var x = Math.max(0, this._view.getFrameOffset() - actualX - 2 * radius);
18399
+ var width = Math.min(this._width - x, this._view.getWidth() + 4 * radius - Math.max(0, actualX - this._view.getFrameOffset()));
18211
18400
  var xWidth = x + width;
18212
18401
  if (width > 0) {
18213
18402
  ctx.beginPath();
@@ -18395,9 +18584,6 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
18395
18584
  SourceGroup.prototype.getWidth = function () {
18396
18585
  return this._width;
18397
18586
  };
18398
- SourceGroup.prototype.getX = function () {
18399
- return this._x;
18400
- };
18401
18587
  SourceGroup.prototype.getAbsoluteY = function () {
18402
18588
  return this._group.absolutePosition().y;
18403
18589
  };
@@ -18413,6 +18599,12 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
18413
18599
  }
18414
18600
  return this._group.y(value);
18415
18601
  };
18602
+ SourceGroup.prototype.absolutePosition = function (value) {
18603
+ if (value) {
18604
+ return this._group.absolutePosition(value);
18605
+ }
18606
+ return this._group.absolutePosition();
18607
+ };
18416
18608
  SourceGroup.prototype.getSource = function () {
18417
18609
  return this._source;
18418
18610
  };
@@ -18423,6 +18615,9 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
18423
18615
  SourceGroup.prototype.stopHover = function () {
18424
18616
  this._group.fire('mouseleave', { evt: new MouseEvent('mouseleave') }, true);
18425
18617
  };
18618
+ SourceGroup.prototype.setDragging = function (isDragging) {
18619
+ this._isDragged = isDragging;
18620
+ };
18426
18621
  SourceGroup.prototype.startDrag = function () {
18427
18622
  return this._group.startDrag();
18428
18623
  };
@@ -18432,12 +18627,12 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
18432
18627
  SourceGroup.prototype.moveTo = function (group) {
18433
18628
  this._group.moveTo(group);
18434
18629
  };
18630
+ SourceGroup.prototype.moveToTop = function () {
18631
+ this._group.moveToTop();
18632
+ };
18435
18633
  SourceGroup.prototype.isDescendantOf = function (group) {
18436
18634
  return group.isAncestorOf(this._group);
18437
18635
  };
18438
- SourceGroup.prototype.hideButKeepFocus = function () {
18439
- this._group.moveTo(this._view.getTempGroup());
18440
- };
18441
18636
  SourceGroup.prototype.getParent = function () {
18442
18637
  return this._group.getParent();
18443
18638
  };
@@ -18547,17 +18742,29 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
18547
18742
  }
18548
18743
  };
18549
18744
  SourceGroup.prototype._createAudioPreview = function (preview, redraw) {
18745
+ var url = preview.url;
18746
+ var scaledData = this._layer.getLoadedData(url + '-scaled');
18747
+ var currentScale = this._view.getTimeToPixelsScale();
18748
+ if (scaledData && scaledData.scale !== currentScale) {
18749
+ var originalData = this._layer.getLoadedData(url);
18750
+ if (originalData) {
18751
+ this._layer.setLoadedData(url + '-scaled', {
18752
+ data: originalData.resample({ scale: originalData.sample_rate / currentScale }),
18753
+ scale: currentScale
18754
+ });
18755
+ }
18756
+ }
18550
18757
  var waveform = new WaveformShape({
18551
18758
  layer: this._layer,
18552
18759
  view: this._view,
18553
18760
  source: this._source,
18554
18761
  height: preview.group.height(),
18555
- url: preview.url
18762
+ url: url
18556
18763
  });
18557
18764
  preview.group.add(waveform);
18558
18765
  this._addToUnwrap(preview.group);
18559
18766
  if (redraw) {
18560
- this._layer.rescale(true);
18767
+ this._scheduleBatchDraw();
18561
18768
  }
18562
18769
  this._previewList.push(preview);
18563
18770
  };
@@ -18631,6 +18838,19 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
18631
18838
  }
18632
18839
  });
18633
18840
  };
18841
+ SourceGroup.prototype._scheduleBatchDraw = function () {
18842
+ if (this._destroyed || this._drawScheduled) {
18843
+ return;
18844
+ }
18845
+ this._drawScheduled = true;
18846
+ var self = this;
18847
+ sharedInvoker.scheduleFrame(function () {
18848
+ self._drawScheduled = false;
18849
+ if (!self._destroyed) {
18850
+ self._batchDraw();
18851
+ }
18852
+ });
18853
+ };
18634
18854
  SourceGroup.prototype._batchDraw = function () {
18635
18855
  var layer = this._group && this._group.getLayer && this._group.getLayer();
18636
18856
  if (layer && typeof layer.batchDraw === 'function') {
@@ -18638,27 +18858,13 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
18638
18858
  }
18639
18859
  };
18640
18860
  SourceGroup.prototype._scheduleIdle = function (fn) {
18641
- if (typeof window !== 'undefined' && window.requestIdleCallback) {
18642
- return window.requestIdleCallback(fn, { timeout: 50 });
18643
- }
18644
- if (typeof window !== 'undefined' && window.requestAnimationFrame) {
18645
- return window.requestAnimationFrame(function () {
18646
- fn({
18647
- timeRemaining: function () {
18648
- return 0;
18649
- },
18650
- didTimeout: true
18651
- });
18652
- });
18653
- }
18654
- return setTimeout(function () {
18655
- fn({
18656
- timeRemaining: function () {
18657
- return 0;
18658
- },
18659
- didTimeout: true
18660
- });
18661
- }, 0);
18861
+ var self = this;
18862
+ var id = Utils.scheduleIdle(function (deadline) {
18863
+ self._pendingIdleCallbacks.delete(id);
18864
+ fn(deadline);
18865
+ }, { timeout: 50 });
18866
+ this._pendingIdleCallbacks.add(id);
18867
+ return id;
18662
18868
  };
18663
18869
  SourceGroup.prototype._ensureImagePreviewCount = function (preview, targetCount, interImageSpacing) {
18664
18870
  var imageList = preview.group.getChildren();
@@ -18670,7 +18876,7 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
18670
18876
  imageList[j].visible(false);
18671
18877
  }
18672
18878
  if (currentCount >= targetCount || this._previewBuildQueue.has(preview)) {
18673
- this._batchDraw();
18879
+ this._scheduleBatchDraw();
18674
18880
  return;
18675
18881
  }
18676
18882
  this._previewBuildQueue.add(preview);
@@ -18692,7 +18898,7 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
18692
18898
  nextIndex += 1;
18693
18899
  added += 1;
18694
18900
  }
18695
- self._batchDraw();
18901
+ self._scheduleBatchDraw();
18696
18902
  if (nextIndex < targetCount) {
18697
18903
  self._scheduleIdle(buildChunk);
18698
18904
  } else {
@@ -18725,7 +18931,7 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
18725
18931
  }
18726
18932
  this._ensureImagePreviewCount(preview, targetCount, interImageSpacing);
18727
18933
  if (redraw) {
18728
- this._batchDraw();
18934
+ this._scheduleBatchDraw();
18729
18935
  }
18730
18936
  this._previewList.push(preview);
18731
18937
  };
@@ -19168,7 +19374,7 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
19168
19374
  volumeText.text((volume * 100).toFixed(0) + '%');
19169
19375
  self._source.volume = Math.max(self._source.volumeRange[0], Math.min(volume, self._source.volumeRange[1]));
19170
19376
  self._peaks.emit('source.volumeChanged', self._source);
19171
- self._batchDraw();
19377
+ self._scheduleBatchDraw();
19172
19378
  });
19173
19379
  volumeSliderGroup.on('dragend', function () {
19174
19380
  volumeText.visible(false);
@@ -19185,6 +19391,15 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
19185
19391
  return volumeGroup;
19186
19392
  };
19187
19393
  SourceGroup.prototype.destroy = function () {
19394
+ if (this._pendingIdleCallbacks) {
19395
+ this._pendingIdleCallbacks.forEach(function (id) {
19396
+ Utils.cancelIdle(id);
19397
+ });
19398
+ this._pendingIdleCallbacks.clear();
19399
+ }
19400
+ if (this._previewBuildQueue) {
19401
+ this._previewBuildQueue.clear();
19402
+ }
19188
19403
  if (this._buttonsAnimation) {
19189
19404
  this._buttonsAnimation.destroy();
19190
19405
  this._buttonsAnimation = null;
@@ -19207,8 +19422,8 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
19207
19422
  };
19208
19423
  };
19209
19424
  return SourceGroup;
19210
- }(_dereq_('./waveform-builder'), _dereq_('./waveform-shape'), _dereq_('./loader'), _dereq_('../utils'), _dereq_('konva'));
19211
- },{"../utils":116,"./loader":94,"./waveform-builder":105,"./waveform-shape":106,"konva":43}],103:[function(_dereq_,module,exports){
19425
+ }(_dereq_('./waveform-builder'), _dereq_('./waveform-shape'), _dereq_('./loader'), _dereq_('./invoker'), _dereq_('../utils'), _dereq_('konva'));
19426
+ },{"../utils":116,"./invoker":90,"./loader":94,"./waveform-builder":105,"./waveform-shape":106,"konva":43}],103:[function(_dereq_,module,exports){
19212
19427
  module.exports = function (SourceGroup, LineGroups, DataRetriever, Invoker, Utils, Konva) {
19213
19428
  'use strict';
19214
19429
  function SourcesLayer(peaks, view, allowEditing) {
@@ -19217,11 +19432,15 @@ module.exports = function (SourceGroup, LineGroups, DataRetriever, Invoker, Util
19217
19432
  this._allowEditing = allowEditing;
19218
19433
  this._sourcesGroup = {};
19219
19434
  this._layer = new Konva.Layer();
19435
+ this._dragLayer = new Konva.Layer();
19220
19436
  this._dataRetriever = new DataRetriever(peaks);
19221
19437
  this._lineGroups = new LineGroups(peaks, view, this);
19222
19438
  this._lineGroups.addToLayer(this);
19223
19439
  this._loadedData = {};
19224
- this._debouncedRescale = new Invoker().debounce(this._rescale, 150);
19440
+ this._invoker = new Invoker();
19441
+ this._rescaleVersion = 0;
19442
+ this._throttledBatchDraw = this._invoker.throttleTrailing(this._layer.batchDraw.bind(this._layer));
19443
+ this._drawPending = false;
19225
19444
  this._peaks.on('handler.sources.add', this._onSourcesAdd.bind(this));
19226
19445
  this._peaks.on('handler.sources.destroy', this._onSourcesDestroy.bind(this));
19227
19446
  this._peaks.on('handler.sources.show', this._onSourcesShow.bind(this));
@@ -19232,7 +19451,13 @@ module.exports = function (SourceGroup, LineGroups, DataRetriever, Invoker, Util
19232
19451
  this._peaks.on('handler.segments.show', this._onSegmentsShow.bind(this));
19233
19452
  this._peaks.on('model.source.setIndicators', this.setIndicators.bind(this));
19234
19453
  this._peaks.on('handler.view.mouseup', this._stopDrag.bind(this));
19454
+ this._peaks.on('sources.delayedLineChange', this._onSourcesDelayedLineChanged.bind(this));
19235
19455
  }
19456
+ SourcesLayer.prototype._onSourcesDelayedLineChanged = function () {
19457
+ if (this._dragGhosts && this._draggedElements && this._draggedElements.length > 0) {
19458
+ this._dragSourcesGroup();
19459
+ }
19460
+ };
19236
19461
  SourcesLayer.prototype._stopDrag = function () {
19237
19462
  const draggedSourceGroup = this._sourcesGroup[this._draggedElementId];
19238
19463
  if (draggedSourceGroup) {
@@ -19256,6 +19481,7 @@ module.exports = function (SourceGroup, LineGroups, DataRetriever, Invoker, Util
19256
19481
  };
19257
19482
  SourcesLayer.prototype.addToStage = function (stage) {
19258
19483
  stage.add(this._layer);
19484
+ stage.add(this._dragLayer);
19259
19485
  };
19260
19486
  SourcesLayer.prototype.enableEditing = function (enable) {
19261
19487
  this._allowEditing = enable;
@@ -19324,21 +19550,21 @@ module.exports = function (SourceGroup, LineGroups, DataRetriever, Invoker, Util
19324
19550
  self._removeSource(source);
19325
19551
  });
19326
19552
  this._view.updateTimelineLength();
19327
- this._layer.batchDraw();
19553
+ this.batchDraw();
19328
19554
  };
19329
19555
  SourcesLayer.prototype._onSourcesShow = function (sources) {
19330
19556
  var self = this;
19331
19557
  sources.forEach(function (source) {
19332
19558
  self._sourcesGroup[source.id].setWrapping(false, true);
19333
19559
  });
19334
- this._layer.batchDraw();
19560
+ this.batchDraw();
19335
19561
  };
19336
19562
  SourcesLayer.prototype._onSourcesHide = function (sources) {
19337
19563
  var self = this;
19338
19564
  sources.forEach(function (source) {
19339
19565
  self._sourcesGroup[source.id].setWrapping(true, true);
19340
19566
  });
19341
- this._layer.batchDraw();
19567
+ this.batchDraw();
19342
19568
  };
19343
19569
  SourcesLayer.prototype._onDataRetrieved = function (data, source, url) {
19344
19570
  if (data) {
@@ -19367,7 +19593,7 @@ module.exports = function (SourceGroup, LineGroups, DataRetriever, Invoker, Util
19367
19593
  SourcesLayer.prototype._onSegmentsShow = function (segmentsGroupId, lineId) {
19368
19594
  this._lineGroups.addSegments(segmentsGroupId, lineId);
19369
19595
  this._view.updateTimelineLength();
19370
- this._layer.batchDraw();
19596
+ this.batchDraw();
19371
19597
  };
19372
19598
  SourcesLayer.prototype._createSourceGroup = function (source) {
19373
19599
  return new SourceGroup(source, this._peaks, this, this._view);
@@ -19385,17 +19611,19 @@ module.exports = function (SourceGroup, LineGroups, DataRetriever, Invoker, Util
19385
19611
  var sourceGroup = this._sourcesGroup[source.id];
19386
19612
  if (sourceGroup) {
19387
19613
  sourceGroup.createIndicators();
19388
- this._layer.batchDraw();
19614
+ this.batchDraw();
19389
19615
  }
19390
19616
  };
19391
19617
  SourcesLayer.prototype.updateSources = function (startTime, endTime) {
19392
19618
  this._lineGroups.updateSegments(startTime, endTime);
19393
19619
  var sources = this.findSources(startTime, endTime);
19394
19620
  var count = sources.length;
19395
- sources.forEach(this._updateSource.bind(this));
19621
+ for (var i = 0; i < sources.length; i++) {
19622
+ this._updateSource(sources[i]);
19623
+ }
19396
19624
  count += this._removeInvisibleSources(startTime, endTime);
19397
19625
  if (count > 0) {
19398
- this._layer.batchDraw();
19626
+ this.batchDraw();
19399
19627
  }
19400
19628
  };
19401
19629
  SourcesLayer.prototype.onSourcesGroupDragStart = function (element) {
@@ -19422,22 +19650,104 @@ module.exports = function (SourceGroup, LineGroups, DataRetriever, Invoker, Util
19422
19650
  orderable: true,
19423
19651
  draggable: true
19424
19652
  });
19653
+ var self = this;
19654
+ this._dragGhosts = [];
19655
+ this._initialSourcePositions = {};
19656
+ this._draggedElements.forEach(function (source) {
19657
+ self._initialSourcePositions[source.id] = {
19658
+ startTime: source.startTime,
19659
+ endTime: source.endTime,
19660
+ lineId: source.lineId
19661
+ };
19662
+ var sourceGroup = self._sourcesGroup[source.id];
19663
+ if (sourceGroup) {
19664
+ sourceGroup.setDragging(true);
19665
+ var absoluteY = sourceGroup.getAbsoluteY();
19666
+ sourceGroup.moveTo(self._dragLayer);
19667
+ sourceGroup.y(absoluteY);
19668
+ var ghost = self._createDragGhost(sourceGroup);
19669
+ self._dragGhosts.push({
19670
+ ghost: ghost,
19671
+ sourceId: source.id
19672
+ });
19673
+ }
19674
+ });
19425
19675
  };
19426
19676
  SourcesLayer.prototype.onSourcesGroupDragEnd = function () {
19677
+ if (this._dragGhosts) {
19678
+ this._dragGhosts.forEach(function (item) {
19679
+ if (item.ghost) {
19680
+ item.ghost.destroy();
19681
+ }
19682
+ });
19683
+ this._dragGhosts = null;
19684
+ }
19685
+ this._initialSourcePositions = null;
19686
+ this._dragOffsetX = undefined;
19687
+ this._dragOffsetY = undefined;
19688
+ var self = this;
19427
19689
  const updatedSources = this._draggedElements.map(function (source) {
19428
- const sourceGroup = this._sourcesGroup[source.id];
19690
+ const sourceGroup = self._sourcesGroup[source.id];
19429
19691
  if (sourceGroup) {
19692
+ sourceGroup.setDragging(false);
19430
19693
  sourceGroup.prepareDragEnd();
19694
+ self._lineGroups.addSource(source, sourceGroup);
19695
+ sourceGroup.y(0);
19431
19696
  }
19432
19697
  return source;
19433
- }.bind(this));
19698
+ });
19434
19699
  this._draggedElementId = null;
19700
+ this.refresh();
19435
19701
  this._view.batchDrawSourcesLayer();
19436
19702
  this._view.updateTimelineLength();
19437
19703
  this._peaks.emit('sources.updated', updatedSources);
19438
19704
  };
19439
19705
  SourcesLayer.prototype.onSourcesGroupDrag = function (draggedElement) {
19706
+ var pointerPos = this._view.getPointerPosition();
19440
19707
  this._view.updateWithAutoScroll(this._dragSourcesGroup.bind(this));
19708
+ var clickedSourceGroup = this._sourcesGroup[this._draggedElementId];
19709
+ if (clickedSourceGroup) {
19710
+ var mouseX = pointerPos.x;
19711
+ var mouseY = pointerPos.y;
19712
+ var offsetX = this._dragOffsetX || 0;
19713
+ var offsetY = this._dragOffsetY || 0;
19714
+ if (this._dragOffsetX === undefined) {
19715
+ var currentPos = draggedElement.absolutePosition();
19716
+ this._dragOffsetX = currentPos.x - mouseX;
19717
+ this._dragOffsetY = currentPos.y - mouseY;
19718
+ offsetX = this._dragOffsetX;
19719
+ offsetY = this._dragOffsetY;
19720
+ }
19721
+ var clickedSourceX = mouseX + offsetX;
19722
+ var clickedSourceY = mouseY + offsetY;
19723
+ if (this._draggedElements && this._draggedElements.length > 1 && this._initialSourcePositions) {
19724
+ var self = this;
19725
+ var clickedInitialPos = this._initialSourcePositions[this._draggedElementId];
19726
+ if (clickedInitialPos) {
19727
+ var clickedInitialPixelX = this._view.timeToPixels(clickedInitialPos.startTime);
19728
+ this._draggedElements.forEach(function (source) {
19729
+ if (source.id !== self._draggedElementId) {
19730
+ var sourceGroup = self._sourcesGroup[source.id];
19731
+ if (sourceGroup) {
19732
+ var initialPos = self._initialSourcePositions[source.id];
19733
+ if (initialPos) {
19734
+ var initialPixelX = self._view.timeToPixels(initialPos.startTime);
19735
+ var pixelOffset = initialPixelX - clickedInitialPixelX;
19736
+ sourceGroup.absolutePosition({
19737
+ x: clickedSourceX + pixelOffset,
19738
+ y: clickedSourceY
19739
+ });
19740
+ }
19741
+ }
19742
+ }
19743
+ });
19744
+ }
19745
+ }
19746
+ return {
19747
+ x: clickedSourceX,
19748
+ y: clickedSourceY
19749
+ };
19750
+ }
19441
19751
  return {
19442
19752
  x: draggedElement.absolutePosition().x,
19443
19753
  y: draggedElement.absolutePosition().y
@@ -19453,9 +19763,13 @@ module.exports = function (SourceGroup, LineGroups, DataRetriever, Invoker, Util
19453
19763
  if (!draggable) {
19454
19764
  return;
19455
19765
  }
19456
- const shouldRedraw = this.manageSourceMovements(this._draggedElements, initialStartTime + timeOffsetDiff + timeDiff, initialEndTime + timeOffsetDiff + timeDiff, orderable, mousePosX, mousePosY);
19766
+ var newStartTime = Utils.roundTime(initialStartTime + timeOffsetDiff + timeDiff);
19767
+ var newEndTime = Utils.roundTime(initialEndTime + timeOffsetDiff + timeDiff);
19768
+ const shouldRedraw = this.manageSourceMovements(this._draggedElements, newStartTime, newEndTime, orderable, mousePosX, mousePosY);
19769
+ this._updateDragGhosts();
19457
19770
  if (shouldRedraw) {
19458
19771
  this.batchDraw();
19772
+ this._dragLayer.batchDraw();
19459
19773
  }
19460
19774
  };
19461
19775
  SourcesLayer.prototype.findSources = function (startTime, endTime) {
@@ -19465,15 +19779,101 @@ module.exports = function (SourceGroup, LineGroups, DataRetriever, Invoker, Util
19465
19779
  return lineIds[source.lineId];
19466
19780
  });
19467
19781
  };
19782
+ SourcesLayer.prototype._createDragGhost = function (sourceGroup) {
19783
+ var source = sourceGroup.getSource();
19784
+ var frameOffset = this._view.getFrameOffset();
19785
+ var x = this._view.timeToPixels(source.startTime) - frameOffset;
19786
+ var width = this._view.timeToPixels(source.endTime - source.startTime);
19787
+ var height = sourceGroup.getCurrentHeight();
19788
+ var y = sourceGroup.getAbsoluteY();
19789
+ var ghost = new Konva.Rect({
19790
+ x: x,
19791
+ y: y,
19792
+ width: width,
19793
+ height: height,
19794
+ fill: source.backgroundColor,
19795
+ opacity: 0.4,
19796
+ stroke: source.selectedBorderColor,
19797
+ strokeWidth: 2,
19798
+ dash: [
19799
+ 8,
19800
+ 4
19801
+ ],
19802
+ cornerRadius: 8,
19803
+ listening: false
19804
+ });
19805
+ this._layer.add(ghost);
19806
+ ghost.moveToBottom();
19807
+ return ghost;
19808
+ };
19809
+ SourcesLayer.prototype._updateDragGhosts = function () {
19810
+ if (!this._dragGhosts) {
19811
+ return;
19812
+ }
19813
+ var self = this;
19814
+ var frameOffset = this._view.getFrameOffset();
19815
+ var lineGroupsById = this._lineGroups.getLineGroupsById();
19816
+ this._dragGhosts.forEach(function (item) {
19817
+ var sourceGroup = self._sourcesGroup[item.sourceId];
19818
+ if (!sourceGroup || !item.ghost) {
19819
+ return;
19820
+ }
19821
+ var sourceData = sourceGroup.getSource();
19822
+ var x = self._view.timeToPixels(sourceData.startTime) - frameOffset;
19823
+ item.ghost.x(x);
19824
+ var lineGroup = lineGroupsById[sourceData.lineId];
19825
+ if (lineGroup) {
19826
+ item.ghost.y(lineGroup.y());
19827
+ }
19828
+ });
19829
+ };
19830
+ SourcesLayer.prototype._updateSourceTimesDuringDrag = function (newStartTime) {
19831
+ if (!this._initialSourcePositions || !this._draggedElements) {
19832
+ return;
19833
+ }
19834
+ var self = this;
19835
+ var firstSourceInitial = this._initialSourcePositions[this._draggedElements[0].id];
19836
+ if (!firstSourceInitial) {
19837
+ return;
19838
+ }
19839
+ var timeDiff = Utils.roundTime(newStartTime - firstSourceInitial.startTime);
19840
+ this._draggedElements.forEach(function (source) {
19841
+ var initialPos = self._initialSourcePositions[source.id];
19842
+ if (initialPos) {
19843
+ source.updateTimes(Utils.roundTime(initialPos.startTime + timeDiff), Utils.roundTime(initialPos.endTime + timeDiff));
19844
+ }
19845
+ });
19846
+ };
19468
19847
  SourcesLayer.prototype._applyTimeChangesToSources = function (sources, initialStartTime, newStartTime, newEndTime) {
19469
19848
  if (sources.length === 1) {
19470
19849
  sources[0].updateTimes(newStartTime, newEndTime);
19471
19850
  } else {
19472
- const timeDiff = Utils.roundTime(newStartTime - initialStartTime);
19473
- if (timeDiff !== 0) {
19474
- sources.forEach(function (source) {
19475
- source.updateTimes(Utils.roundTime(source.startTime + timeDiff), Utils.roundTime(source.endTime + timeDiff));
19476
- });
19851
+ var canUseInitialPositions = Boolean(this._initialSourcePositions && this._initialSourcePositions[sources[0].id]);
19852
+ if (canUseInitialPositions) {
19853
+ for (var i = 0; i < sources.length; i++) {
19854
+ if (!this._initialSourcePositions[sources[i].id]) {
19855
+ canUseInitialPositions = false;
19856
+ break;
19857
+ }
19858
+ }
19859
+ }
19860
+ if (canUseInitialPositions) {
19861
+ var firstInitial = this._initialSourcePositions[sources[0].id];
19862
+ var timeDiffFromInitial = Utils.roundTime(newStartTime - firstInitial.startTime);
19863
+ if (timeDiffFromInitial !== 0) {
19864
+ var self = this;
19865
+ sources.forEach(function (source) {
19866
+ var initialPos = self._initialSourcePositions[source.id];
19867
+ source.updateTimes(Utils.roundTime(initialPos.startTime + timeDiffFromInitial), Utils.roundTime(initialPos.endTime + timeDiffFromInitial));
19868
+ });
19869
+ }
19870
+ } else {
19871
+ const timeDiff = Utils.roundTime(newStartTime - initialStartTime);
19872
+ if (timeDiff !== 0) {
19873
+ sources.forEach(function (source) {
19874
+ source.updateTimes(Utils.roundTime(source.startTime + timeDiff), Utils.roundTime(source.endTime + timeDiff));
19875
+ });
19876
+ }
19477
19877
  }
19478
19878
  }
19479
19879
  this.refresh();
@@ -19507,8 +19907,26 @@ module.exports = function (SourceGroup, LineGroups, DataRetriever, Invoker, Util
19507
19907
  };
19508
19908
  SourcesLayer.prototype._findOrAddSourceGroup = function (source) {
19509
19909
  var sourceGroup = this._sourcesGroup[source.id];
19910
+ var isNewlyCreated = false;
19510
19911
  if (!sourceGroup) {
19511
19912
  sourceGroup = this._addSourceGroup(source);
19913
+ isNewlyCreated = true;
19914
+ }
19915
+ if (isNewlyCreated && this._draggedElements && this._initialSourcePositions) {
19916
+ var isDraggedSource = this._draggedElements.some(function (s) {
19917
+ return s.id === source.id;
19918
+ });
19919
+ if (isDraggedSource) {
19920
+ sourceGroup.setDragging(true);
19921
+ var absoluteY = sourceGroup.getAbsoluteY();
19922
+ sourceGroup.moveTo(this._dragLayer);
19923
+ sourceGroup.y(absoluteY);
19924
+ var ghost = this._createDragGhost(sourceGroup);
19925
+ this._dragGhosts.push({
19926
+ ghost: ghost,
19927
+ sourceId: source.id
19928
+ });
19929
+ }
19512
19930
  }
19513
19931
  return sourceGroup;
19514
19932
  };
@@ -19581,7 +19999,7 @@ module.exports = function (SourceGroup, LineGroups, DataRetriever, Invoker, Util
19581
19999
  this._layer.setVisible(visible);
19582
20000
  };
19583
20001
  SourcesLayer.prototype.batchDraw = function () {
19584
- this._layer.batchDraw();
20002
+ this._throttledBatchDraw();
19585
20003
  };
19586
20004
  SourcesLayer.prototype.listening = function (bool) {
19587
20005
  this._layer.listening(bool);
@@ -19600,18 +20018,27 @@ module.exports = function (SourceGroup, LineGroups, DataRetriever, Invoker, Util
19600
20018
  var startsEarlier = source1.startTime > source2.startTime && source1.startTime < source2.endTime;
19601
20019
  return endsLater || startsEarlier;
19602
20020
  };
19603
- SourcesLayer.prototype.rescale = function (debounce) {
19604
- if (debounce) {
19605
- this._debouncedRescale();
19606
- } else {
19607
- this._rescale();
19608
- }
20021
+ SourcesLayer.prototype.rescale = function () {
20022
+ this._rescaleVersion = (this._rescaleVersion || 0) + 1;
20023
+ this._rescale(this._rescaleVersion);
19609
20024
  };
19610
- SourcesLayer.prototype._rescale = function () {
19611
- var id, audioPreviews, urls = [], self = this;
19612
- for (id in this._sourcesGroup) {
19613
- if (Utils.objectHasProperty(this._sourcesGroup, id)) {
19614
- audioPreviews = this._sourcesGroup[id].getAudioPreview();
20025
+ SourcesLayer.prototype._rescale = function (version) {
20026
+ var self = this;
20027
+ var ids = Object.keys(this._sourcesGroup);
20028
+ var urls = [];
20029
+ var index = 0;
20030
+ function processNext() {
20031
+ if (self._rescaleVersion !== version) {
20032
+ return;
20033
+ }
20034
+ if (index >= ids.length) {
20035
+ self.batchDraw();
20036
+ return;
20037
+ }
20038
+ var id = ids[index];
20039
+ var sourceGroup = self._sourcesGroup[id];
20040
+ if (sourceGroup) {
20041
+ var audioPreviews = sourceGroup.getAudioPreview();
19615
20042
  audioPreviews.forEach(function (audioPreview) {
19616
20043
  if (self._shouldResampleAudio(audioPreview.url, urls)) {
19617
20044
  self._loadedData[audioPreview.url + '-scaled'] = {
@@ -19622,8 +20049,10 @@ module.exports = function (SourceGroup, LineGroups, DataRetriever, Invoker, Util
19622
20049
  }
19623
20050
  });
19624
20051
  }
20052
+ index++;
20053
+ Utils.scheduleIdle(processNext, { timeout: 16 });
19625
20054
  }
19626
- this._layer.batchDraw();
20055
+ processNext();
19627
20056
  };
19628
20057
  SourcesLayer.prototype._shouldResampleAudio = function (audioUrl, urls) {
19629
20058
  return this._loadedData[audioUrl + '-scaled'] && !urls.includes(audioUrl) && this._loadedData[audioUrl + '-scaled'].scale !== this._view.getTimeToPixelsScale();
@@ -19641,6 +20070,10 @@ module.exports = function (SourceGroup, LineGroups, DataRetriever, Invoker, Util
19641
20070
  this._peaks.off('handler.segments.show', this._onSegmentsShow);
19642
20071
  this._peaks.off('model.source.setIndicators', this.setIndicators);
19643
20072
  this._peaks.off('handler.view.mouseup', this._stopDrag);
20073
+ this._rescaleVersion++;
20074
+ if (this._invoker) {
20075
+ this._invoker.destroy();
20076
+ }
19644
20077
  };
19645
20078
  SourcesLayer.prototype.getHeight = function () {
19646
20079
  return this._layer.getHeight();
@@ -19690,15 +20123,13 @@ module.exports = function () {
19690
20123
  module.exports = function (WaveformData, Utils) {
19691
20124
  'use strict';
19692
20125
  var isXhr2 = 'withCredentials' in new XMLHttpRequest();
19693
- function scheduleIdle(fn) {
19694
- if (typeof window !== 'undefined' && window.requestIdleCallback) {
19695
- return window.requestIdleCallback(fn, { timeout: 80 });
19696
- }
19697
- return setTimeout(fn, 0);
19698
- }
20126
+ var waveformCache = Utils.createLRUCache(50);
19699
20127
  function WaveformBuilder(peaks) {
19700
20128
  this._peaks = peaks;
19701
20129
  }
20130
+ WaveformBuilder.clearCache = function () {
20131
+ waveformCache.clear();
20132
+ };
19702
20133
  WaveformBuilder.prototype.init = function (options, callback) {
19703
20134
  if (options.dataUri && (options.webAudio || options.audioContext) || options.waveformData && (options.webAudio || options.audioContext) || options.dataUri && options.waveformData) {
19704
20135
  callback(new TypeError('Peaks.init(): You may only pass one source (webAudio, dataUri, or waveformData) to render waveform data.'));
@@ -19752,6 +20183,14 @@ module.exports = function (WaveformData, Utils) {
19752
20183
  callback(new Error('Peaks.init(): Unable to determine a compatible dataUri format for this browser'));
19753
20184
  return;
19754
20185
  }
20186
+ var cacheKey = url + ':' + requestType;
20187
+ var cachedData = waveformCache.get(cacheKey);
20188
+ if (cachedData) {
20189
+ Utils.scheduleIdle(function () {
20190
+ callback(null, cachedData);
20191
+ });
20192
+ return;
20193
+ }
19755
20194
  var xhr = self._createXHR(url, requestType, options.withCredentials, function (event) {
19756
20195
  if (this.readyState !== 4) {
19757
20196
  return;
@@ -19760,13 +20199,14 @@ module.exports = function (WaveformData, Utils) {
19760
20199
  callback(new Error('Unable to fetch remote data. HTTP status ' + this.status));
19761
20200
  return;
19762
20201
  }
19763
- scheduleIdle(function () {
20202
+ Utils.scheduleIdle(function () {
19764
20203
  try {
19765
20204
  var waveformData = WaveformData.create(event.target.response);
19766
20205
  if (waveformData.channels !== 1 && waveformData.channels !== 2) {
19767
20206
  callback(new Error('Peaks.init(): Only mono or stereo waveforms are currently supported'));
19768
20207
  return;
19769
20208
  }
20209
+ waveformCache.set(cacheKey, waveformData);
19770
20210
  callback(null, waveformData);
19771
20211
  } catch (err) {
19772
20212
  callback(err);
@@ -19795,7 +20235,7 @@ module.exports = function (WaveformData, Utils) {
19795
20235
  callback(new Error('Peaks.init(): Unable to determine a compatible waveformData format'));
19796
20236
  return;
19797
20237
  }
19798
- scheduleIdle(function () {
20238
+ Utils.scheduleIdle(function () {
19799
20239
  try {
19800
20240
  var createdWaveformData = WaveformData.create(data);
19801
20241
  if (createdWaveformData.channels !== 1 && createdWaveformData.channels !== 2) {
@@ -22457,6 +22897,63 @@ module.exports = function (UUID) {
22457
22897
  var GG = G.toString(16).length === 1 ? '0' + G.toString(16) : G.toString(16);
22458
22898
  var BB = B.toString(16).length === 1 ? '0' + B.toString(16) : B.toString(16);
22459
22899
  return '#' + RR + GG + BB;
22900
+ },
22901
+ scheduleIdle: function (callback, options) {
22902
+ options = options || { timeout: 50 };
22903
+ if (typeof window !== 'undefined' && window.requestIdleCallback) {
22904
+ return window.requestIdleCallback(callback, options);
22905
+ }
22906
+ return setTimeout(function () {
22907
+ callback({
22908
+ didTimeout: true,
22909
+ timeRemaining: function () {
22910
+ return 0;
22911
+ }
22912
+ });
22913
+ }, 0);
22914
+ },
22915
+ cancelIdle: function (id) {
22916
+ if (typeof window !== 'undefined' && window.cancelIdleCallback) {
22917
+ window.cancelIdleCallback(id);
22918
+ } else {
22919
+ clearTimeout(id);
22920
+ }
22921
+ },
22922
+ createLRUCache: function (maxSize) {
22923
+ var cache = new Map();
22924
+ maxSize = maxSize || 100;
22925
+ return {
22926
+ get: function (key) {
22927
+ if (!cache.has(key)) {
22928
+ return undefined;
22929
+ }
22930
+ var value = cache.get(key);
22931
+ cache.delete(key);
22932
+ cache.set(key, value);
22933
+ return value;
22934
+ },
22935
+ set: function (key, value) {
22936
+ if (cache.has(key)) {
22937
+ cache.delete(key);
22938
+ } else if (cache.size >= maxSize) {
22939
+ var firstKey = cache.keys().next().value;
22940
+ cache.delete(firstKey);
22941
+ }
22942
+ cache.set(key, value);
22943
+ },
22944
+ has: function (key) {
22945
+ return cache.has(key);
22946
+ },
22947
+ delete: function (key) {
22948
+ return cache.delete(key);
22949
+ },
22950
+ clear: function () {
22951
+ cache.clear();
22952
+ },
22953
+ size: function () {
22954
+ return cache.size;
22955
+ }
22956
+ };
22460
22957
  }
22461
22958
  };
22462
22959
  }(_dereq_('uuid'));
@@ -22529,7 +23026,6 @@ module.exports = function (MouseDragHandler, PlayheadLayer, SourcesLayer, ModeLa
22529
23026
  width: self._width - self._peaks.options.lineIndicatorWidth,
22530
23027
  height: self._height
22531
23028
  });
22532
- self._tempGroup = new Konva.Group({ listening: false });
22533
23029
  self._width -= self._peaks.options.lineIndicatorWidth;
22534
23030
  self._axis = new Axis(self._peaks, self, {
22535
23031
  axisGridlineColor: this._options.axisGridlineColor,
@@ -22538,7 +23034,6 @@ module.exports = function (MouseDragHandler, PlayheadLayer, SourcesLayer, ModeLa
22538
23034
  self._axis.addBackToStage(self._stage);
22539
23035
  self._sourcesLayer = new SourcesLayer(peaks, self, true);
22540
23036
  self._sourcesLayer.addToStage(self._stage);
22541
- self._sourcesLayer.add(self._tempGroup);
22542
23037
  self._axis.addFrontToStage(self._stage);
22543
23038
  self._playheadLayer = new PlayheadLayer(peaks, self, self._sourcesLayer.getLineGroups(), self._options.showPlayheadTime);
22544
23039
  self._playheadLayer.addToStage(self._stage);
@@ -22644,7 +23139,7 @@ module.exports = function (MouseDragHandler, PlayheadLayer, SourcesLayer, ModeLa
22644
23139
  window.addEventListener('click', this._onWindowClick, false);
22645
23140
  }
22646
23141
  View.prototype._mouseUp = function () {
22647
- this.clearScrollingInterval();
23142
+ this.stopAutoScroll();
22648
23143
  this._peaks.emit('handler.view.mouseup');
22649
23144
  };
22650
23145
  View.prototype._onWindowClick = function (event) {
@@ -22655,49 +23150,67 @@ module.exports = function (MouseDragHandler, PlayheadLayer, SourcesLayer, ModeLa
22655
23150
  View.prototype.setClickable = function (clickable) {
22656
23151
  this._isClickable = clickable;
22657
23152
  };
22658
- View.prototype.getTempGroup = function () {
22659
- return this._tempGroup;
22660
- };
22661
23153
  View.prototype.getSelectedElements = function () {
22662
23154
  return Object.values(this._modeLayer.getSelectedElements());
22663
23155
  };
22664
- View.prototype.updateWithAutoScroll = function (updateInInterval, updateOutInterval) {
23156
+ View.prototype.updateWithAutoScroll = function (updateWhileScrolling, updateWhileNotScrolling) {
22665
23157
  var self = this;
22666
- var posX = this.getPointerPosition().x;
22667
- var threshold = Math.round(this._peaks.options.autoScrollThreshold * this.getWidth());
22668
- this._limited = 0;
22669
- if (posX < threshold) {
22670
- this._limited = Math.round(-30 * Math.min(1, (threshold - posX) / threshold));
22671
- } else if (posX > this.getWidth() - threshold) {
22672
- this._limited = Math.round(30 * Math.min(1, (posX - (this.getWidth() - threshold)) / threshold));
22673
- }
22674
- if (this._limited && self.getFrameOffset() > 0 || this._limited > 0) {
22675
- if (!this._scrollingInterval) {
22676
- this._scrollingInterval = setInterval(function () {
22677
- var newOffset = self.getFrameOffset() + self._limited;
23158
+ var pointer = this.getPointerPosition();
23159
+ var pointerX = pointer ? pointer.x : null;
23160
+ var viewWidth = this.getWidth();
23161
+ var thresholdPx = Math.round(this._peaks.options.autoScrollThreshold * viewWidth);
23162
+ var MAX_AUTO_SCROLL_PX_PER_FRAME = 30;
23163
+ var NOMINAL_FRAME_MS = 16.67;
23164
+ function getAutoScrollVelocity(pointerXValue) {
23165
+ if (typeof pointerXValue !== 'number' || thresholdPx <= 0) {
23166
+ return 0;
23167
+ }
23168
+ if (pointerXValue < thresholdPx) {
23169
+ return Math.round(-MAX_AUTO_SCROLL_PX_PER_FRAME * Math.min(1, (thresholdPx - pointerXValue) / thresholdPx));
23170
+ }
23171
+ if (pointerXValue > viewWidth - thresholdPx) {
23172
+ return Math.round(MAX_AUTO_SCROLL_PX_PER_FRAME * Math.min(1, (pointerXValue - (viewWidth - thresholdPx)) / thresholdPx));
23173
+ }
23174
+ return 0;
23175
+ }
23176
+ var velocityPxPerFrame = getAutoScrollVelocity(pointerX);
23177
+ var canScroll = velocityPxPerFrame > 0 || velocityPxPerFrame < 0 && self.getFrameOffset() > 0;
23178
+ this._limited = velocityPxPerFrame;
23179
+ if (velocityPxPerFrame !== 0 && canScroll) {
23180
+ if (!this._scrollingRafId) {
23181
+ var lastTime = performance.now();
23182
+ function scrollFrame(currentTime) {
23183
+ if (!self._scrollingRafId) {
23184
+ return;
23185
+ }
23186
+ var deltaTime = currentTime - lastTime;
23187
+ var scrollAmount = Math.round(self._limited * deltaTime / NOMINAL_FRAME_MS);
23188
+ lastTime = currentTime;
23189
+ var newOffset = self.getFrameOffset() + scrollAmount;
22678
23190
  if (newOffset < 0) {
22679
23191
  self.updateTimeline(0);
22680
- clearInterval(self._scrollingInterval);
22681
- self._scrollingInterval = null;
23192
+ self._scrollingRafId = null;
22682
23193
  } else {
22683
- self.updateTimeline(self.getFrameOffset() + self._limited);
23194
+ self.updateTimeline(newOffset);
23195
+ updateWhileScrolling();
23196
+ self._scrollingRafId = requestAnimationFrame(scrollFrame);
22684
23197
  }
22685
- updateInInterval();
22686
- }, 10);
23198
+ }
23199
+ self._scrollingRafId = requestAnimationFrame(scrollFrame);
22687
23200
  }
22688
23201
  } else {
22689
- this.clearScrollingInterval();
22690
- if (updateOutInterval) {
22691
- updateOutInterval();
23202
+ this.stopAutoScroll();
23203
+ if (updateWhileNotScrolling) {
23204
+ updateWhileNotScrolling();
22692
23205
  } else {
22693
- updateInInterval();
23206
+ updateWhileScrolling();
22694
23207
  }
22695
23208
  }
22696
23209
  };
22697
- View.prototype.clearScrollingInterval = function () {
22698
- if (this._scrollingInterval) {
22699
- clearInterval(this._scrollingInterval);
22700
- this._scrollingInterval = null;
23210
+ View.prototype.stopAutoScroll = function () {
23211
+ if (this._scrollingRafId) {
23212
+ cancelAnimationFrame(this._scrollingRafId);
23213
+ this._scrollingRafId = null;
22701
23214
  }
22702
23215
  };
22703
23216
  View.prototype.getCurrentMode = function () {
@@ -22891,7 +23404,7 @@ module.exports = function (MouseDragHandler, PlayheadLayer, SourcesLayer, ModeLa
22891
23404
  this.setFrameOffset(apexPixel - playheadOffsetPixels);
22892
23405
  this.overrideInteractions(true, true);
22893
23406
  this.updateTimeline(this._frameOffset);
22894
- this._sourcesLayer.rescale(true);
23407
+ this._sourcesLayer.rescale();
22895
23408
  this._playheadLayer.updatePlayheadTime(currentTime);
22896
23409
  this._peaks.emit('handler.view.updatezoom', newScale, prevScale);
22897
23410
  this.overrideInteractions(false, true);