@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/peaks.js CHANGED
@@ -14418,44 +14418,47 @@ WaveformData.createFromAudio = _dereq_("./lib/builders/webaudio");
14418
14418
  module.exports = WaveformData;
14419
14419
 
14420
14420
  },{"./lib/builders/webaudio":81,"./lib/core":83}],86:[function(_dereq_,module,exports){
14421
- module.exports = function (Utils, Konva) {
14421
+ module.exports = function (Utils, Invoker, Konva) {
14422
14422
  'use strict';
14423
14423
  var LEFT_PADDING = 4;
14424
14424
  function Axis(peaks, view, options) {
14425
14425
  this._view = view;
14426
+ this._invoker = new Invoker();
14426
14427
  var self = this;
14427
14428
  peaks.on('playhead.moved', this._onPlayheadMoved.bind(this));
14428
14429
  peaks.on('playhead.hidden', this._onPlayheadHidden.bind(this));
14429
- self._axisGridlineColor = options.axisGridlineColor;
14430
- self._axisLabelColor = options.axisLabelColor;
14431
- self._backLayer = new Konva.Layer({ listening: false });
14432
- self._frontLayer = new Konva.Layer({ listening: false });
14433
- self._axisShape = new Konva.Shape({
14430
+ this._axisGridlineColor = options.axisGridlineColor;
14431
+ this._axisLabelColor = options.axisLabelColor;
14432
+ this._backLayer = new Konva.Layer({ listening: false });
14433
+ this._frontLayer = new Konva.Layer({ listening: false });
14434
+ this._axisShape = new Konva.Shape({
14434
14435
  sceneFunc: function (context) {
14435
14436
  self.drawAxis(context, view);
14436
14437
  }
14437
14438
  });
14438
- self._backLayer.add(self._axisShape);
14439
- self._timesShape = new Konva.Shape({
14439
+ this._backLayer.add(this._axisShape);
14440
+ this._timesShape = new Konva.Shape({
14440
14441
  sceneFunc: function (context) {
14441
14442
  self.drawTimes(context, view);
14442
14443
  }
14443
14444
  });
14444
- self._frontLayer.add(self._timesShape);
14445
+ this._frontLayer.add(this._timesShape);
14446
+ this._throttledBackDraw = this._invoker.throttleTrailing(this._backLayer.batchDraw.bind(this._backLayer));
14447
+ this._throttledFrontDraw = this._invoker.throttleTrailing(this._frontLayer.batchDraw.bind(this._frontLayer));
14445
14448
  }
14446
14449
  Axis.prototype._onPlayheadMoved = function (playheadX, playheadWidth) {
14447
14450
  this._maskStart = playheadX + this._view.getFrameOffset();
14448
14451
  this._maskEnd = playheadX + this._view.getFrameOffset() + playheadWidth;
14449
- this._frontLayer.batchDraw();
14452
+ this._throttledFrontDraw();
14450
14453
  };
14451
14454
  Axis.prototype._onPlayheadHidden = function () {
14452
14455
  this._maskStart = null;
14453
14456
  this._maskEnd = null;
14454
- this._frontLayer.batchDraw();
14457
+ this._throttledFrontDraw();
14455
14458
  };
14456
14459
  Axis.prototype.batchDraw = function () {
14457
- this._backLayer.batchDraw();
14458
- this._frontLayer.batchDraw();
14460
+ this._throttledBackDraw();
14461
+ this._throttledFrontDraw();
14459
14462
  };
14460
14463
  Axis.prototype.addBackToStage = function (stage) {
14461
14464
  stage.add(this._backLayer);
@@ -14559,8 +14562,8 @@ module.exports = function (Utils, Konva) {
14559
14562
  return false;
14560
14563
  };
14561
14564
  return Axis;
14562
- }(_dereq_('../utils'), _dereq_('konva'));
14563
- },{"../utils":116,"konva":43}],87:[function(_dereq_,module,exports){
14565
+ }(_dereq_('../utils'), _dereq_('./invoker'), _dereq_('konva'));
14566
+ },{"../utils":116,"./invoker":90,"konva":43}],87:[function(_dereq_,module,exports){
14564
14567
  module.exports = function (Data, Utils) {
14565
14568
  'use strict';
14566
14569
  function DataRetriever(peaks) {
@@ -14760,8 +14763,17 @@ module.exports = function (Utils, Konva) {
14760
14763
  },{"../utils":116,"konva":43}],90:[function(_dereq_,module,exports){
14761
14764
  module.exports = function () {
14762
14765
  'use strict';
14766
+ var raf = typeof window !== 'undefined' && window.requestAnimationFrame || function (fn) {
14767
+ return setTimeout(fn, 16);
14768
+ };
14769
+ var caf = typeof window !== 'undefined' && window.cancelAnimationFrame || function (id) {
14770
+ clearTimeout(id);
14771
+ };
14763
14772
  function Invoker() {
14764
14773
  this._throttledFunc = {};
14774
+ this._rafThrottled = {};
14775
+ this._frameCallbacks = [];
14776
+ this._frameScheduled = false;
14765
14777
  }
14766
14778
  Invoker.prototype.throttle = function (id, func, wait) {
14767
14779
  var self = this;
@@ -14785,6 +14797,52 @@ module.exports = function () {
14785
14797
  }, wait);
14786
14798
  }
14787
14799
  };
14800
+ Invoker.prototype.throttleRAF = function (id, func) {
14801
+ var self = this;
14802
+ if (this._rafThrottled[id]) {
14803
+ this._rafThrottled[id].func = func;
14804
+ this._rafThrottled[id].pending = true;
14805
+ return;
14806
+ }
14807
+ this._rafThrottled[id] = {
14808
+ func: func,
14809
+ pending: true,
14810
+ rafId: null
14811
+ };
14812
+ function frame() {
14813
+ if (self._rafThrottled[id] && self._rafThrottled[id].pending) {
14814
+ self._rafThrottled[id].pending = false;
14815
+ self._rafThrottled[id].func();
14816
+ self._rafThrottled[id].rafId = raf(frame);
14817
+ } else if (self._rafThrottled[id]) {
14818
+ delete self._rafThrottled[id];
14819
+ }
14820
+ }
14821
+ this._rafThrottled[id].rafId = raf(frame);
14822
+ };
14823
+ Invoker.prototype.cancelThrottleRAF = function (id) {
14824
+ if (this._rafThrottled[id]) {
14825
+ if (this._rafThrottled[id].rafId) {
14826
+ caf(this._rafThrottled[id].rafId);
14827
+ }
14828
+ delete this._rafThrottled[id];
14829
+ }
14830
+ };
14831
+ Invoker.prototype.scheduleFrame = function (callback) {
14832
+ var self = this;
14833
+ this._frameCallbacks.push(callback);
14834
+ if (!this._frameScheduled) {
14835
+ this._frameScheduled = true;
14836
+ raf(function () {
14837
+ self._frameScheduled = false;
14838
+ var callbacks = self._frameCallbacks;
14839
+ self._frameCallbacks = [];
14840
+ for (var i = 0; i < callbacks.length; i++) {
14841
+ callbacks[i]();
14842
+ }
14843
+ });
14844
+ }
14845
+ };
14788
14846
  Invoker.prototype.debounce = function (func, wait, immediate) {
14789
14847
  var timeout;
14790
14848
  return function executedFunction() {
@@ -14804,6 +14862,96 @@ module.exports = function () {
14804
14862
  }
14805
14863
  };
14806
14864
  };
14865
+ Invoker.prototype.throttleLeading = function (func) {
14866
+ var scheduled = false;
14867
+ var savedArgs = null;
14868
+ var savedThis = null;
14869
+ return function throttled() {
14870
+ if (scheduled) {
14871
+ savedArgs = arguments;
14872
+ savedThis = this;
14873
+ return;
14874
+ }
14875
+ func.apply(this, arguments);
14876
+ scheduled = true;
14877
+ raf(function () {
14878
+ scheduled = false;
14879
+ if (savedArgs) {
14880
+ func.apply(savedThis, savedArgs);
14881
+ savedArgs = null;
14882
+ savedThis = null;
14883
+ }
14884
+ });
14885
+ };
14886
+ };
14887
+ Invoker.prototype.throttleTrailing = function (func) {
14888
+ var rafId = null;
14889
+ var savedArgs = null;
14890
+ var savedThis = null;
14891
+ return function throttled() {
14892
+ savedArgs = arguments;
14893
+ savedThis = this;
14894
+ if (rafId === null) {
14895
+ rafId = raf(function () {
14896
+ rafId = null;
14897
+ func.apply(savedThis, savedArgs);
14898
+ });
14899
+ }
14900
+ };
14901
+ };
14902
+ Invoker.prototype.createBatcher = function (processFn, options) {
14903
+ options = options || {};
14904
+ var maxWait = options.maxWait || 100;
14905
+ var items = [];
14906
+ var timeout = null;
14907
+ var lastFlush = 0;
14908
+ function flush() {
14909
+ if (items.length === 0) {
14910
+ return;
14911
+ }
14912
+ var batch = items;
14913
+ items = [];
14914
+ timeout = null;
14915
+ lastFlush = Date.now();
14916
+ processFn(batch);
14917
+ }
14918
+ return {
14919
+ add: function (item) {
14920
+ items.push(item);
14921
+ if (timeout === null) {
14922
+ var timeSinceLastFlush = Date.now() - lastFlush;
14923
+ if (timeSinceLastFlush >= maxWait) {
14924
+ raf(flush);
14925
+ } else {
14926
+ timeout = setTimeout(flush, Math.min(16, maxWait - timeSinceLastFlush));
14927
+ }
14928
+ }
14929
+ },
14930
+ flush: flush,
14931
+ size: function () {
14932
+ return items.length;
14933
+ }
14934
+ };
14935
+ };
14936
+ Invoker.prototype.destroy = function () {
14937
+ var id;
14938
+ for (id in this._throttledFunc) {
14939
+ if (Object.prototype.hasOwnProperty.call(this._throttledFunc, id)) {
14940
+ clearInterval(this._throttledFunc[id].timer);
14941
+ }
14942
+ }
14943
+ this._throttledFunc = {};
14944
+ for (id in this._rafThrottled) {
14945
+ if (Object.prototype.hasOwnProperty.call(this._rafThrottled, id)) {
14946
+ if (this._rafThrottled[id].rafId) {
14947
+ caf(this._rafThrottled[id].rafId);
14948
+ }
14949
+ }
14950
+ }
14951
+ this._rafThrottled = {};
14952
+ this._frameCallbacks = [];
14953
+ this._frameScheduled = false;
14954
+ };
14807
14955
  return Invoker;
14808
14956
  }();
14809
14957
  },{}],91:[function(_dereq_,module,exports){
@@ -14937,8 +15085,10 @@ module.exports = function (SourceGroup, Utils, Konva) {
14937
15085
  LineGroup.prototype.addSource = function (source, sourceGroup, sourcesAround) {
14938
15086
  if (sourceGroup) {
14939
15087
  this._sourcesGroup[source.id] = sourceGroup;
14940
- if (!sourceGroup.getParent() || !sourceGroup.isDescendantOf(this._group)) {
14941
- sourceGroup.moveTo(this._group);
15088
+ if (!sourceGroup.isActive()) {
15089
+ if (!sourceGroup.getParent() || !sourceGroup.isDescendantOf(this._group)) {
15090
+ sourceGroup.moveTo(this._group);
15091
+ }
14942
15092
  }
14943
15093
  }
14944
15094
  if (!this._sources[source.id]) {
@@ -15042,9 +15192,6 @@ module.exports = function (SourceGroup, Utils, Konva) {
15042
15192
  LineGroup.prototype.removeSourceGroup = function (source) {
15043
15193
  const sourceGroup = this._sourcesGroup[source.id];
15044
15194
  delete this._sourcesGroup[source.id];
15045
- if (sourceGroup) {
15046
- sourceGroup.hideButKeepFocus();
15047
- }
15048
15195
  return sourceGroup;
15049
15196
  };
15050
15197
  LineGroup.prototype.removeSource = function (source) {
@@ -15359,6 +15506,7 @@ module.exports = function (SegmentsGroup, LineGroup, LineIndicator, Utils) {
15359
15506
  this._areSegmentInteractionsAllowed = true;
15360
15507
  this._automaticallyCreatedLineId = null;
15361
15508
  this._automaticLineCreationPosition = null;
15509
+ this._automaticLineCreationMouseY = null;
15362
15510
  this._automaticLineCreationTimeout = null;
15363
15511
  this._segmentsGroups = {};
15364
15512
  this._segmentsGroupToLine = {};
@@ -15438,7 +15586,6 @@ module.exports = function (SegmentsGroup, LineGroup, LineIndicator, Utils) {
15438
15586
  };
15439
15587
  LineGroups.prototype._onLineHeightChanged = function () {
15440
15588
  this.refreshLineYs();
15441
- this._view.updateTimeline();
15442
15589
  };
15443
15590
  LineGroups.prototype._onSourcesWrappingChanged = function (sources) {
15444
15591
  sources.forEach(function (source) {
@@ -15544,9 +15691,10 @@ module.exports = function (SegmentsGroup, LineGroup, LineIndicator, Utils) {
15544
15691
  }
15545
15692
  this._automaticLineCreationTimeout = null;
15546
15693
  this._automaticLineCreationPosition = null;
15694
+ this._automaticLineCreationMouseY = null;
15547
15695
  this._automaticallyCreatedLineId = null;
15548
15696
  };
15549
- LineGroups.prototype.manageAutomaticLineCreation = function (newLinePosition, initialPosition, sources) {
15697
+ LineGroups.prototype.manageAutomaticLineCreation = function (newLinePosition, initialPosition, sources, mouseY) {
15550
15698
  if (!Utils.isNullOrUndefined(this._automaticallyCreatedLineId)) {
15551
15699
  return;
15552
15700
  } else if (!Utils.isNullOrUndefined(this._automaticLineCreationPosition) && this._automaticLineCreationPosition !== newLinePosition) {
@@ -15556,6 +15704,7 @@ module.exports = function (SegmentsGroup, LineGroup, LineIndicator, Utils) {
15556
15704
  return;
15557
15705
  }
15558
15706
  this._automaticLineCreationPosition = newLinePosition;
15707
+ this._automaticLineCreationMouseY = mouseY;
15559
15708
  this._automaticLineCreationTimeout = setTimeout(function () {
15560
15709
  this._automaticLineCreationTimeout = null;
15561
15710
  const currentLine = this._lineGroupsByPosition[initialPosition];
@@ -15586,6 +15735,7 @@ module.exports = function (SegmentsGroup, LineGroup, LineIndicator, Utils) {
15586
15735
  }
15587
15736
  this._automaticallyCreatedLineId = automaticallyCreatedLineGroup.getId();
15588
15737
  this._moveSourcesToPositionIfPossible(sources, newLinePosition);
15738
+ this._peaks.emit('sources.delayedLineChange', sources);
15589
15739
  }.bind(this), this._peaks.options.automaticLineCreationDelay);
15590
15740
  };
15591
15741
  LineGroups.prototype.manageVerticalPosition = function (sources, startTime, endTime, mouseX, mouseY) {
@@ -15599,7 +15749,7 @@ module.exports = function (SegmentsGroup, LineGroup, LineIndicator, Utils) {
15599
15749
  return;
15600
15750
  }
15601
15751
  if (linePos[0] !== linePos[1]) {
15602
- this.manageAutomaticLineCreation(linePos[0] + 1, position, sources);
15752
+ this.manageAutomaticLineCreation(linePos[0] + 1, position, sources, mouseY);
15603
15753
  } else {
15604
15754
  this.stopAutomaticLineCreation();
15605
15755
  const targetLineGroup = this._lineGroupsByPosition[linePos[0]];
@@ -15815,12 +15965,13 @@ module.exports = function (SegmentsGroup, LineGroup, LineIndicator, Utils) {
15815
15965
  return LineGroups;
15816
15966
  }(_dereq_('./segments-group'), _dereq_('./line-group'), _dereq_('./line-indicator'), _dereq_('../utils'));
15817
15967
  },{"../utils":116,"./line-group":91,"./line-indicator":93,"./segments-group":101}],93:[function(_dereq_,module,exports){
15818
- module.exports = function (Konva, SVGs, Utils) {
15968
+ module.exports = function (Konva, SVGs, Invoker, Utils) {
15819
15969
  'use strict';
15820
15970
  function LineIndicator(peaks, view, container) {
15821
15971
  this._peaks = peaks;
15822
15972
  this._view = view;
15823
15973
  this._container = container;
15974
+ this._invoker = new Invoker();
15824
15975
  this._width = this._peaks.options.lineIndicatorWidth;
15825
15976
  this._height = this._view.getHeight();
15826
15977
  this._sizes = {
@@ -15844,6 +15995,7 @@ module.exports = function (Konva, SVGs, Utils) {
15844
15995
  });
15845
15996
  this._layer = new Konva.Layer();
15846
15997
  this._stage.add(this._layer);
15998
+ this._throttledBatchDraw = this._invoker.throttleTrailing(this._layer.batchDraw.bind(this._layer));
15847
15999
  this._indicators = {};
15848
16000
  this._separatingLine = new Konva.Line({
15849
16001
  points: [
@@ -15857,7 +16009,7 @@ module.exports = function (Konva, SVGs, Utils) {
15857
16009
  listening: false
15858
16010
  });
15859
16011
  this._layer.add(this._separatingLine);
15860
- this._layer.batchDraw();
16012
+ this.batchDraw();
15861
16013
  this._isDragging = false;
15862
16014
  this._dragLineId = null;
15863
16015
  this._dragContainerRect = null;
@@ -16133,7 +16285,7 @@ module.exports = function (Konva, SVGs, Utils) {
16133
16285
  return anyChange;
16134
16286
  };
16135
16287
  LineIndicator.prototype.batchDraw = function () {
16136
- this._layer.batchDraw();
16288
+ this._throttledBatchDraw();
16137
16289
  };
16138
16290
  LineIndicator.prototype._onWindowMove = function (event) {
16139
16291
  if (!this._dragContainerRect) {
@@ -16163,8 +16315,8 @@ module.exports = function (Konva, SVGs, Utils) {
16163
16315
  this._stage.container().style.cursor = 'pointer';
16164
16316
  };
16165
16317
  return LineIndicator;
16166
- }(_dereq_('konva'), _dereq_('./svgs'), _dereq_('../utils'));
16167
- },{"../utils":116,"./svgs":104,"konva":43}],94:[function(_dereq_,module,exports){
16318
+ }(_dereq_('konva'), _dereq_('./svgs'), _dereq_('./invoker'), _dereq_('../utils'));
16319
+ },{"../utils":116,"./invoker":90,"./svgs":104,"konva":43}],94:[function(_dereq_,module,exports){
16168
16320
  module.exports = function (Konva) {
16169
16321
  'use strict';
16170
16322
  var RADIUS = 5;
@@ -16246,7 +16398,7 @@ module.exports = function (DefaultSegmentMarker, Utils, Konva) {
16246
16398
  };
16247
16399
  }(_dereq_('./default-segment-marker'), _dereq_('../utils'), _dereq_('konva'));
16248
16400
  },{"../utils":116,"./default-segment-marker":89,"konva":43}],96:[function(_dereq_,module,exports){
16249
- module.exports = function (SourceGroup, Source, Utils, Konva) {
16401
+ module.exports = function (SourceGroup, Invoker, Source, Utils, Konva) {
16250
16402
  'use strict';
16251
16403
  var TIME_X_OFFSET = 20;
16252
16404
  var TIME_Y_OFFSET = 10;
@@ -16256,9 +16408,11 @@ module.exports = function (SourceGroup, Source, Utils, Konva) {
16256
16408
  this._view = view;
16257
16409
  this._playheadLayer = playheadLayer;
16258
16410
  this._stage = stage;
16411
+ this._invoker = new Invoker();
16259
16412
  this._selectedElements = {};
16260
16413
  this._currentLine = null;
16261
16414
  this._layer = new Konva.Layer({ listening: this._mode !== 'default' });
16415
+ this._throttledBatchDraw = this._invoker.throttleTrailing(this._layer.batchDraw.bind(this._layer));
16262
16416
  this._prepareDefaultMode();
16263
16417
  this._onMouseClickInDefaultMode = this._onMouseClickInDefaultMode.bind(this);
16264
16418
  this._onKeyboardDelete = this._onKeyboardDelete.bind(this);
@@ -16270,6 +16424,9 @@ module.exports = function (SourceGroup, Source, Utils, Konva) {
16270
16424
  this.setMode(initialMode);
16271
16425
  this._peaks.on('handler.sources.destroy', this._onSourcesDestroy.bind(this));
16272
16426
  }
16427
+ ModeLayer.prototype.batchDraw = function () {
16428
+ this._throttledBatchDraw();
16429
+ };
16273
16430
  ModeLayer.prototype._onSourcesDestroy = function (sources) {
16274
16431
  const selectedElementsToDeselect = {};
16275
16432
  sources.forEach(function (source) {
@@ -16431,7 +16588,7 @@ module.exports = function (SourceGroup, Source, Utils, Konva) {
16431
16588
  };
16432
16589
  ModeLayer.prototype._onMouseEnterInCutMode = function () {
16433
16590
  this._cutGroup.visible(true);
16434
- this._layer.batchDraw();
16591
+ this.batchDraw();
16435
16592
  };
16436
16593
  ModeLayer.prototype._updateCursorTime = function (position) {
16437
16594
  var hoveredElement = this._view.getHoveredElement();
@@ -16503,11 +16660,11 @@ module.exports = function (SourceGroup, Source, Utils, Konva) {
16503
16660
  }
16504
16661
  this._updateCursorTime(cuttingPosition);
16505
16662
  this._updateCuttingLine(cuttingPosition);
16506
- this._layer.batchDraw();
16663
+ this.batchDraw();
16507
16664
  };
16508
16665
  ModeLayer.prototype._onMouseLeaveInCutMode = function () {
16509
16666
  this._cutGroup.visible(false);
16510
- this._layer.batchDraw();
16667
+ this.batchDraw();
16511
16668
  };
16512
16669
  ModeLayer.prototype._onMouseClickInCutMode = function () {
16513
16670
  var mousePosition = this._stage.getPointerPosition();
@@ -16532,14 +16689,32 @@ module.exports = function (SourceGroup, Source, Utils, Konva) {
16532
16689
  }
16533
16690
  cuttingPixel -= hoveredElement.x();
16534
16691
  this._cuttingLine.visible(false);
16535
- this._peaks.cutSource(hoveredElement.getSource(), this._view.pixelsToTime(cuttingPixel));
16536
16692
  this._view.setHoveredElement(null);
16693
+ this._peaks.cutSource(hoveredElement.getSource(), this._view.pixelsToTime(cuttingPixel));
16694
+ this._syncHoveredElementFromPointer();
16537
16695
  this._updateCursorTime(cuttingPosition);
16538
16696
  this._updateCuttingLine(cuttingPosition);
16539
- this._layer.batchDraw();
16697
+ this.batchDraw();
16540
16698
  }
16541
16699
  }
16542
16700
  };
16701
+ ModeLayer.prototype._syncHoveredElementFromPointer = function () {
16702
+ var pointerPos = this._stage.getPointerPosition();
16703
+ if (!pointerPos) {
16704
+ return;
16705
+ }
16706
+ var node = this._stage.getIntersection(pointerPos);
16707
+ while (node) {
16708
+ if (node.attrs && node.attrs.sourceId) {
16709
+ var sourceGroup = this._view.getSourceGroupById(node.attrs.sourceId);
16710
+ if (sourceGroup && !sourceGroup.isHovered()) {
16711
+ sourceGroup.startHover();
16712
+ }
16713
+ return;
16714
+ }
16715
+ node = node.getParent ? node.getParent() : null;
16716
+ }
16717
+ };
16543
16718
  ModeLayer.prototype.setMode = function (mode) {
16544
16719
  if (this._mode === mode) {
16545
16720
  return;
@@ -16593,15 +16768,15 @@ module.exports = function (SourceGroup, Source, Utils, Konva) {
16593
16768
  return;
16594
16769
  }
16595
16770
  this._mode = mode;
16596
- this._layer.batchDraw();
16771
+ this.batchDraw();
16597
16772
  this._view.batchDrawSourcesLayer();
16598
16773
  };
16599
16774
  ModeLayer.prototype.getCurrentMode = function () {
16600
16775
  return this._mode;
16601
16776
  };
16602
16777
  return ModeLayer;
16603
- }(_dereq_('./source-group'), _dereq_('../models/source'), _dereq_('../utils'), _dereq_('konva'));
16604
- },{"../models/source":112,"../utils":116,"./source-group":102,"konva":43}],97:[function(_dereq_,module,exports){
16778
+ }(_dereq_('./source-group'), _dereq_('./invoker'), _dereq_('../models/source'), _dereq_('../utils'), _dereq_('konva'));
16779
+ },{"../models/source":112,"../utils":116,"./invoker":90,"./source-group":102,"konva":43}],97:[function(_dereq_,module,exports){
16605
16780
  module.exports = function (Konva) {
16606
16781
  'use strict';
16607
16782
  function getMarkerObject(obj) {
@@ -16698,7 +16873,7 @@ module.exports = function (Konva) {
16698
16873
  return MouseDragHandler;
16699
16874
  }(_dereq_('konva'));
16700
16875
  },{"konva":43}],98:[function(_dereq_,module,exports){
16701
- module.exports = function (Utils, Konva) {
16876
+ module.exports = function (Utils, Invoker, Konva) {
16702
16877
  'use strict';
16703
16878
  var HANDLE_RADIUS = 10;
16704
16879
  function PlayheadLayer(peaks, view, lines, showTime) {
@@ -16711,6 +16886,8 @@ module.exports = function (Utils, Konva) {
16711
16886
  this._playheadTextColor = peaks.options.playheadTextColor;
16712
16887
  this._time = null;
16713
16888
  this._playheadLayer = new Konva.Layer();
16889
+ this._invoker = new Invoker();
16890
+ this._throttledBatchDraw = this._invoker.throttleTrailing(this._playheadLayer.batchDraw.bind(this._playheadLayer));
16714
16891
  this._activeSegments = {};
16715
16892
  this._activeSources = {};
16716
16893
  this._createPlayhead(this._playheadColor);
@@ -16833,9 +17010,12 @@ module.exports = function (Utils, Konva) {
16833
17010
  }
16834
17011
  this._time = time;
16835
17012
  if (pixelHasChanged || timeHasChanged) {
16836
- this._playheadLayer.batchDraw();
17013
+ this.batchDraw();
16837
17014
  }
16838
17015
  };
17016
+ PlayheadLayer.prototype.batchDraw = function () {
17017
+ this._throttledBatchDraw();
17018
+ };
16839
17019
  PlayheadLayer.prototype._updatePlayheadPixel = function (time) {
16840
17020
  const pixelIndex = this._view.timeToPixels(time);
16841
17021
  const frameOffset = this._view.timeToPixels(this._view.getTimeOffset());
@@ -16913,12 +17093,12 @@ module.exports = function (Utils, Konva) {
16913
17093
  }
16914
17094
  }
16915
17095
  if (updated) {
16916
- this._playheadLayer.batchDraw();
17096
+ this.batchDraw();
16917
17097
  }
16918
17098
  };
16919
17099
  return PlayheadLayer;
16920
- }(_dereq_('../utils'), _dereq_('konva'));
16921
- },{"../utils":116,"konva":43}],99:[function(_dereq_,module,exports){
17100
+ }(_dereq_('../utils'), _dereq_('./invoker'), _dereq_('konva'));
17101
+ },{"../utils":116,"./invoker":90,"konva":43}],99:[function(_dereq_,module,exports){
16922
17102
  module.exports = function (Konva) {
16923
17103
  'use strict';
16924
17104
  function SegmentMarker(options) {
@@ -17910,13 +18090,14 @@ module.exports = function (SegmentShape, Utils, Konva) {
17910
18090
  return SegmentsGroup;
17911
18091
  }(_dereq_('./segment-shape'), _dereq_('../utils'), _dereq_('konva'));
17912
18092
  },{"../utils":116,"./segment-shape":100,"konva":43}],102:[function(_dereq_,module,exports){
17913
- module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva) {
18093
+ module.exports = function (WaveformBuilder, WaveformShape, Loader, Invoker, Utils, Konva) {
17914
18094
  'use strict';
17915
18095
  var SPACING_BETWEEN_PREVIEW_AND_BORDER_RATIO = 0.15;
17916
18096
  var SPACING_BETWEEN_PREVIEWS = 1.5;
17917
18097
  var CORNER_RADIUS = 8;
17918
18098
  var INDICATOR_RADIUS = 4;
17919
- var PREVIEW_CREATE_CHUNK = 8;
18099
+ var PREVIEW_CREATE_CHUNK = 12;
18100
+ var sharedInvoker = new Invoker();
17920
18101
  function SourceGroup(source, peaks, layer, view) {
17921
18102
  this._source = source;
17922
18103
  this._peaks = peaks;
@@ -17924,7 +18105,6 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
17924
18105
  this._view = view;
17925
18106
  this._indicators = {};
17926
18107
  var self = this;
17927
- this._x = this._view.timeToPixels(source.startTime);
17928
18108
  this._width = this._view.timeToPixels(source.endTime - source.startTime);
17929
18109
  var heights = SourceGroup.getHeights(source, peaks);
17930
18110
  this._unwrappedHeight = heights.unwrapped;
@@ -17935,12 +18115,16 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
17935
18115
  this._selected = this._source.selected;
17936
18116
  this._hovered = false;
17937
18117
  this._isDragged = false;
18118
+ this._isHandleDragging = false;
17938
18119
  this._destroyed = false;
18120
+ this._dragGhost = null;
18121
+ this._drawScheduled = false;
17939
18122
  this._previewList = [];
17940
18123
  this._previewBuildQueue = new Set();
18124
+ this._pendingIdleCallbacks = new Set();
17941
18125
  this._markersGroup = this._createMarkers();
17942
18126
  this._group = new Konva.Group({
17943
- x: this._x,
18127
+ x: this._view.timeToPixels(source.startTime),
17944
18128
  sourceId: this._source.id,
17945
18129
  draggable: this._source.draggable,
17946
18130
  dragBoundFunc: function () {
@@ -17995,14 +18179,46 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
17995
18179
  if (!this._source.loading) {
17996
18180
  this._showButtons();
17997
18181
  }
17998
- this._batchDraw();
18182
+ this._scheduleBatchDraw();
17999
18183
  };
18000
18184
  SourceGroup.prototype._onHoverEnd = function () {
18001
18185
  this._hovered = false;
18002
18186
  this._manualHover = false;
18187
+ this._disableManualHoverTracking();
18003
18188
  this._view.setHoveredElement(null);
18004
18189
  this._hideButtons();
18005
- this._batchDraw();
18190
+ this._scheduleBatchDraw();
18191
+ };
18192
+ SourceGroup.prototype._enableManualHoverTracking = function () {
18193
+ if (this._manualHoverTrackingEnabled) {
18194
+ return;
18195
+ }
18196
+ if (!this._group || this._destroyed) {
18197
+ return;
18198
+ }
18199
+ var stage = this._group.getStage && this._group.getStage();
18200
+ if (!stage) {
18201
+ return;
18202
+ }
18203
+ this._manualHoverTrackingEnabled = true;
18204
+ this._manualHoverNamespace = '.manualHover.' + this._source.id;
18205
+ this._manualHoverMoveHandler = function () {
18206
+ this._manageManualHoverStop();
18207
+ }.bind(this);
18208
+ stage.on('mousemove' + this._manualHoverNamespace, this._manualHoverMoveHandler);
18209
+ stage.on('touchmove' + this._manualHoverNamespace, this._manualHoverMoveHandler);
18210
+ };
18211
+ SourceGroup.prototype._disableManualHoverTracking = function () {
18212
+ if (!this._manualHoverTrackingEnabled) {
18213
+ return;
18214
+ }
18215
+ var stage = this._group && this._group.getStage && this._group.getStage();
18216
+ if (stage && this._manualHoverNamespace) {
18217
+ stage.off(this._manualHoverNamespace);
18218
+ }
18219
+ this._manualHoverTrackingEnabled = false;
18220
+ this._manualHoverMoveHandler = null;
18221
+ this._manualHoverNamespace = null;
18006
18222
  };
18007
18223
  SourceGroup.prototype._onDragStart = function (element) {
18008
18224
  this._isDragged = true;
@@ -18030,7 +18246,7 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
18030
18246
  return this._hovered;
18031
18247
  };
18032
18248
  SourceGroup.prototype.isActive = function () {
18033
- return this._isDragged;
18249
+ return this._isDragged || this._isHandleDragging;
18034
18250
  };
18035
18251
  SourceGroup.prototype.addToContent = function (newChild) {
18036
18252
  if (this._source.wrapped) {
@@ -18045,15 +18261,17 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
18045
18261
  this._rightHandle.width(handleWidth);
18046
18262
  this._rightHandle.x(this._width - handleWidth);
18047
18263
  };
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;
18264
+ SourceGroup.prototype._onSourceGroupHandleDrag = function (draggedElement, leftHandle) {
18051
18265
  const {start, end} = this._initialTimes;
18052
18266
  this._view.updateWithAutoScroll(function () {
18267
+ var pointer = this._view.getPointerPosition();
18268
+ var pointerX = pointer ? pointer.x : this._mouseDownX;
18269
+ const diff = this._view.pixelsToTime(pointerX - this._mouseDownX);
18270
+ const timeOffsetDiff = this._view.getTimeOffset() - this._initialTimeOffset;
18053
18271
  if (this._layer.manageSourceMovements([this._source], leftHandle ? start + diff + timeOffsetDiff : null, leftHandle ? null : end + diff + timeOffsetDiff)) {
18054
18272
  this._layer.batchDraw();
18055
18273
  }
18056
- }.bind(this));
18274
+ }.bind(this), null, false);
18057
18275
  return {
18058
18276
  x: draggedElement.absolutePosition().x,
18059
18277
  y: draggedElement.absolutePosition().y
@@ -18064,8 +18282,9 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
18064
18282
  const endPixel = this._view.timeToPixels(this._source.endTime);
18065
18283
  const frameOffset = this._view.timeToPixels(this._view.getTimeOffset());
18066
18284
  const newTimeToPixelsScale = this._view.getTimeToPixelsScale();
18067
- this._group.x(startPixel - frameOffset);
18068
- this._x = startPixel;
18285
+ if (!this._isDragged) {
18286
+ this._group.x(startPixel - frameOffset);
18287
+ }
18069
18288
  const newWidth = endPixel - startPixel;
18070
18289
  if (newWidth !== this._width) {
18071
18290
  this._width = newWidth;
@@ -18087,6 +18306,10 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
18087
18306
  this._updateLoadingOverlay();
18088
18307
  this.updatePreviews();
18089
18308
  }
18309
+ if (this._isDragged) {
18310
+ this.createDragGhost();
18311
+ this.updateDragGhost();
18312
+ }
18090
18313
  };
18091
18314
  SourceGroup.prototype.setWrapping = function (wrap, forceCreate, notify) {
18092
18315
  if (wrap) {
@@ -18119,12 +18342,14 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
18119
18342
  start: this._source.startTime,
18120
18343
  end: this._source.endTime
18121
18344
  };
18122
- this._isDragged = true;
18345
+ this._isHandleDragging = true;
18123
18346
  this._hideButtons();
18124
18347
  };
18125
18348
  SourceGroup.prototype._onHandleDragEnd = function () {
18126
- this._isDragged = false;
18349
+ this._isHandleDragging = false;
18127
18350
  this._showButtons();
18351
+ this.update();
18352
+ this.prepareDragEnd();
18128
18353
  };
18129
18354
  SourceGroup.prototype._addHandles = function (forceCreate) {
18130
18355
  var self = this;
@@ -18136,12 +18361,18 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
18136
18361
  height: this._unwrappedHeight,
18137
18362
  visible: true,
18138
18363
  draggable: this._source.resizable,
18139
- dragBoundFunc: function (pos) {
18140
- return self._onSourceGroupHandleDrag(this, pos, true);
18364
+ dragBoundFunc: function () {
18365
+ return self._onSourceGroupHandleDrag(this, true);
18141
18366
  }
18142
18367
  });
18143
- this._leftHandle.on('dragstart', this._onHandleDragStart.bind(this));
18144
- this._leftHandle.on('dragend', this._onHandleDragEnd.bind(this));
18368
+ this._leftHandle.on('dragstart', function (event) {
18369
+ event.cancelBubble = true;
18370
+ self._onHandleDragStart(event);
18371
+ });
18372
+ this._leftHandle.on('dragend', function (event) {
18373
+ event.cancelBubble = true;
18374
+ self._onHandleDragEnd(event);
18375
+ });
18145
18376
  if (this._source.resizable) {
18146
18377
  this._leftHandle.on('mouseover', function () {
18147
18378
  self._cursor = 'ew-resize';
@@ -18158,12 +18389,18 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
18158
18389
  height: this._unwrappedHeight,
18159
18390
  visible: true,
18160
18391
  draggable: this._source.resizable,
18161
- dragBoundFunc: function (pos) {
18162
- return self._onSourceGroupHandleDrag(this, pos, false);
18392
+ dragBoundFunc: function () {
18393
+ return self._onSourceGroupHandleDrag(this, false);
18163
18394
  }
18164
18395
  });
18165
- this._rightHandle.on('dragstart', this._onHandleDragStart.bind(this));
18166
- this._rightHandle.on('dragend', this._onHandleDragEnd.bind(this));
18396
+ this._rightHandle.on('dragstart', function (event) {
18397
+ event.cancelBubble = true;
18398
+ self._onHandleDragStart(event);
18399
+ });
18400
+ this._rightHandle.on('dragend', function (event) {
18401
+ event.cancelBubble = true;
18402
+ self._onHandleDragEnd(event);
18403
+ });
18167
18404
  if (this._source.resizable) {
18168
18405
  this._rightHandle.on('mouseover', function () {
18169
18406
  self._cursor = 'ew-resize';
@@ -18206,8 +18443,9 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
18206
18443
  SourceGroup.prototype.drawSourceShape = function (ctx, shape, addBorderWidth, fill) {
18207
18444
  var offset = addBorderWidth ? this._borderWidth : 0;
18208
18445
  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()));
18446
+ var actualX = this._group.x() + this._view.getFrameOffset();
18447
+ var x = Math.max(0, this._view.getFrameOffset() - actualX - 2 * radius);
18448
+ var width = Math.min(this._width - x, this._view.getWidth() + 4 * radius - Math.max(0, actualX - this._view.getFrameOffset()));
18211
18449
  var xWidth = x + width;
18212
18450
  if (width > 0) {
18213
18451
  ctx.beginPath();
@@ -18395,9 +18633,6 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
18395
18633
  SourceGroup.prototype.getWidth = function () {
18396
18634
  return this._width;
18397
18635
  };
18398
- SourceGroup.prototype.getX = function () {
18399
- return this._x;
18400
- };
18401
18636
  SourceGroup.prototype.getAbsoluteY = function () {
18402
18637
  return this._group.absolutePosition().y;
18403
18638
  };
@@ -18413,16 +18648,31 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
18413
18648
  }
18414
18649
  return this._group.y(value);
18415
18650
  };
18651
+ SourceGroup.prototype.absolutePosition = function (value) {
18652
+ if (value) {
18653
+ return this._group.absolutePosition(value);
18654
+ }
18655
+ return this._group.absolutePosition();
18656
+ };
18416
18657
  SourceGroup.prototype.getSource = function () {
18417
18658
  return this._source;
18418
18659
  };
18419
18660
  SourceGroup.prototype.startHover = function () {
18420
18661
  this._manualHover = true;
18662
+ this._enableManualHoverTracking();
18421
18663
  this._group.fire('mouseenter', { evt: new MouseEvent('mouseenter') }, true);
18422
18664
  };
18423
18665
  SourceGroup.prototype.stopHover = function () {
18424
18666
  this._group.fire('mouseleave', { evt: new MouseEvent('mouseleave') }, true);
18425
18667
  };
18668
+ SourceGroup.prototype.setDragging = function (isDragging) {
18669
+ this._isDragged = isDragging;
18670
+ if (isDragging) {
18671
+ this.createDragGhost();
18672
+ } else {
18673
+ this.destroyDragGhost();
18674
+ }
18675
+ };
18426
18676
  SourceGroup.prototype.startDrag = function () {
18427
18677
  return this._group.startDrag();
18428
18678
  };
@@ -18432,12 +18682,12 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
18432
18682
  SourceGroup.prototype.moveTo = function (group) {
18433
18683
  this._group.moveTo(group);
18434
18684
  };
18685
+ SourceGroup.prototype.moveToTop = function () {
18686
+ this._group.moveToTop();
18687
+ };
18435
18688
  SourceGroup.prototype.isDescendantOf = function (group) {
18436
18689
  return group.isAncestorOf(this._group);
18437
18690
  };
18438
- SourceGroup.prototype.hideButKeepFocus = function () {
18439
- this._group.moveTo(this._view.getTempGroup());
18440
- };
18441
18691
  SourceGroup.prototype.getParent = function () {
18442
18692
  return this._group.getParent();
18443
18693
  };
@@ -18547,17 +18797,29 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
18547
18797
  }
18548
18798
  };
18549
18799
  SourceGroup.prototype._createAudioPreview = function (preview, redraw) {
18800
+ var url = preview.url;
18801
+ var scaledData = this._layer.getLoadedData(url + '-scaled');
18802
+ var currentScale = this._view.getTimeToPixelsScale();
18803
+ if (scaledData && scaledData.scale !== currentScale) {
18804
+ var originalData = this._layer.getLoadedData(url);
18805
+ if (originalData) {
18806
+ this._layer.setLoadedData(url + '-scaled', {
18807
+ data: originalData.resample({ scale: originalData.sample_rate / currentScale }),
18808
+ scale: currentScale
18809
+ });
18810
+ }
18811
+ }
18550
18812
  var waveform = new WaveformShape({
18551
18813
  layer: this._layer,
18552
18814
  view: this._view,
18553
18815
  source: this._source,
18554
18816
  height: preview.group.height(),
18555
- url: preview.url
18817
+ url: url
18556
18818
  });
18557
18819
  preview.group.add(waveform);
18558
18820
  this._addToUnwrap(preview.group);
18559
18821
  if (redraw) {
18560
- this._layer.rescale(true);
18822
+ this._scheduleBatchDraw();
18561
18823
  }
18562
18824
  this._previewList.push(preview);
18563
18825
  };
@@ -18631,6 +18893,19 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
18631
18893
  }
18632
18894
  });
18633
18895
  };
18896
+ SourceGroup.prototype._scheduleBatchDraw = function () {
18897
+ if (this._destroyed || this._drawScheduled) {
18898
+ return;
18899
+ }
18900
+ this._drawScheduled = true;
18901
+ var self = this;
18902
+ sharedInvoker.scheduleFrame(function () {
18903
+ self._drawScheduled = false;
18904
+ if (!self._destroyed) {
18905
+ self._batchDraw();
18906
+ }
18907
+ });
18908
+ };
18634
18909
  SourceGroup.prototype._batchDraw = function () {
18635
18910
  var layer = this._group && this._group.getLayer && this._group.getLayer();
18636
18911
  if (layer && typeof layer.batchDraw === 'function') {
@@ -18638,27 +18913,13 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
18638
18913
  }
18639
18914
  };
18640
18915
  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);
18916
+ var self = this;
18917
+ var id = Utils.scheduleIdle(function (deadline) {
18918
+ self._pendingIdleCallbacks.delete(id);
18919
+ fn(deadline);
18920
+ }, { timeout: 50 });
18921
+ this._pendingIdleCallbacks.add(id);
18922
+ return id;
18662
18923
  };
18663
18924
  SourceGroup.prototype._ensureImagePreviewCount = function (preview, targetCount, interImageSpacing) {
18664
18925
  var imageList = preview.group.getChildren();
@@ -18670,7 +18931,7 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
18670
18931
  imageList[j].visible(false);
18671
18932
  }
18672
18933
  if (currentCount >= targetCount || this._previewBuildQueue.has(preview)) {
18673
- this._batchDraw();
18934
+ this._scheduleBatchDraw();
18674
18935
  return;
18675
18936
  }
18676
18937
  this._previewBuildQueue.add(preview);
@@ -18692,7 +18953,7 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
18692
18953
  nextIndex += 1;
18693
18954
  added += 1;
18694
18955
  }
18695
- self._batchDraw();
18956
+ self._scheduleBatchDraw();
18696
18957
  if (nextIndex < targetCount) {
18697
18958
  self._scheduleIdle(buildChunk);
18698
18959
  } else {
@@ -18725,7 +18986,7 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
18725
18986
  }
18726
18987
  this._ensureImagePreviewCount(preview, targetCount, interImageSpacing);
18727
18988
  if (redraw) {
18728
- this._batchDraw();
18989
+ this._scheduleBatchDraw();
18729
18990
  }
18730
18991
  this._previewList.push(preview);
18731
18992
  };
@@ -18792,6 +19053,65 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
18792
19053
  SourceGroup.prototype.getCurrentHeight = function () {
18793
19054
  return this._height;
18794
19055
  };
19056
+ SourceGroup.prototype.createDragGhost = function () {
19057
+ if (this._dragGhost) {
19058
+ return this._dragGhost;
19059
+ }
19060
+ var frameOffset = this._view.getFrameOffset();
19061
+ var x = this._view.timeToPixels(this._source.startTime) - frameOffset;
19062
+ var width = this._view.timeToPixels(this._source.endTime - this._source.startTime);
19063
+ var height = this.getCurrentHeight();
19064
+ var y = this.getAbsoluteY();
19065
+ this._dragGhost = new Konva.Rect({
19066
+ x: x,
19067
+ y: y,
19068
+ width: width,
19069
+ height: height,
19070
+ fill: this._source.backgroundColor,
19071
+ opacity: 0.4,
19072
+ stroke: this._source.selectedBorderColor,
19073
+ strokeWidth: 2,
19074
+ dash: [
19075
+ 8,
19076
+ 4
19077
+ ],
19078
+ cornerRadius: 8,
19079
+ listening: false
19080
+ });
19081
+ this._layer.add(this._dragGhost);
19082
+ this._dragGhost.moveToBottom();
19083
+ this.updateDragGhost();
19084
+ return this._dragGhost;
19085
+ };
19086
+ SourceGroup.prototype.updateDragGhost = function (lineGroupsById) {
19087
+ if (!this._dragGhost) {
19088
+ return;
19089
+ }
19090
+ if (!lineGroupsById && this._layer && typeof this._layer.getLineGroups === 'function') {
19091
+ var lineGroups = this._layer.getLineGroups();
19092
+ if (lineGroups && typeof lineGroups.getLineGroupsById === 'function') {
19093
+ lineGroupsById = lineGroups.getLineGroupsById();
19094
+ }
19095
+ }
19096
+ var frameOffset = this._view.getFrameOffset();
19097
+ var x = this._view.timeToPixels(this._source.startTime) - frameOffset;
19098
+ var width = this._view.timeToPixels(this._source.endTime - this._source.startTime);
19099
+ this._dragGhost.x(x);
19100
+ this._dragGhost.width(width);
19101
+ this._dragGhost.height(this.getCurrentHeight());
19102
+ if (lineGroupsById) {
19103
+ var lineGroup = lineGroupsById[this._source.lineId];
19104
+ if (lineGroup) {
19105
+ this._dragGhost.y(lineGroup.y());
19106
+ }
19107
+ }
19108
+ };
19109
+ SourceGroup.prototype.destroyDragGhost = function () {
19110
+ if (this._dragGhost) {
19111
+ this._dragGhost.destroy();
19112
+ this._dragGhost = null;
19113
+ }
19114
+ };
18795
19115
  SourceGroup.prototype.getHeights = function () {
18796
19116
  return {
18797
19117
  unwrapped: this._unwrappedHeight,
@@ -19168,7 +19488,7 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
19168
19488
  volumeText.text((volume * 100).toFixed(0) + '%');
19169
19489
  self._source.volume = Math.max(self._source.volumeRange[0], Math.min(volume, self._source.volumeRange[1]));
19170
19490
  self._peaks.emit('source.volumeChanged', self._source);
19171
- self._batchDraw();
19491
+ self._scheduleBatchDraw();
19172
19492
  });
19173
19493
  volumeSliderGroup.on('dragend', function () {
19174
19494
  volumeText.visible(false);
@@ -19185,6 +19505,17 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
19185
19505
  return volumeGroup;
19186
19506
  };
19187
19507
  SourceGroup.prototype.destroy = function () {
19508
+ this.destroyDragGhost();
19509
+ this._disableManualHoverTracking();
19510
+ if (this._pendingIdleCallbacks) {
19511
+ this._pendingIdleCallbacks.forEach(function (id) {
19512
+ Utils.cancelIdle(id);
19513
+ });
19514
+ this._pendingIdleCallbacks.clear();
19515
+ }
19516
+ if (this._previewBuildQueue) {
19517
+ this._previewBuildQueue.clear();
19518
+ }
19188
19519
  if (this._buttonsAnimation) {
19189
19520
  this._buttonsAnimation.destroy();
19190
19521
  this._buttonsAnimation = null;
@@ -19207,8 +19538,8 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
19207
19538
  };
19208
19539
  };
19209
19540
  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){
19541
+ }(_dereq_('./waveform-builder'), _dereq_('./waveform-shape'), _dereq_('./loader'), _dereq_('./invoker'), _dereq_('../utils'), _dereq_('konva'));
19542
+ },{"../utils":116,"./invoker":90,"./loader":94,"./waveform-builder":105,"./waveform-shape":106,"konva":43}],103:[function(_dereq_,module,exports){
19212
19543
  module.exports = function (SourceGroup, LineGroups, DataRetriever, Invoker, Utils, Konva) {
19213
19544
  'use strict';
19214
19545
  function SourcesLayer(peaks, view, allowEditing) {
@@ -19220,8 +19551,13 @@ module.exports = function (SourceGroup, LineGroups, DataRetriever, Invoker, Util
19220
19551
  this._dataRetriever = new DataRetriever(peaks);
19221
19552
  this._lineGroups = new LineGroups(peaks, view, this);
19222
19553
  this._lineGroups.addToLayer(this);
19554
+ this._dragGroup = new Konva.Group({ listening: false });
19555
+ this._layer.add(this._dragGroup);
19223
19556
  this._loadedData = {};
19224
- this._debouncedRescale = new Invoker().debounce(this._rescale, 150);
19557
+ this._invoker = new Invoker();
19558
+ this._rescaleVersion = 0;
19559
+ this._throttledBatchDraw = this._invoker.throttleTrailing(this._layer.batchDraw.bind(this._layer));
19560
+ this._drawPending = false;
19225
19561
  this._peaks.on('handler.sources.add', this._onSourcesAdd.bind(this));
19226
19562
  this._peaks.on('handler.sources.destroy', this._onSourcesDestroy.bind(this));
19227
19563
  this._peaks.on('handler.sources.show', this._onSourcesShow.bind(this));
@@ -19232,7 +19568,13 @@ module.exports = function (SourceGroup, LineGroups, DataRetriever, Invoker, Util
19232
19568
  this._peaks.on('handler.segments.show', this._onSegmentsShow.bind(this));
19233
19569
  this._peaks.on('model.source.setIndicators', this.setIndicators.bind(this));
19234
19570
  this._peaks.on('handler.view.mouseup', this._stopDrag.bind(this));
19571
+ this._peaks.on('sources.delayedLineChange', this._onSourcesDelayedLineChanged.bind(this));
19235
19572
  }
19573
+ SourcesLayer.prototype._onSourcesDelayedLineChanged = function () {
19574
+ if (this._draggedElements && this._draggedElements.length > 0) {
19575
+ this._dragSourcesGroup();
19576
+ }
19577
+ };
19236
19578
  SourcesLayer.prototype._stopDrag = function () {
19237
19579
  const draggedSourceGroup = this._sourcesGroup[this._draggedElementId];
19238
19580
  if (draggedSourceGroup) {
@@ -19253,6 +19595,9 @@ module.exports = function (SourceGroup, LineGroups, DataRetriever, Invoker, Util
19253
19595
  };
19254
19596
  SourcesLayer.prototype.add = function (element) {
19255
19597
  this._layer.add(element);
19598
+ if (this._dragGroup) {
19599
+ this._dragGroup.moveToTop();
19600
+ }
19256
19601
  };
19257
19602
  SourcesLayer.prototype.addToStage = function (stage) {
19258
19603
  stage.add(this._layer);
@@ -19324,21 +19669,21 @@ module.exports = function (SourceGroup, LineGroups, DataRetriever, Invoker, Util
19324
19669
  self._removeSource(source);
19325
19670
  });
19326
19671
  this._view.updateTimelineLength();
19327
- this._layer.batchDraw();
19672
+ this.batchDraw();
19328
19673
  };
19329
19674
  SourcesLayer.prototype._onSourcesShow = function (sources) {
19330
19675
  var self = this;
19331
19676
  sources.forEach(function (source) {
19332
19677
  self._sourcesGroup[source.id].setWrapping(false, true);
19333
19678
  });
19334
- this._layer.batchDraw();
19679
+ this.batchDraw();
19335
19680
  };
19336
19681
  SourcesLayer.prototype._onSourcesHide = function (sources) {
19337
19682
  var self = this;
19338
19683
  sources.forEach(function (source) {
19339
19684
  self._sourcesGroup[source.id].setWrapping(true, true);
19340
19685
  });
19341
- this._layer.batchDraw();
19686
+ this.batchDraw();
19342
19687
  };
19343
19688
  SourcesLayer.prototype._onDataRetrieved = function (data, source, url) {
19344
19689
  if (data) {
@@ -19367,7 +19712,7 @@ module.exports = function (SourceGroup, LineGroups, DataRetriever, Invoker, Util
19367
19712
  SourcesLayer.prototype._onSegmentsShow = function (segmentsGroupId, lineId) {
19368
19713
  this._lineGroups.addSegments(segmentsGroupId, lineId);
19369
19714
  this._view.updateTimelineLength();
19370
- this._layer.batchDraw();
19715
+ this.batchDraw();
19371
19716
  };
19372
19717
  SourcesLayer.prototype._createSourceGroup = function (source) {
19373
19718
  return new SourceGroup(source, this._peaks, this, this._view);
@@ -19385,17 +19730,19 @@ module.exports = function (SourceGroup, LineGroups, DataRetriever, Invoker, Util
19385
19730
  var sourceGroup = this._sourcesGroup[source.id];
19386
19731
  if (sourceGroup) {
19387
19732
  sourceGroup.createIndicators();
19388
- this._layer.batchDraw();
19733
+ this.batchDraw();
19389
19734
  }
19390
19735
  };
19391
19736
  SourcesLayer.prototype.updateSources = function (startTime, endTime) {
19392
19737
  this._lineGroups.updateSegments(startTime, endTime);
19393
19738
  var sources = this.findSources(startTime, endTime);
19394
19739
  var count = sources.length;
19395
- sources.forEach(this._updateSource.bind(this));
19740
+ for (var i = 0; i < sources.length; i++) {
19741
+ this._updateSource(sources[i]);
19742
+ }
19396
19743
  count += this._removeInvisibleSources(startTime, endTime);
19397
19744
  if (count > 0) {
19398
- this._layer.batchDraw();
19745
+ this.batchDraw();
19399
19746
  }
19400
19747
  };
19401
19748
  SourcesLayer.prototype.onSourcesGroupDragStart = function (element) {
@@ -19422,22 +19769,90 @@ module.exports = function (SourceGroup, LineGroups, DataRetriever, Invoker, Util
19422
19769
  orderable: true,
19423
19770
  draggable: true
19424
19771
  });
19772
+ var self = this;
19773
+ this._initialSourcePositions = {};
19774
+ this._draggedElements.forEach(function (source) {
19775
+ self._initialSourcePositions[source.id] = {
19776
+ startTime: source.startTime,
19777
+ endTime: source.endTime,
19778
+ lineId: source.lineId
19779
+ };
19780
+ var sourceGroup = self._sourcesGroup[source.id];
19781
+ if (sourceGroup) {
19782
+ sourceGroup.setDragging(true);
19783
+ var absoluteY = sourceGroup.getAbsoluteY();
19784
+ sourceGroup.moveTo(self._dragGroup);
19785
+ sourceGroup.y(absoluteY);
19786
+ }
19787
+ });
19425
19788
  };
19426
19789
  SourcesLayer.prototype.onSourcesGroupDragEnd = function () {
19790
+ var self = this;
19791
+ this._initialSourcePositions = null;
19792
+ this._dragOffsetX = undefined;
19793
+ this._dragOffsetY = undefined;
19427
19794
  const updatedSources = this._draggedElements.map(function (source) {
19428
- const sourceGroup = this._sourcesGroup[source.id];
19795
+ const sourceGroup = self._sourcesGroup[source.id];
19429
19796
  if (sourceGroup) {
19797
+ sourceGroup.setDragging(false);
19430
19798
  sourceGroup.prepareDragEnd();
19799
+ self._lineGroups.addSource(source, sourceGroup);
19800
+ sourceGroup.y(0);
19431
19801
  }
19432
19802
  return source;
19433
- }.bind(this));
19803
+ });
19434
19804
  this._draggedElementId = null;
19805
+ this.refresh();
19435
19806
  this._view.batchDrawSourcesLayer();
19436
19807
  this._view.updateTimelineLength();
19437
19808
  this._peaks.emit('sources.updated', updatedSources);
19438
19809
  };
19439
19810
  SourcesLayer.prototype.onSourcesGroupDrag = function (draggedElement) {
19440
- this._view.updateWithAutoScroll(this._dragSourcesGroup.bind(this));
19811
+ var pointerPos = this._view.getPointerPosition();
19812
+ this._view.updateWithAutoScroll(this._dragSourcesGroup.bind(this), null, true);
19813
+ var clickedSourceGroup = this._sourcesGroup[this._draggedElementId];
19814
+ if (clickedSourceGroup) {
19815
+ var mouseX = pointerPos.x;
19816
+ var mouseY = pointerPos.y;
19817
+ var offsetX = this._dragOffsetX || 0;
19818
+ var offsetY = this._dragOffsetY || 0;
19819
+ if (this._dragOffsetX === undefined) {
19820
+ var currentPos = draggedElement.absolutePosition();
19821
+ this._dragOffsetX = currentPos.x - mouseX;
19822
+ this._dragOffsetY = currentPos.y - mouseY;
19823
+ offsetX = this._dragOffsetX;
19824
+ offsetY = this._dragOffsetY;
19825
+ }
19826
+ var clickedSourceX = mouseX + offsetX;
19827
+ var clickedSourceY = mouseY + offsetY;
19828
+ if (this._draggedElements && this._draggedElements.length > 1 && this._initialSourcePositions) {
19829
+ var self = this;
19830
+ var clickedInitialPos = this._initialSourcePositions[this._draggedElementId];
19831
+ if (clickedInitialPos) {
19832
+ var clickedInitialPixelX = this._view.timeToPixels(clickedInitialPos.startTime);
19833
+ this._draggedElements.forEach(function (source) {
19834
+ if (source.id !== self._draggedElementId) {
19835
+ var sourceGroup = self._sourcesGroup[source.id];
19836
+ if (sourceGroup) {
19837
+ var initialPos = self._initialSourcePositions[source.id];
19838
+ if (initialPos) {
19839
+ var initialPixelX = self._view.timeToPixels(initialPos.startTime);
19840
+ var pixelOffset = initialPixelX - clickedInitialPixelX;
19841
+ sourceGroup.absolutePosition({
19842
+ x: clickedSourceX + pixelOffset,
19843
+ y: clickedSourceY
19844
+ });
19845
+ }
19846
+ }
19847
+ }
19848
+ });
19849
+ }
19850
+ }
19851
+ return {
19852
+ x: clickedSourceX,
19853
+ y: clickedSourceY
19854
+ };
19855
+ }
19441
19856
  return {
19442
19857
  x: draggedElement.absolutePosition().x,
19443
19858
  y: draggedElement.absolutePosition().y
@@ -19453,7 +19868,9 @@ module.exports = function (SourceGroup, LineGroups, DataRetriever, Invoker, Util
19453
19868
  if (!draggable) {
19454
19869
  return;
19455
19870
  }
19456
- const shouldRedraw = this.manageSourceMovements(this._draggedElements, initialStartTime + timeOffsetDiff + timeDiff, initialEndTime + timeOffsetDiff + timeDiff, orderable, mousePosX, mousePosY);
19871
+ var newStartTime = Utils.roundTime(initialStartTime + timeOffsetDiff + timeDiff);
19872
+ var newEndTime = Utils.roundTime(initialEndTime + timeOffsetDiff + timeDiff);
19873
+ const shouldRedraw = this.manageSourceMovements(this._draggedElements, newStartTime, newEndTime, orderable, mousePosX, mousePosY);
19457
19874
  if (shouldRedraw) {
19458
19875
  this.batchDraw();
19459
19876
  }
@@ -19465,15 +19882,53 @@ module.exports = function (SourceGroup, LineGroups, DataRetriever, Invoker, Util
19465
19882
  return lineIds[source.lineId];
19466
19883
  });
19467
19884
  };
19885
+ SourcesLayer.prototype._updateSourceTimesDuringDrag = function (newStartTime) {
19886
+ if (!this._initialSourcePositions || !this._draggedElements) {
19887
+ return;
19888
+ }
19889
+ var self = this;
19890
+ var firstSourceInitial = this._initialSourcePositions[this._draggedElements[0].id];
19891
+ if (!firstSourceInitial) {
19892
+ return;
19893
+ }
19894
+ var timeDiff = Utils.roundTime(newStartTime - firstSourceInitial.startTime);
19895
+ this._draggedElements.forEach(function (source) {
19896
+ var initialPos = self._initialSourcePositions[source.id];
19897
+ if (initialPos) {
19898
+ source.updateTimes(Utils.roundTime(initialPos.startTime + timeDiff), Utils.roundTime(initialPos.endTime + timeDiff));
19899
+ }
19900
+ });
19901
+ };
19468
19902
  SourcesLayer.prototype._applyTimeChangesToSources = function (sources, initialStartTime, newStartTime, newEndTime) {
19469
19903
  if (sources.length === 1) {
19470
19904
  sources[0].updateTimes(newStartTime, newEndTime);
19471
19905
  } 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
- });
19906
+ var canUseInitialPositions = Boolean(this._initialSourcePositions && this._initialSourcePositions[sources[0].id]);
19907
+ if (canUseInitialPositions) {
19908
+ for (var i = 0; i < sources.length; i++) {
19909
+ if (!this._initialSourcePositions[sources[i].id]) {
19910
+ canUseInitialPositions = false;
19911
+ break;
19912
+ }
19913
+ }
19914
+ }
19915
+ if (canUseInitialPositions) {
19916
+ var firstInitial = this._initialSourcePositions[sources[0].id];
19917
+ var timeDiffFromInitial = Utils.roundTime(newStartTime - firstInitial.startTime);
19918
+ if (timeDiffFromInitial !== 0) {
19919
+ var self = this;
19920
+ sources.forEach(function (source) {
19921
+ var initialPos = self._initialSourcePositions[source.id];
19922
+ source.updateTimes(Utils.roundTime(initialPos.startTime + timeDiffFromInitial), Utils.roundTime(initialPos.endTime + timeDiffFromInitial));
19923
+ });
19924
+ }
19925
+ } else {
19926
+ const timeDiff = Utils.roundTime(newStartTime - initialStartTime);
19927
+ if (timeDiff !== 0) {
19928
+ sources.forEach(function (source) {
19929
+ source.updateTimes(Utils.roundTime(source.startTime + timeDiff), Utils.roundTime(source.endTime + timeDiff));
19930
+ });
19931
+ }
19477
19932
  }
19478
19933
  }
19479
19934
  this.refresh();
@@ -19507,8 +19962,21 @@ module.exports = function (SourceGroup, LineGroups, DataRetriever, Invoker, Util
19507
19962
  };
19508
19963
  SourcesLayer.prototype._findOrAddSourceGroup = function (source) {
19509
19964
  var sourceGroup = this._sourcesGroup[source.id];
19965
+ var isNewlyCreated = false;
19510
19966
  if (!sourceGroup) {
19511
19967
  sourceGroup = this._addSourceGroup(source);
19968
+ isNewlyCreated = true;
19969
+ }
19970
+ if (isNewlyCreated && this._draggedElements && this._initialSourcePositions) {
19971
+ var isDraggedSource = this._draggedElements.some(function (s) {
19972
+ return s.id === source.id;
19973
+ });
19974
+ if (isDraggedSource) {
19975
+ sourceGroup.setDragging(true);
19976
+ var absoluteY = sourceGroup.getAbsoluteY();
19977
+ sourceGroup.moveTo(this._dragGroup);
19978
+ sourceGroup.y(absoluteY);
19979
+ }
19512
19980
  }
19513
19981
  return sourceGroup;
19514
19982
  };
@@ -19581,7 +20049,7 @@ module.exports = function (SourceGroup, LineGroups, DataRetriever, Invoker, Util
19581
20049
  this._layer.setVisible(visible);
19582
20050
  };
19583
20051
  SourcesLayer.prototype.batchDraw = function () {
19584
- this._layer.batchDraw();
20052
+ this._throttledBatchDraw();
19585
20053
  };
19586
20054
  SourcesLayer.prototype.listening = function (bool) {
19587
20055
  this._layer.listening(bool);
@@ -19600,18 +20068,27 @@ module.exports = function (SourceGroup, LineGroups, DataRetriever, Invoker, Util
19600
20068
  var startsEarlier = source1.startTime > source2.startTime && source1.startTime < source2.endTime;
19601
20069
  return endsLater || startsEarlier;
19602
20070
  };
19603
- SourcesLayer.prototype.rescale = function (debounce) {
19604
- if (debounce) {
19605
- this._debouncedRescale();
19606
- } else {
19607
- this._rescale();
19608
- }
20071
+ SourcesLayer.prototype.rescale = function () {
20072
+ this._rescaleVersion = (this._rescaleVersion || 0) + 1;
20073
+ this._rescale(this._rescaleVersion);
19609
20074
  };
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();
20075
+ SourcesLayer.prototype._rescale = function (version) {
20076
+ var self = this;
20077
+ var ids = Object.keys(this._sourcesGroup);
20078
+ var urls = [];
20079
+ var index = 0;
20080
+ function processNext() {
20081
+ if (self._rescaleVersion !== version) {
20082
+ return;
20083
+ }
20084
+ if (index >= ids.length) {
20085
+ self.batchDraw();
20086
+ return;
20087
+ }
20088
+ var id = ids[index];
20089
+ var sourceGroup = self._sourcesGroup[id];
20090
+ if (sourceGroup) {
20091
+ var audioPreviews = sourceGroup.getAudioPreview();
19615
20092
  audioPreviews.forEach(function (audioPreview) {
19616
20093
  if (self._shouldResampleAudio(audioPreview.url, urls)) {
19617
20094
  self._loadedData[audioPreview.url + '-scaled'] = {
@@ -19622,8 +20099,10 @@ module.exports = function (SourceGroup, LineGroups, DataRetriever, Invoker, Util
19622
20099
  }
19623
20100
  });
19624
20101
  }
20102
+ index++;
20103
+ Utils.scheduleIdle(processNext, { timeout: 16 });
19625
20104
  }
19626
- this._layer.batchDraw();
20105
+ processNext();
19627
20106
  };
19628
20107
  SourcesLayer.prototype._shouldResampleAudio = function (audioUrl, urls) {
19629
20108
  return this._loadedData[audioUrl + '-scaled'] && !urls.includes(audioUrl) && this._loadedData[audioUrl + '-scaled'].scale !== this._view.getTimeToPixelsScale();
@@ -19641,6 +20120,10 @@ module.exports = function (SourceGroup, LineGroups, DataRetriever, Invoker, Util
19641
20120
  this._peaks.off('handler.segments.show', this._onSegmentsShow);
19642
20121
  this._peaks.off('model.source.setIndicators', this.setIndicators);
19643
20122
  this._peaks.off('handler.view.mouseup', this._stopDrag);
20123
+ this._rescaleVersion++;
20124
+ if (this._invoker) {
20125
+ this._invoker.destroy();
20126
+ }
19644
20127
  };
19645
20128
  SourcesLayer.prototype.getHeight = function () {
19646
20129
  return this._layer.getHeight();
@@ -19690,15 +20173,13 @@ module.exports = function () {
19690
20173
  module.exports = function (WaveformData, Utils) {
19691
20174
  'use strict';
19692
20175
  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
- }
20176
+ var waveformCache = Utils.createLRUCache(50);
19699
20177
  function WaveformBuilder(peaks) {
19700
20178
  this._peaks = peaks;
19701
20179
  }
20180
+ WaveformBuilder.clearCache = function () {
20181
+ waveformCache.clear();
20182
+ };
19702
20183
  WaveformBuilder.prototype.init = function (options, callback) {
19703
20184
  if (options.dataUri && (options.webAudio || options.audioContext) || options.waveformData && (options.webAudio || options.audioContext) || options.dataUri && options.waveformData) {
19704
20185
  callback(new TypeError('Peaks.init(): You may only pass one source (webAudio, dataUri, or waveformData) to render waveform data.'));
@@ -19752,6 +20233,14 @@ module.exports = function (WaveformData, Utils) {
19752
20233
  callback(new Error('Peaks.init(): Unable to determine a compatible dataUri format for this browser'));
19753
20234
  return;
19754
20235
  }
20236
+ var cacheKey = url + ':' + requestType;
20237
+ var cachedData = waveformCache.get(cacheKey);
20238
+ if (cachedData) {
20239
+ Utils.scheduleIdle(function () {
20240
+ callback(null, cachedData);
20241
+ });
20242
+ return;
20243
+ }
19755
20244
  var xhr = self._createXHR(url, requestType, options.withCredentials, function (event) {
19756
20245
  if (this.readyState !== 4) {
19757
20246
  return;
@@ -19760,13 +20249,14 @@ module.exports = function (WaveformData, Utils) {
19760
20249
  callback(new Error('Unable to fetch remote data. HTTP status ' + this.status));
19761
20250
  return;
19762
20251
  }
19763
- scheduleIdle(function () {
20252
+ Utils.scheduleIdle(function () {
19764
20253
  try {
19765
20254
  var waveformData = WaveformData.create(event.target.response);
19766
20255
  if (waveformData.channels !== 1 && waveformData.channels !== 2) {
19767
20256
  callback(new Error('Peaks.init(): Only mono or stereo waveforms are currently supported'));
19768
20257
  return;
19769
20258
  }
20259
+ waveformCache.set(cacheKey, waveformData);
19770
20260
  callback(null, waveformData);
19771
20261
  } catch (err) {
19772
20262
  callback(err);
@@ -19795,7 +20285,7 @@ module.exports = function (WaveformData, Utils) {
19795
20285
  callback(new Error('Peaks.init(): Unable to determine a compatible waveformData format'));
19796
20286
  return;
19797
20287
  }
19798
- scheduleIdle(function () {
20288
+ Utils.scheduleIdle(function () {
19799
20289
  try {
19800
20290
  var createdWaveformData = WaveformData.create(data);
19801
20291
  if (createdWaveformData.channels !== 1 && createdWaveformData.channels !== 2) {
@@ -22457,6 +22947,63 @@ module.exports = function (UUID) {
22457
22947
  var GG = G.toString(16).length === 1 ? '0' + G.toString(16) : G.toString(16);
22458
22948
  var BB = B.toString(16).length === 1 ? '0' + B.toString(16) : B.toString(16);
22459
22949
  return '#' + RR + GG + BB;
22950
+ },
22951
+ scheduleIdle: function (callback, options) {
22952
+ options = options || { timeout: 50 };
22953
+ if (typeof window !== 'undefined' && window.requestIdleCallback) {
22954
+ return window.requestIdleCallback(callback, options);
22955
+ }
22956
+ return setTimeout(function () {
22957
+ callback({
22958
+ didTimeout: true,
22959
+ timeRemaining: function () {
22960
+ return 0;
22961
+ }
22962
+ });
22963
+ }, 0);
22964
+ },
22965
+ cancelIdle: function (id) {
22966
+ if (typeof window !== 'undefined' && window.cancelIdleCallback) {
22967
+ window.cancelIdleCallback(id);
22968
+ } else {
22969
+ clearTimeout(id);
22970
+ }
22971
+ },
22972
+ createLRUCache: function (maxSize) {
22973
+ var cache = new Map();
22974
+ maxSize = maxSize || 100;
22975
+ return {
22976
+ get: function (key) {
22977
+ if (!cache.has(key)) {
22978
+ return undefined;
22979
+ }
22980
+ var value = cache.get(key);
22981
+ cache.delete(key);
22982
+ cache.set(key, value);
22983
+ return value;
22984
+ },
22985
+ set: function (key, value) {
22986
+ if (cache.has(key)) {
22987
+ cache.delete(key);
22988
+ } else if (cache.size >= maxSize) {
22989
+ var firstKey = cache.keys().next().value;
22990
+ cache.delete(firstKey);
22991
+ }
22992
+ cache.set(key, value);
22993
+ },
22994
+ has: function (key) {
22995
+ return cache.has(key);
22996
+ },
22997
+ delete: function (key) {
22998
+ return cache.delete(key);
22999
+ },
23000
+ clear: function () {
23001
+ cache.clear();
23002
+ },
23003
+ size: function () {
23004
+ return cache.size;
23005
+ }
23006
+ };
22460
23007
  }
22461
23008
  };
22462
23009
  }(_dereq_('uuid'));
@@ -22529,7 +23076,6 @@ module.exports = function (MouseDragHandler, PlayheadLayer, SourcesLayer, ModeLa
22529
23076
  width: self._width - self._peaks.options.lineIndicatorWidth,
22530
23077
  height: self._height
22531
23078
  });
22532
- self._tempGroup = new Konva.Group({ listening: false });
22533
23079
  self._width -= self._peaks.options.lineIndicatorWidth;
22534
23080
  self._axis = new Axis(self._peaks, self, {
22535
23081
  axisGridlineColor: this._options.axisGridlineColor,
@@ -22538,7 +23084,6 @@ module.exports = function (MouseDragHandler, PlayheadLayer, SourcesLayer, ModeLa
22538
23084
  self._axis.addBackToStage(self._stage);
22539
23085
  self._sourcesLayer = new SourcesLayer(peaks, self, true);
22540
23086
  self._sourcesLayer.addToStage(self._stage);
22541
- self._sourcesLayer.add(self._tempGroup);
22542
23087
  self._axis.addFrontToStage(self._stage);
22543
23088
  self._playheadLayer = new PlayheadLayer(peaks, self, self._sourcesLayer.getLineGroups(), self._options.showPlayheadTime);
22544
23089
  self._playheadLayer.addToStage(self._stage);
@@ -22644,7 +23189,7 @@ module.exports = function (MouseDragHandler, PlayheadLayer, SourcesLayer, ModeLa
22644
23189
  window.addEventListener('click', this._onWindowClick, false);
22645
23190
  }
22646
23191
  View.prototype._mouseUp = function () {
22647
- this.clearScrollingInterval();
23192
+ this.stopAutoScroll();
22648
23193
  this._peaks.emit('handler.view.mouseup');
22649
23194
  };
22650
23195
  View.prototype._onWindowClick = function (event) {
@@ -22655,49 +23200,109 @@ module.exports = function (MouseDragHandler, PlayheadLayer, SourcesLayer, ModeLa
22655
23200
  View.prototype.setClickable = function (clickable) {
22656
23201
  this._isClickable = clickable;
22657
23202
  };
22658
- View.prototype.getTempGroup = function () {
22659
- return this._tempGroup;
22660
- };
22661
23203
  View.prototype.getSelectedElements = function () {
22662
23204
  return Object.values(this._modeLayer.getSelectedElements());
22663
23205
  };
22664
- View.prototype.updateWithAutoScroll = function (updateInInterval, updateOutInterval) {
23206
+ View.prototype.updateWithAutoScroll = function (updateWhileScrolling, updateWhileNotScrolling, enableVerticalAutoScroll) {
22665
23207
  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;
22678
- if (newOffset < 0) {
22679
- self.updateTimeline(0);
22680
- clearInterval(self._scrollingInterval);
22681
- self._scrollingInterval = null;
23208
+ var pointer = this.getPointerPosition();
23209
+ var pointerX = pointer ? pointer.x : null;
23210
+ var pointerY = pointer ? pointer.y : null;
23211
+ var viewWidth = this.getWidth();
23212
+ var viewHeight = this.getHeight();
23213
+ var thresholdPx = Math.round(this._peaks.options.autoScrollThreshold * viewWidth);
23214
+ var thresholdPy = Math.round(this._peaks.options.autoScrollThreshold * viewHeight);
23215
+ var MAX_AUTO_SCROLL_PX_PER_FRAME = 30;
23216
+ var NOMINAL_FRAME_MS = 16.67;
23217
+ function getAutoScrollVelocity(pointerValue, threshold, size) {
23218
+ if (typeof pointerValue !== 'number' || threshold <= 0 || size <= 0) {
23219
+ return 0;
23220
+ }
23221
+ if (pointerValue < threshold) {
23222
+ return Math.round(-MAX_AUTO_SCROLL_PX_PER_FRAME * Math.min(1, (threshold - pointerValue) / threshold));
23223
+ }
23224
+ if (pointerValue > size - threshold) {
23225
+ return Math.round(MAX_AUTO_SCROLL_PX_PER_FRAME * Math.min(1, (pointerValue - (size - threshold)) / threshold));
23226
+ }
23227
+ return 0;
23228
+ }
23229
+ var velocityXPerFrame = getAutoScrollVelocity(pointerX, thresholdPx, viewWidth);
23230
+ var verticalScrollingEnabled = Boolean(enableVerticalAutoScroll && this._peaks.options.enableVerticalScrolling);
23231
+ var maxFrameOffsetY = 0;
23232
+ if (verticalScrollingEnabled) {
23233
+ maxFrameOffsetY = this.getFullHeight() - viewHeight;
23234
+ if (!Number.isFinite(maxFrameOffsetY) || maxFrameOffsetY < 0) {
23235
+ maxFrameOffsetY = 0;
23236
+ }
23237
+ }
23238
+ var velocityYPerFrame = verticalScrollingEnabled && maxFrameOffsetY > 0 ? getAutoScrollVelocity(pointerY, thresholdPy, viewHeight) : 0;
23239
+ var canScrollX = velocityXPerFrame > 0 || velocityXPerFrame < 0 && self.getFrameOffset() > 0;
23240
+ var canScrollY = verticalScrollingEnabled && maxFrameOffsetY > 0 && (velocityYPerFrame > 0 && self.getFrameOffsetY() < maxFrameOffsetY || velocityYPerFrame < 0 && self.getFrameOffsetY() > 0);
23241
+ this._autoScrollVelocityX = velocityXPerFrame;
23242
+ this._autoScrollVelocityY = velocityYPerFrame;
23243
+ if (velocityXPerFrame !== 0 && canScrollX || velocityYPerFrame !== 0 && canScrollY) {
23244
+ if (!this._scrollingRafId) {
23245
+ var lastTime = performance.now();
23246
+ function scrollFrame(currentTime) {
23247
+ if (!self._scrollingRafId) {
23248
+ return;
23249
+ }
23250
+ var xVel = self._autoScrollVelocityX || 0;
23251
+ var yVel = self._autoScrollVelocityY || 0;
23252
+ var canContinueX = xVel > 0 || xVel < 0 && self.getFrameOffset() > 0;
23253
+ var maxY = 0;
23254
+ var canContinueY = false;
23255
+ if (verticalScrollingEnabled) {
23256
+ maxY = self.getFullHeight() - self.getHeight();
23257
+ if (!Number.isFinite(maxY) || maxY < 0) {
23258
+ maxY = 0;
23259
+ }
23260
+ canContinueY = maxY > 0 && (yVel > 0 && self.getFrameOffsetY() < maxY || yVel < 0 && self.getFrameOffsetY() > 0);
23261
+ }
23262
+ if ((xVel === 0 || !canContinueX) && (yVel === 0 || !canContinueY)) {
23263
+ self.stopAutoScroll();
23264
+ updateWhileScrolling();
23265
+ return;
23266
+ }
23267
+ var deltaTime = currentTime - lastTime;
23268
+ var scrollAmountX = Math.round(xVel * deltaTime / NOMINAL_FRAME_MS);
23269
+ var scrollAmountY = Math.round(yVel * deltaTime / NOMINAL_FRAME_MS);
23270
+ lastTime = currentTime;
23271
+ var newOffsetX = self.getFrameOffset() + scrollAmountX;
23272
+ var newOffsetY = self.getFrameOffsetY() + scrollAmountY;
23273
+ if (newOffsetX < 0) {
23274
+ newOffsetX = 0;
23275
+ }
23276
+ if (verticalScrollingEnabled) {
23277
+ if (newOffsetY < 0) {
23278
+ newOffsetY = 0;
23279
+ } else if (newOffsetY > maxY) {
23280
+ newOffsetY = maxY;
23281
+ }
23282
+ }
23283
+ if (!verticalScrollingEnabled) {
23284
+ self.updateTimeline(newOffsetX);
22682
23285
  } else {
22683
- self.updateTimeline(self.getFrameOffset() + self._limited);
23286
+ self.updateTimeline(newOffsetX, newOffsetY);
22684
23287
  }
22685
- updateInInterval();
22686
- }, 10);
23288
+ updateWhileScrolling();
23289
+ self._scrollingRafId = requestAnimationFrame(scrollFrame);
23290
+ }
23291
+ self._scrollingRafId = requestAnimationFrame(scrollFrame);
22687
23292
  }
22688
23293
  } else {
22689
- this.clearScrollingInterval();
22690
- if (updateOutInterval) {
22691
- updateOutInterval();
23294
+ this.stopAutoScroll();
23295
+ if (updateWhileNotScrolling) {
23296
+ updateWhileNotScrolling();
22692
23297
  } else {
22693
- updateInInterval();
23298
+ updateWhileScrolling();
22694
23299
  }
22695
23300
  }
22696
23301
  };
22697
- View.prototype.clearScrollingInterval = function () {
22698
- if (this._scrollingInterval) {
22699
- clearInterval(this._scrollingInterval);
22700
- this._scrollingInterval = null;
23302
+ View.prototype.stopAutoScroll = function () {
23303
+ if (this._scrollingRafId) {
23304
+ cancelAnimationFrame(this._scrollingRafId);
23305
+ this._scrollingRafId = null;
22701
23306
  }
22702
23307
  };
22703
23308
  View.prototype.getCurrentMode = function () {
@@ -22891,7 +23496,7 @@ module.exports = function (MouseDragHandler, PlayheadLayer, SourcesLayer, ModeLa
22891
23496
  this.setFrameOffset(apexPixel - playheadOffsetPixels);
22892
23497
  this.overrideInteractions(true, true);
22893
23498
  this.updateTimeline(this._frameOffset);
22894
- this._sourcesLayer.rescale(true);
23499
+ this._sourcesLayer.rescale();
22895
23500
  this._playheadLayer.updatePlayheadTime(currentTime);
22896
23501
  this._peaks.emit('handler.view.updatezoom', newScale, prevScale);
22897
23502
  this.overrideInteractions(false, true);