@checksub_team/peaks_timeline 2.0.0-alpha.9 → 2.0.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
@@ -14446,16 +14446,16 @@ module.exports = function (Utils, Konva) {
14446
14446
  Axis.prototype._onPlayheadMoved = function (playheadX, playheadWidth) {
14447
14447
  this._maskStart = playheadX + this._view.getFrameOffset();
14448
14448
  this._maskEnd = playheadX + this._view.getFrameOffset() + playheadWidth;
14449
- this._frontLayer.draw();
14449
+ this._frontLayer.batchDraw();
14450
14450
  };
14451
14451
  Axis.prototype._onPlayheadHidden = function () {
14452
14452
  this._maskStart = null;
14453
14453
  this._maskEnd = null;
14454
- this._frontLayer.draw();
14454
+ this._frontLayer.batchDraw();
14455
14455
  };
14456
- Axis.prototype.draw = function () {
14457
- this._backLayer.draw();
14458
- this._frontLayer.draw();
14456
+ Axis.prototype.batchDraw = function () {
14457
+ this._backLayer.batchDraw();
14458
+ this._frontLayer.batchDraw();
14459
14459
  };
14460
14460
  Axis.prototype.addBackToStage = function (stage) {
14461
14461
  stage.add(this._backLayer);
@@ -14561,7 +14561,7 @@ module.exports = function (Utils, Konva) {
14561
14561
  return Axis;
14562
14562
  }(_dereq_('../utils'), _dereq_('konva'));
14563
14563
  },{"../utils":116,"konva":43}],87:[function(_dereq_,module,exports){
14564
- module.exports = function (Data) {
14564
+ module.exports = function (Data, Utils) {
14565
14565
  'use strict';
14566
14566
  function DataRetriever(peaks) {
14567
14567
  this._peaks = peaks;
@@ -14607,11 +14607,10 @@ module.exports = function (Data) {
14607
14607
  throw new Error('HTTP ' + response.status + ': ' + response.statusText);
14608
14608
  }
14609
14609
  return response.blob();
14610
- }).catch(function (err) {
14611
- return later(delay).then(function () {
14612
- return recur(timesTried + 1, err);
14613
- });
14614
14610
  }).then(function (blob) {
14611
+ if (Utils.isNullOrUndefined(blob)) {
14612
+ throw new Error('Failed to retrieve blob');
14613
+ }
14615
14614
  var type = blob.type;
14616
14615
  if (type) {
14617
14616
  type = type.split('/')[0];
@@ -14625,13 +14624,17 @@ module.exports = function (Data) {
14625
14624
  self._peaks.emit('data.retrieved', data, src, url);
14626
14625
  });
14627
14626
  }
14627
+ }).catch(function (err) {
14628
+ return later(delay).then(function () {
14629
+ return recur(timesTried + 1, err);
14630
+ });
14628
14631
  });
14629
14632
  }
14630
14633
  return recur(0);
14631
14634
  };
14632
14635
  return DataRetriever;
14633
- }(_dereq_('./data'));
14634
- },{"./data":88}],88:[function(_dereq_,module,exports){
14636
+ }(_dereq_('./data'), _dereq_('../utils'));
14637
+ },{"../utils":116,"./data":88}],88:[function(_dereq_,module,exports){
14635
14638
  module.exports = function () {
14636
14639
  'use strict';
14637
14640
  function Data(type, content) {
@@ -14710,11 +14713,11 @@ module.exports = function (Utils, Konva) {
14710
14713
  if (self._options.draggable) {
14711
14714
  group.on('dragstart', function () {
14712
14715
  self._label.show();
14713
- self._options.group.draw();
14716
+ self._batchDraw();
14714
14717
  });
14715
14718
  group.on('dragend', function () {
14716
14719
  self._label.hide();
14717
- self._options.group.draw();
14720
+ self._batchDraw();
14718
14721
  });
14719
14722
  }
14720
14723
  if (self._handle) {
@@ -14722,12 +14725,12 @@ module.exports = function (Utils, Konva) {
14722
14725
  self._options.view.setCursor('ew-resize');
14723
14726
  self._label.show();
14724
14727
  self._group.moveToTop();
14725
- self._options.view.drawSourcesLayer();
14728
+ self._options.view.batchDrawSourcesLayer();
14726
14729
  });
14727
14730
  self._handle.on('mouseout touchend', function () {
14728
14731
  self._options.view.setCursor('default');
14729
14732
  self._label.hide();
14730
- self._options.view.drawSourcesLayer();
14733
+ self._options.view.batchDrawSourcesLayer();
14731
14734
  });
14732
14735
  }
14733
14736
  };
@@ -14745,6 +14748,13 @@ module.exports = function (Utils, Konva) {
14745
14748
  DefaultSegmentMarker.prototype.timeUpdated = function (time) {
14746
14749
  this._label.setText(Utils.formatTime(time, false));
14747
14750
  };
14751
+ DefaultSegmentMarker.prototype._batchDraw = function () {
14752
+ const group = this._options.group;
14753
+ const layer = group && group.getLayer && group.getLayer();
14754
+ if (layer && typeof layer.batchDraw === 'function') {
14755
+ layer.batchDraw();
14756
+ }
14757
+ };
14748
14758
  return DefaultSegmentMarker;
14749
14759
  }(_dereq_('../utils'), _dereq_('konva'));
14750
14760
  },{"../utils":116,"konva":43}],90:[function(_dereq_,module,exports){
@@ -15325,6 +15335,7 @@ module.exports = function (SegmentsGroup, LineGroup, LineIndicator, Utils) {
15325
15335
  this._peaks.on('main.allowInteractions', this.allowInteractions.bind(this));
15326
15336
  this._peaks.on('line.heightChanged', this._onLineHeightChanged.bind(this));
15327
15337
  this._peaks.on('segments.dragend', this._onSegmentUpdated.bind(this));
15338
+ this._peaks.on('lineIndicator.drag', this._onIndicatorDrag.bind(this));
15328
15339
  }
15329
15340
  LineGroups.prototype.fitToView = function () {
15330
15341
  this._lineIndicator.fitToView();
@@ -15502,11 +15513,18 @@ module.exports = function (SegmentsGroup, LineGroup, LineIndicator, Utils) {
15502
15513
  this._automaticLineCreationPosition = newLinePosition;
15503
15514
  this._automaticLineCreationTimeout = setTimeout(function () {
15504
15515
  this._automaticLineCreationTimeout = null;
15505
- var currentLine = this._lineGroupsByPosition[initialPosition];
15516
+ const currentLine = this._lineGroupsByPosition[initialPosition];
15506
15517
  sources = sources.filter(function (source) {
15507
15518
  return currentLine.hasSource(source.id);
15508
15519
  });
15509
- if (sources.length === 0 || sources.length === currentLine.countRemainingElements()) {
15520
+ if (sources.length === 0) {
15521
+ this.stopAutomaticLineCreation();
15522
+ return;
15523
+ }
15524
+ const posAround = this.getLinesAroundPos(currentLine.getPosition());
15525
+ const targetPosIsJustBefore = newLinePosition <= currentLine.getPosition() && newLinePosition > posAround[0];
15526
+ const targetPosIsJustAfter = newLinePosition >= currentLine.getPosition() && newLinePosition <= posAround[1];
15527
+ if (sources.length === currentLine.countRemainingElements() && (targetPosIsJustBefore || targetPosIsJustAfter)) {
15510
15528
  this.stopAutomaticLineCreation();
15511
15529
  return;
15512
15530
  }
@@ -15583,6 +15601,24 @@ module.exports = function (SegmentsGroup, LineGroup, LineIndicator, Utils) {
15583
15601
  }
15584
15602
  return pos;
15585
15603
  };
15604
+ LineGroups.prototype.getLinesAroundPos = function (pos) {
15605
+ var returnPos = [
15606
+ -1,
15607
+ this.getLastPosition() + 1
15608
+ ];
15609
+ for (var position in this._lineGroupsByPosition) {
15610
+ if (Utils.objectHasProperty(this._lineGroupsByPosition, position)) {
15611
+ var p = parseInt(position, 10);
15612
+ if (p < pos) {
15613
+ returnPos[0] = p;
15614
+ } else if (p > pos) {
15615
+ returnPos[1] = p;
15616
+ break;
15617
+ }
15618
+ }
15619
+ }
15620
+ return returnPos;
15621
+ };
15586
15622
  LineGroups.prototype._moveSourcesToPositionIfPossible = function (sources, targetPosition, targetTime, sourcesDuration) {
15587
15623
  const lineGroup = this._lineGroupsByPosition[targetPosition];
15588
15624
  if (!lineGroup || lineGroup.isSegmentsLine()) {
@@ -15667,6 +15703,30 @@ module.exports = function (SegmentsGroup, LineGroup, LineIndicator, Utils) {
15667
15703
  this.refreshLineYs();
15668
15704
  return line.id;
15669
15705
  };
15706
+ LineGroups.prototype._onIndicatorDrag = function (lineId, y) {
15707
+ const lineGroup = this._lineGroupsById[lineId];
15708
+ if (!lineGroup) {
15709
+ return;
15710
+ }
15711
+ const positions = this.getLinesUnderY(y);
15712
+ if (positions[0] !== positions[1] || positions[0] === lineGroup.getPosition()) {
15713
+ return;
15714
+ }
15715
+ const targetPos = positions[0];
15716
+ const targetLineGroup = this._lineGroupsByPosition[targetPos];
15717
+ const targetCenterY = targetLineGroup.y() + targetLineGroup.lineHeight() / 2;
15718
+ const movingDown = targetPos > lineGroup.getPosition();
15719
+ if (movingDown && y < targetCenterY || !movingDown && y > targetCenterY) {
15720
+ return;
15721
+ }
15722
+ if (targetPos === lineGroup.getPosition() + 1) {
15723
+ this._setLinePosition(targetLineGroup.getId(), lineGroup.getPosition());
15724
+ } else {
15725
+ this._setLinePosition(lineId, targetPos);
15726
+ }
15727
+ this.refreshLineYs();
15728
+ this._peaks.emit('line.moved', lineGroup.getLine());
15729
+ };
15670
15730
  LineGroups.prototype.updateSegments = function (frameStartTime, frameEndTime) {
15671
15731
  for (var lineId in this._segmentsGroups) {
15672
15732
  if (Utils.objectHasProperty(this._segmentsGroups, lineId)) {
@@ -15750,7 +15810,12 @@ module.exports = function (Konva, SVGs, Utils) {
15750
15810
  listening: false
15751
15811
  });
15752
15812
  this._layer.add(this._separatingLine);
15753
- this._layer.draw();
15813
+ this._layer.batchDraw();
15814
+ this._isDragging = false;
15815
+ this._dragLineId = null;
15816
+ this._dragContainerRect = null;
15817
+ this._onWindowMove = this._onWindowMove.bind(this);
15818
+ this._onWindowUp = this._onWindowUp.bind(this);
15754
15819
  }
15755
15820
  LineIndicator.prototype.fitToView = function () {
15756
15821
  this._height = this._view.getHeight();
@@ -15830,19 +15895,30 @@ module.exports = function (Konva, SVGs, Utils) {
15830
15895
  indicator.getChildren().forEach(function (child) {
15831
15896
  child.fill(child.getAttr('selectedColor'));
15832
15897
  });
15833
- self.draw();
15898
+ self.batchDraw();
15834
15899
  self._stage.container().style.cursor = 'pointer';
15835
15900
  });
15836
15901
  indicator.on('mouseout', function () {
15837
15902
  indicator.getChildren().forEach(function (child) {
15838
15903
  child.fill(child.getAttr('defaultColor'));
15839
15904
  });
15840
- self.draw();
15841
- self._stage.container().style.cursor = 'default';
15905
+ self.batchDraw();
15906
+ if (!self._isDragging) {
15907
+ self._stage.container().style.cursor = 'default';
15908
+ }
15842
15909
  });
15843
15910
  indicator.on('click', function (e) {
15844
15911
  self._peaks.emit('lineIndicator.click', self._indicators[lineGroup.getId()], e.evt);
15845
15912
  });
15913
+ indicator.on('mousedown touchstart', function () {
15914
+ self._dragLineId = lineGroup.getId();
15915
+ self._dragContainerRect = self._stage.getContainer().getBoundingClientRect();
15916
+ window.addEventListener('mousemove', self._onWindowMove, false);
15917
+ window.addEventListener('touchmove', self._onWindowMove, false);
15918
+ window.addEventListener('mouseup', self._onWindowUp, false);
15919
+ window.addEventListener('touchend', self._onWindowUp, false);
15920
+ window.addEventListener('blur', self._onWindowUp, false);
15921
+ });
15846
15922
  return indicator;
15847
15923
  };
15848
15924
  LineIndicator.prototype.addIndicator = function (lineGroup) {
@@ -15853,7 +15929,8 @@ module.exports = function (Konva, SVGs, Utils) {
15853
15929
  this._indicators[line.id] = {
15854
15930
  lineGroup: lineGroup,
15855
15931
  indicator: indicator,
15856
- type: line.indicatorType
15932
+ type: line.indicatorType,
15933
+ text: line.indicatorText
15857
15934
  };
15858
15935
  }
15859
15936
  };
@@ -15872,7 +15949,7 @@ module.exports = function (Konva, SVGs, Utils) {
15872
15949
  indicatorData.indicator = indicator;
15873
15950
  indicatorData.type = line.indicatorType;
15874
15951
  indicatorData.text = line.indicatorText;
15875
- this.draw();
15952
+ this.batchDraw();
15876
15953
  };
15877
15954
  LineIndicator.prototype.removeIndicator = function (lineId, keepInList) {
15878
15955
  if (this._indicators[lineId]) {
@@ -15921,12 +15998,39 @@ module.exports = function (Konva, SVGs, Utils) {
15921
15998
  }
15922
15999
  }
15923
16000
  if (anyChange) {
15924
- this.draw();
16001
+ this.batchDraw();
15925
16002
  }
15926
16003
  return anyChange;
15927
16004
  };
15928
- LineIndicator.prototype.draw = function () {
15929
- this._layer.draw();
16005
+ LineIndicator.prototype.batchDraw = function () {
16006
+ this._layer.batchDraw();
16007
+ };
16008
+ LineIndicator.prototype._onWindowMove = function (event) {
16009
+ if (!this._dragContainerRect) {
16010
+ return;
16011
+ }
16012
+ if (!this._isDragging) {
16013
+ this._stage.container().style.cursor = 'grabbing';
16014
+ }
16015
+ var clientY;
16016
+ if (event.type === 'touchmove') {
16017
+ clientY = Math.floor(event.changedTouches[0].clientY);
16018
+ } else {
16019
+ clientY = event.clientY;
16020
+ }
16021
+ const relY = clientY - this._dragContainerRect.top;
16022
+ this._peaks.emit('lineIndicator.drag', this._dragLineId, relY);
16023
+ };
16024
+ LineIndicator.prototype._onWindowUp = function () {
16025
+ window.removeEventListener('mousemove', this._onWindowMove, false);
16026
+ window.removeEventListener('touchmove', this._onWindowMove, false);
16027
+ window.removeEventListener('mouseup', this._onWindowUp, false);
16028
+ window.removeEventListener('touchend', this._onWindowUp, false);
16029
+ window.removeEventListener('blur', this._onWindowUp, false);
16030
+ this._isDragging = false;
16031
+ this._dragLineId = null;
16032
+ this._dragContainerRect = null;
16033
+ this._stage.container().style.cursor = 'pointer';
15930
16034
  };
15931
16035
  return LineIndicator;
15932
16036
  }(_dereq_('konva'), _dereq_('./svgs'), _dereq_('../utils'));
@@ -16173,7 +16277,7 @@ module.exports = function (SourceGroup, Source, Utils, Konva) {
16173
16277
  }
16174
16278
  } else {
16175
16279
  this.deselectDifference([], true);
16176
- this._view.drawSourcesLayer();
16280
+ this._view.batchDrawSourcesLayer();
16177
16281
  }
16178
16282
  };
16179
16283
  ModeLayer.prototype._onKeyboardDelete = function () {
@@ -16194,7 +16298,7 @@ module.exports = function (SourceGroup, Source, Utils, Konva) {
16194
16298
  };
16195
16299
  ModeLayer.prototype._onMouseEnterInCutMode = function () {
16196
16300
  this._cutGroup.visible(true);
16197
- this._layer.draw();
16301
+ this._layer.batchDraw();
16198
16302
  };
16199
16303
  ModeLayer.prototype._updateCursorTime = function (position) {
16200
16304
  var hoveredElement = this._view.getHoveredElement();
@@ -16266,11 +16370,11 @@ module.exports = function (SourceGroup, Source, Utils, Konva) {
16266
16370
  }
16267
16371
  this._updateCursorTime(cuttingPosition);
16268
16372
  this._updateCuttingLine(cuttingPosition);
16269
- this._layer.draw();
16373
+ this._layer.batchDraw();
16270
16374
  };
16271
16375
  ModeLayer.prototype._onMouseLeaveInCutMode = function () {
16272
16376
  this._cutGroup.visible(false);
16273
- this._layer.draw();
16377
+ this._layer.batchDraw();
16274
16378
  };
16275
16379
  ModeLayer.prototype._onMouseClickInCutMode = function () {
16276
16380
  var mousePosition = this._stage.getPointerPosition();
@@ -16299,7 +16403,7 @@ module.exports = function (SourceGroup, Source, Utils, Konva) {
16299
16403
  this._view.setHoveredElement(null);
16300
16404
  this._updateCursorTime(cuttingPosition);
16301
16405
  this._updateCuttingLine(cuttingPosition);
16302
- this._layer.draw();
16406
+ this._layer.batchDraw();
16303
16407
  }
16304
16408
  }
16305
16409
  };
@@ -16356,8 +16460,8 @@ module.exports = function (SourceGroup, Source, Utils, Konva) {
16356
16460
  return;
16357
16461
  }
16358
16462
  this._mode = mode;
16359
- this._layer.draw();
16360
- this._view.drawSourcesLayer();
16463
+ this._layer.batchDraw();
16464
+ this._view.batchDrawSourcesLayer();
16361
16465
  };
16362
16466
  ModeLayer.prototype.getCurrentMode = function () {
16363
16467
  return this._mode;
@@ -16616,7 +16720,7 @@ module.exports = function (Utils, Konva) {
16616
16720
  }
16617
16721
  }
16618
16722
  this._time = time;
16619
- this._playheadLayer.draw();
16723
+ this._playheadLayer.batchDraw();
16620
16724
  };
16621
16725
  PlayheadLayer.prototype.getPlayheadOffset = function () {
16622
16726
  return this._playheadPixel - this._view.getFrameOffset();
@@ -16640,7 +16744,7 @@ module.exports = function (Utils, Konva) {
16640
16744
  }
16641
16745
  }
16642
16746
  if (updated) {
16643
- this._playheadLayer.draw();
16747
+ this._playheadLayer.batchDraw();
16644
16748
  }
16645
16749
  };
16646
16750
  return PlayheadLayer;
@@ -17016,7 +17120,7 @@ module.exports = function (Konva, SegmentMarker, Utils) {
17016
17120
  0.65,
17017
17121
  this._segment.warningColor
17018
17122
  ]);
17019
- this._view.drawSourcesLayer();
17123
+ this._view.batchDrawSourcesLayer();
17020
17124
  this._peaks.emit('segments.mouseenter', this._segment);
17021
17125
  };
17022
17126
  SegmentShape.prototype._onMouseLeave = function () {
@@ -17030,7 +17134,7 @@ module.exports = function (Konva, SegmentMarker, Utils) {
17030
17134
  0.65,
17031
17135
  this._segment.warningColor
17032
17136
  ]);
17033
- this._view.drawSourcesLayer();
17137
+ this._view.batchDrawSourcesLayer();
17034
17138
  this._peaks.emit('segments.mouseleave', this._segment);
17035
17139
  };
17036
17140
  SegmentShape.prototype._onClick = function () {
@@ -17331,7 +17435,7 @@ module.exports = function (SegmentShape, Utils, Konva) {
17331
17435
  return visibleSegments;
17332
17436
  };
17333
17437
  SegmentsGroup.prototype._draw = function () {
17334
- this._view.drawSourcesLayer();
17438
+ this._view.batchDrawSourcesLayer();
17335
17439
  };
17336
17440
  SegmentsGroup.prototype._updateSegment = function (segment) {
17337
17441
  var segmentShape = this._findOrAddSegmentShape(segment);
@@ -17629,6 +17733,7 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
17629
17733
  var SPACING_BETWEEN_PREVIEWS = 1.5;
17630
17734
  var CORNER_RADIUS = 8;
17631
17735
  var INDICATOR_RADIUS = 4;
17736
+ var PREVIEW_CREATE_CHUNK = 8;
17632
17737
  function SourceGroup(source, peaks, layer, view) {
17633
17738
  this._source = source;
17634
17739
  this._peaks = peaks;
@@ -17648,6 +17753,7 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
17648
17753
  this._hovered = false;
17649
17754
  this._isDragged = false;
17650
17755
  this._previewList = [];
17756
+ this._previewBuildQueue = new Set();
17651
17757
  this._markersGroup = this._createMarkers();
17652
17758
  this._group = new Konva.Group({
17653
17759
  x: this._x,
@@ -17663,18 +17769,8 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
17663
17769
  this._group.on('dragstart', this._onDragStart.bind(this));
17664
17770
  this._group.on('dragend', this._onDragEnd.bind(this));
17665
17771
  this._cursor = null;
17666
- this._group.on('mouseenter', function () {
17667
- self._setHovered(true);
17668
- self._view.setHoveredElement(self);
17669
- if (!self._source.loading) {
17670
- self._showButtons();
17671
- }
17672
- });
17673
- this._group.on('mouseleave', function () {
17674
- self._setHovered(false);
17675
- self._view.setHoveredElement(null);
17676
- self._hideButtons();
17677
- });
17772
+ this._group.on('mouseenter', this._onHoverStart.bind(this));
17773
+ this._group.on('mouseleave', this._onHoverEnd.bind(this));
17678
17774
  this._group.on('mouseover', function () {
17679
17775
  if (self._source.draggable) {
17680
17776
  self._view.setCursor(self._cursor || 'pointer');
@@ -17709,9 +17805,20 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
17709
17805
  this.createIndicators();
17710
17806
  this.setLoadingState(this._source.loading);
17711
17807
  }
17712
- SourceGroup.prototype._setHovered = function (newValue) {
17713
- this._hovered = newValue;
17714
- this._group.draw();
17808
+ SourceGroup.prototype._onHoverStart = function () {
17809
+ this._hovered = true;
17810
+ this._view.setHoveredElement(this);
17811
+ if (!this._source.loading) {
17812
+ this._showButtons();
17813
+ }
17814
+ this._batchDraw();
17815
+ };
17816
+ SourceGroup.prototype._onHoverEnd = function () {
17817
+ this._hovered = false;
17818
+ this._manualHover = false;
17819
+ this._view.setHoveredElement(null);
17820
+ this._hideButtons();
17821
+ this._batchDraw();
17715
17822
  };
17716
17823
  SourceGroup.prototype._onDragStart = function (element) {
17717
17824
  this._isDragged = true;
@@ -17719,8 +17826,25 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
17719
17826
  };
17720
17827
  SourceGroup.prototype._onDragEnd = function (element) {
17721
17828
  this._isDragged = false;
17829
+ this._manageManualHoverStop();
17722
17830
  this._layer.onSourcesGroupDragEnd(element);
17723
17831
  };
17832
+ SourceGroup.prototype._manageManualHoverStop = function () {
17833
+ if (!this._manualHover) {
17834
+ return;
17835
+ }
17836
+ var pointer = this._view.getPointerPosition();
17837
+ if (pointer) {
17838
+ var absPos = this._group.absolutePosition();
17839
+ var inside = pointer.x >= absPos.x && pointer.x <= absPos.x + this._width && pointer.y >= absPos.y && pointer.y <= absPos.y + this._height;
17840
+ if (!inside) {
17841
+ this.stopHover();
17842
+ }
17843
+ }
17844
+ };
17845
+ SourceGroup.prototype.isHovered = function () {
17846
+ return this._hovered;
17847
+ };
17724
17848
  SourceGroup.prototype.isActive = function () {
17725
17849
  return this._isDragged;
17726
17850
  };
@@ -17743,7 +17867,7 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
17743
17867
  const {start, end} = this._initialTimes;
17744
17868
  this._view.updateWithAutoScroll(function () {
17745
17869
  if (this._layer.manageSourceMovements([this._source], leftHandle ? start + diff + timeOffsetDiff : null, leftHandle ? null : end + diff + timeOffsetDiff)) {
17746
- this._layer.draw();
17870
+ this._layer.batchDraw();
17747
17871
  }
17748
17872
  }.bind(this));
17749
17873
  return {
@@ -18108,6 +18232,13 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
18108
18232
  SourceGroup.prototype.getSource = function () {
18109
18233
  return this._source;
18110
18234
  };
18235
+ SourceGroup.prototype.startHover = function () {
18236
+ this._manualHover = true;
18237
+ this._group.fire('mouseenter', { evt: new MouseEvent('mouseenter') }, true);
18238
+ };
18239
+ SourceGroup.prototype.stopHover = function () {
18240
+ this._group.fire('mouseleave', { evt: new MouseEvent('mouseleave') }, true);
18241
+ };
18111
18242
  SourceGroup.prototype.startDrag = function () {
18112
18243
  return this._group.startDrag();
18113
18244
  };
@@ -18208,64 +18339,40 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
18208
18339
  if (err) {
18209
18340
  throw err;
18210
18341
  }
18211
- originalWaveformData.hasAudio = self._hasAudio(originalWaveformData);
18212
- if (originalWaveformData.hasAudio) {
18213
- var newScale = originalWaveformData.sample_rate / self._view.getTimeToPixelsMaxZoom();
18214
- if (newScale > originalWaveformData.scale) {
18215
- self._minScale = newScale;
18216
- } else {
18217
- self._minScale = originalWaveformData.scale;
18218
- }
18219
- self._view.setTimeToPixelsMaxZoom(originalWaveformData.sample_rate / self._minScale);
18342
+ var newScale = originalWaveformData.sample_rate / self._view.getTimeToPixelsMaxZoom();
18343
+ if (newScale > originalWaveformData.scale) {
18344
+ self._minScale = newScale;
18345
+ } else {
18346
+ self._minScale = originalWaveformData.scale;
18220
18347
  }
18348
+ self._view.setTimeToPixelsMaxZoom(originalWaveformData.sample_rate / self._minScale);
18221
18349
  self._layer.setLoadedData(url, originalWaveformData);
18222
18350
  self._layer.setLoadedData(url + '-scaled', {
18223
18351
  data: originalWaveformData,
18224
18352
  scale: originalWaveformData.sample_rate / self._minScale
18225
18353
  });
18226
18354
  preview.loaded = true;
18227
- self._createAudioPreview(preview, originalWaveformData, redraw);
18355
+ self._createAudioPreview(preview, redraw);
18228
18356
  });
18229
18357
  } else {
18230
18358
  preview.loaded = true;
18231
- this._createAudioPreview(preview, audioData, redraw);
18359
+ this._createAudioPreview(preview, redraw);
18232
18360
  }
18233
18361
  };
18234
- SourceGroup.prototype._hasAudio = function (waveformData) {
18235
- var channels = waveformData.channels;
18236
- var channel, someIsNotZero = false;
18237
- for (var i = 0; i < channels; i++) {
18238
- channel = waveformData.channel(i);
18239
- someIsNotZero = channel.min_array().some(function (item) {
18240
- return item !== 0;
18241
- });
18242
- if (!someIsNotZero) {
18243
- someIsNotZero = channel.max_array().some(function (item) {
18244
- return item !== 0;
18245
- });
18246
- }
18247
- if (someIsNotZero) {
18248
- break;
18249
- }
18250
- }
18251
- return someIsNotZero;
18252
- };
18253
- SourceGroup.prototype._createAudioPreview = function (preview, waveformData, redraw) {
18254
- if (waveformData.hasAudio) {
18255
- var waveform = new WaveformShape({
18256
- layer: this._layer,
18257
- view: this._view,
18258
- source: this._source,
18259
- height: preview.group.height(),
18260
- url: preview.url
18261
- });
18262
- preview.group.add(waveform);
18263
- this._addToUnwrap(preview.group);
18264
- if (redraw) {
18265
- this._layer.rescale(true);
18266
- }
18267
- this._previewList.push(preview);
18362
+ SourceGroup.prototype._createAudioPreview = function (preview, redraw) {
18363
+ var waveform = new WaveformShape({
18364
+ layer: this._layer,
18365
+ view: this._view,
18366
+ source: this._source,
18367
+ height: preview.group.height(),
18368
+ url: preview.url
18369
+ });
18370
+ preview.group.add(waveform);
18371
+ this._addToUnwrap(preview.group);
18372
+ if (redraw) {
18373
+ this._layer.rescale(true);
18268
18374
  }
18375
+ this._previewList.push(preview);
18269
18376
  };
18270
18377
  SourceGroup.prototype.getAudioPreview = function () {
18271
18378
  return this._previewList.filter(function (preview) {
@@ -18332,31 +18439,81 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
18332
18439
  } else {
18333
18440
  imageNumber = 0;
18334
18441
  }
18335
- var imageList = preview.group.getChildren();
18336
- var i = 0;
18337
- for (i = 0; i < imageNumber; i++) {
18338
- if (imageList.length > i) {
18339
- imageList[i].visible(true);
18340
- } else {
18341
- var imagePreview = new Konva.Image({
18342
- x: preview.imageData.borderSpacing + i * interImageSpacing,
18343
- y: preview.imageData.borderSpacing,
18344
- image: preview.imageData.image,
18345
- width: preview.imageData.width,
18346
- height: preview.imageData.height,
18347
- listening: false,
18348
- visible: true
18349
- });
18350
- preview.group.add(imagePreview);
18351
- }
18352
- }
18353
- for (i = imageNumber; i < imageList.length; i++) {
18354
- imageList[i].visible(false);
18355
- }
18442
+ self._ensureImagePreviewCount(preview, imageNumber, interImageSpacing);
18356
18443
  }
18357
18444
  }
18358
18445
  });
18359
18446
  };
18447
+ SourceGroup.prototype._batchDraw = function () {
18448
+ var layer = this._group && this._group.getLayer && this._group.getLayer();
18449
+ if (layer && typeof layer.batchDraw === 'function') {
18450
+ layer.batchDraw();
18451
+ }
18452
+ };
18453
+ SourceGroup.prototype._scheduleIdle = function (fn) {
18454
+ if (typeof window !== 'undefined' && window.requestIdleCallback) {
18455
+ return window.requestIdleCallback(fn, { timeout: 50 });
18456
+ }
18457
+ if (typeof window !== 'undefined' && window.requestAnimationFrame) {
18458
+ return window.requestAnimationFrame(function () {
18459
+ fn({
18460
+ timeRemaining: function () {
18461
+ return 0;
18462
+ },
18463
+ didTimeout: true
18464
+ });
18465
+ });
18466
+ }
18467
+ return setTimeout(function () {
18468
+ fn({
18469
+ timeRemaining: function () {
18470
+ return 0;
18471
+ },
18472
+ didTimeout: true
18473
+ });
18474
+ }, 0);
18475
+ };
18476
+ SourceGroup.prototype._ensureImagePreviewCount = function (preview, targetCount, interImageSpacing) {
18477
+ var imageList = preview.group.getChildren();
18478
+ var currentCount = imageList.length;
18479
+ for (var i = 0; i < Math.min(currentCount, targetCount); i++) {
18480
+ imageList[i].visible(true);
18481
+ }
18482
+ for (var j = targetCount; j < currentCount; j++) {
18483
+ imageList[j].visible(false);
18484
+ }
18485
+ if (currentCount >= targetCount || this._previewBuildQueue.has(preview)) {
18486
+ this._batchDraw();
18487
+ return;
18488
+ }
18489
+ this._previewBuildQueue.add(preview);
18490
+ var self = this;
18491
+ var nextIndex = currentCount;
18492
+ function buildChunk() {
18493
+ var added = 0;
18494
+ while (nextIndex < targetCount && added < PREVIEW_CREATE_CHUNK) {
18495
+ var imagePreview = new Konva.Image({
18496
+ x: preview.imageData.borderSpacing + nextIndex * interImageSpacing,
18497
+ y: preview.imageData.borderSpacing,
18498
+ image: preview.imageData.image,
18499
+ width: preview.imageData.width,
18500
+ height: preview.imageData.height,
18501
+ listening: false,
18502
+ visible: true
18503
+ });
18504
+ preview.group.add(imagePreview);
18505
+ nextIndex += 1;
18506
+ added += 1;
18507
+ }
18508
+ self._batchDraw();
18509
+ if (nextIndex < targetCount) {
18510
+ self._scheduleIdle(buildChunk);
18511
+ } else {
18512
+ self._previewBuildQueue.delete(preview);
18513
+ }
18514
+ }
18515
+ this._scheduleIdle(buildChunk);
18516
+ };
18360
18517
  SourceGroup.prototype._createImagePreview = function (preview, image, redraw) {
18361
18518
  preview.imageData = {
18362
18519
  image: image,
@@ -18373,22 +18530,15 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
18373
18530
  preview.imageData.height = preview.imageData.referenceHeight - 2 * preview.imageData.borderSpacing;
18374
18531
  preview.imageData.width = preview.imageData.height * preview.imageData.dimRatio;
18375
18532
  preview.imageData.imageSpacing = preview.imageData.width * SPACING_BETWEEN_PREVIEWS;
18376
- var currentX = preview.imageData.borderSpacing;
18377
- while (currentX < this._width) {
18378
- var imagePreview = new Konva.Image({
18379
- x: currentX,
18380
- y: preview.imageData.borderSpacing,
18381
- image: image,
18382
- width: preview.imageData.width,
18383
- height: preview.imageData.height,
18384
- listening: false
18385
- });
18386
- preview.group.add(imagePreview);
18387
- currentX += preview.imageData.width + preview.imageData.imageSpacing;
18388
- }
18389
18533
  this._addToUnwrap(preview.group);
18534
+ var interImageSpacing = preview.imageData.width + preview.imageData.imageSpacing;
18535
+ var targetCount = 0;
18536
+ if (this._width > preview.imageData.borderSpacing) {
18537
+ targetCount = Math.trunc((this._width - preview.imageData.borderSpacing) / interImageSpacing) + 1;
18538
+ }
18539
+ this._ensureImagePreviewCount(preview, targetCount, interImageSpacing);
18390
18540
  if (redraw) {
18391
- this._group.draw();
18541
+ this._batchDraw();
18392
18542
  }
18393
18543
  this._previewList.push(preview);
18394
18544
  };
@@ -18688,6 +18838,13 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
18688
18838
  this._buttonsAnimation.destroy();
18689
18839
  this._buttonsAnimation = null;
18690
18840
  }
18841
+ if (!this._buttonsGroup.getLayer()) {
18842
+ if (!this._buttonsGroup.getLayer()) {
18843
+ this._buttonsGroup.visible(true);
18844
+ this._buttonsGroup.opacity(1);
18845
+ return;
18846
+ }
18847
+ }
18691
18848
  var self = this;
18692
18849
  this._buttonsGroup.visible(true);
18693
18850
  this._buttonsAnimation = new Konva.Tween({
@@ -18709,6 +18866,11 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
18709
18866
  this._buttonsAnimation.destroy();
18710
18867
  this._buttonsAnimation = null;
18711
18868
  }
18869
+ if (!this._buttonsGroup.getLayer()) {
18870
+ this._buttonsGroup.visible(false);
18871
+ this._buttonsGroup.opacity(0);
18872
+ return;
18873
+ }
18712
18874
  var self = this;
18713
18875
  this._buttonsAnimation = new Konva.Tween({
18714
18876
  node: this._buttonsGroup,
@@ -18819,7 +18981,7 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
18819
18981
  volumeText.text((volume * 100).toFixed(0) + '%');
18820
18982
  self._source.volume = Math.max(self._source.volumeRange[0], Math.min(volume, self._source.volumeRange[1]));
18821
18983
  self._peaks.emit('source.volumeChanged', self._source);
18822
- self._group.draw();
18984
+ self._batchDraw();
18823
18985
  });
18824
18986
  volumeSliderGroup.on('dragend', function () {
18825
18987
  volumeText.visible(false);
@@ -18881,7 +19043,14 @@ module.exports = function (SourceGroup, LineGroups, DataRetriever, Invoker, Util
18881
19043
  this._peaks.on('data.retrieved', this._onDataRetrieved.bind(this));
18882
19044
  this._peaks.on('handler.segments.show', this._onSegmentsShow.bind(this));
18883
19045
  this._peaks.on('model.source.setIndicators', this.setIndicators.bind(this));
19046
+ this._peaks.on('handler.view.mouseup', this._stopDrag.bind(this));
18884
19047
  }
19048
+ SourcesLayer.prototype._stopDrag = function () {
19049
+ const draggedSourceGroup = this._sourcesGroup[this._draggedElementId];
19050
+ if (draggedSourceGroup) {
19051
+ draggedSourceGroup.stopDrag();
19052
+ }
19053
+ };
18885
19054
  SourcesLayer.prototype.fitToView = function () {
18886
19055
  this._lineGroups.fitToView();
18887
19056
  };
@@ -18912,18 +19081,28 @@ module.exports = function (SourceGroup, LineGroups, DataRetriever, Invoker, Util
18912
19081
  this.updateSources(this._view.pixelsToTime(frameOffset), this._view.pixelsToTime(frameOffset + width));
18913
19082
  };
18914
19083
  SourcesLayer.prototype._onSourceUpdate = function (source) {
19084
+ const sourceGroup = this._sourcesGroup[source.id];
19085
+ const frameOffset = this._view.getFrameOffset();
19086
+ const width = this._view.getWidth();
19087
+ const frameStartTime = this._view.pixelsToTime(frameOffset);
19088
+ const frameEndTime = this._view.pixelsToTime(frameOffset + width);
18915
19089
  var redraw = false;
18916
- var sourceGroup = this._sourcesGroup[source.id];
18917
- var frameOffset = this._view.getFrameOffset();
18918
- var width = this._view.getWidth();
18919
- var frameStartTime = this._view.pixelsToTime(frameOffset);
18920
- var frameEndTime = this._view.pixelsToTime(frameOffset + width);
19090
+ var isSourceGroupHovered = false;
19091
+ var isSourceGroupActive = false;
18921
19092
  if (sourceGroup) {
19093
+ isSourceGroupHovered = sourceGroup.isHovered();
19094
+ isSourceGroupActive = sourceGroup.isActive();
18922
19095
  this._destroySourceGroup(source);
18923
19096
  redraw = true;
18924
19097
  }
18925
- if (source.isVisible(frameStartTime, frameEndTime)) {
18926
- this._addSourceGroup(source);
19098
+ if (source.isVisible(frameStartTime, frameEndTime) || isSourceGroupActive) {
19099
+ const newSourceGroup = this._addSourceGroup(source);
19100
+ if (isSourceGroupHovered) {
19101
+ newSourceGroup.startHover();
19102
+ }
19103
+ if (isSourceGroupActive) {
19104
+ newSourceGroup.startDrag();
19105
+ }
18927
19106
  redraw = true;
18928
19107
  }
18929
19108
  if (redraw) {
@@ -18937,7 +19116,7 @@ module.exports = function (SourceGroup, LineGroups, DataRetriever, Invoker, Util
18937
19116
  sourceGroup.setSelected();
18938
19117
  }
18939
19118
  }.bind(this));
18940
- this.draw();
19119
+ this.batchDraw();
18941
19120
  };
18942
19121
  SourcesLayer.prototype._onSourcesAdd = function (sources) {
18943
19122
  var self = this;
@@ -18957,21 +19136,21 @@ module.exports = function (SourceGroup, LineGroups, DataRetriever, Invoker, Util
18957
19136
  self._removeSource(source);
18958
19137
  });
18959
19138
  this._view.updateTimelineLength();
18960
- this._layer.draw();
19139
+ this._layer.batchDraw();
18961
19140
  };
18962
19141
  SourcesLayer.prototype._onSourcesShow = function (sources) {
18963
19142
  var self = this;
18964
19143
  sources.forEach(function (source) {
18965
19144
  self._sourcesGroup[source.id].setWrapping(false, true);
18966
19145
  });
18967
- this._layer.draw();
19146
+ this._layer.batchDraw();
18968
19147
  };
18969
19148
  SourcesLayer.prototype._onSourcesHide = function (sources) {
18970
19149
  var self = this;
18971
19150
  sources.forEach(function (source) {
18972
19151
  self._sourcesGroup[source.id].setWrapping(true, true);
18973
19152
  });
18974
- this._layer.draw();
19153
+ this._layer.batchDraw();
18975
19154
  };
18976
19155
  SourcesLayer.prototype._onDataRetrieved = function (data, source, url) {
18977
19156
  if (data) {
@@ -19000,7 +19179,7 @@ module.exports = function (SourceGroup, LineGroups, DataRetriever, Invoker, Util
19000
19179
  SourcesLayer.prototype._onSegmentsShow = function (segmentsGroupId, lineId) {
19001
19180
  this._lineGroups.addSegments(segmentsGroupId, lineId);
19002
19181
  this._view.updateTimelineLength();
19003
- this._layer.draw();
19182
+ this._layer.batchDraw();
19004
19183
  };
19005
19184
  SourcesLayer.prototype._createSourceGroup = function (source) {
19006
19185
  return new SourceGroup(source, this._peaks, this, this._view);
@@ -19018,7 +19197,7 @@ module.exports = function (SourceGroup, LineGroups, DataRetriever, Invoker, Util
19018
19197
  var sourceGroup = this._sourcesGroup[source.id];
19019
19198
  if (sourceGroup) {
19020
19199
  sourceGroup.createIndicators();
19021
- this._layer.draw();
19200
+ this._layer.batchDraw();
19022
19201
  }
19023
19202
  };
19024
19203
  SourcesLayer.prototype.updateSources = function (startTime, endTime) {
@@ -19028,19 +19207,19 @@ module.exports = function (SourceGroup, LineGroups, DataRetriever, Invoker, Util
19028
19207
  sources.forEach(this._updateSource.bind(this));
19029
19208
  count += this._removeInvisibleSources(startTime, endTime);
19030
19209
  if (count > 0) {
19031
- this._layer.draw();
19210
+ this._layer.batchDraw();
19032
19211
  }
19033
19212
  };
19034
19213
  SourcesLayer.prototype.onSourcesGroupDragStart = function (element) {
19035
19214
  this._initialTimeOffset = this._view.getTimeOffset();
19036
19215
  this._mouseDownX = this._view.getPointerPosition().x;
19037
- const draggedElementId = element.currentTarget.attrs.sourceId;
19216
+ this._draggedElementId = element.currentTarget.attrs.sourceId;
19038
19217
  var selectedElements = this._view.getSelectedElements();
19039
- const shouldDragSelectedElements = Object.keys(selectedElements).includes(draggedElementId);
19218
+ const shouldDragSelectedElements = Object.keys(selectedElements).includes(this._draggedElementId);
19040
19219
  if (shouldDragSelectedElements) {
19041
19220
  this._draggedElements = Object.values(selectedElements).sort((a, b) => a.startTime - b.startTime);
19042
19221
  } else {
19043
- this._draggedElements = [this._sourcesGroup[draggedElementId].getSource()];
19222
+ this._draggedElements = [this._sourcesGroup[this._draggedElementId].getSource()];
19044
19223
  this._view.deselectAll();
19045
19224
  }
19046
19225
  this._draggedElementsData = this._draggedElements.reduce(function (bounds, source) {
@@ -19064,7 +19243,8 @@ module.exports = function (SourceGroup, LineGroups, DataRetriever, Invoker, Util
19064
19243
  }
19065
19244
  return source;
19066
19245
  }.bind(this));
19067
- this._view.drawSourcesLayer();
19246
+ this._draggedElementId = null;
19247
+ this._view.batchDrawSourcesLayer();
19068
19248
  this._view.updateTimelineLength();
19069
19249
  this._peaks.emit('sources.updated', updatedSources);
19070
19250
  };
@@ -19087,7 +19267,7 @@ module.exports = function (SourceGroup, LineGroups, DataRetriever, Invoker, Util
19087
19267
  }
19088
19268
  const shouldRedraw = this.manageSourceMovements(this._draggedElements, initialStartTime + timeOffsetDiff + timeDiff, initialEndTime + timeOffsetDiff + timeDiff, orderable, mousePosX, mousePosY);
19089
19269
  if (shouldRedraw) {
19090
- this.draw();
19270
+ this.batchDraw();
19091
19271
  }
19092
19272
  };
19093
19273
  SourcesLayer.prototype.findSources = function (startTime, endTime) {
@@ -19212,8 +19392,8 @@ module.exports = function (SourceGroup, LineGroups, DataRetriever, Invoker, Util
19212
19392
  SourcesLayer.prototype.setVisible = function (visible) {
19213
19393
  this._layer.setVisible(visible);
19214
19394
  };
19215
- SourcesLayer.prototype.draw = function () {
19216
- this._layer.draw();
19395
+ SourcesLayer.prototype.batchDraw = function () {
19396
+ this._layer.batchDraw();
19217
19397
  };
19218
19398
  SourcesLayer.prototype.listening = function (bool) {
19219
19399
  this._layer.listening(bool);
@@ -19255,7 +19435,7 @@ module.exports = function (SourceGroup, LineGroups, DataRetriever, Invoker, Util
19255
19435
  });
19256
19436
  }
19257
19437
  }
19258
- this._layer.draw();
19438
+ this._layer.batchDraw();
19259
19439
  };
19260
19440
  SourcesLayer.prototype._shouldResampleAudio = function (audioUrl, urls) {
19261
19441
  return this._loadedData[audioUrl + '-scaled'] && !urls.includes(audioUrl) && this._loadedData[audioUrl + '-scaled'].scale !== this._view.getTimeToPixelsScale();
@@ -19272,6 +19452,7 @@ module.exports = function (SourceGroup, LineGroups, DataRetriever, Invoker, Util
19272
19452
  this._peaks.off('data.retrieved', this._onDataRetrieved);
19273
19453
  this._peaks.off('handler.segments.show', this._onSegmentsShow);
19274
19454
  this._peaks.off('model.source.setIndicators', this.setIndicators);
19455
+ this._peaks.off('handler.view.mouseup', this._stopDrag);
19275
19456
  };
19276
19457
  SourcesLayer.prototype.getHeight = function () {
19277
19458
  return this._layer.getHeight();
@@ -19318,6 +19499,12 @@ module.exports = function () {
19318
19499
  module.exports = function (WaveformData, Utils) {
19319
19500
  'use strict';
19320
19501
  var isXhr2 = 'withCredentials' in new XMLHttpRequest();
19502
+ function scheduleIdle(fn) {
19503
+ if (typeof window !== 'undefined' && window.requestIdleCallback) {
19504
+ return window.requestIdleCallback(fn, { timeout: 80 });
19505
+ }
19506
+ return setTimeout(fn, 0);
19507
+ }
19321
19508
  function WaveformBuilder(peaks) {
19322
19509
  this._peaks = peaks;
19323
19510
  }
@@ -19382,12 +19569,18 @@ module.exports = function (WaveformData, Utils) {
19382
19569
  callback(new Error('Unable to fetch remote data. HTTP status ' + this.status));
19383
19570
  return;
19384
19571
  }
19385
- var waveformData = WaveformData.create(event.target.response);
19386
- if (waveformData.channels !== 1 && waveformData.channels !== 2) {
19387
- callback(new Error('Peaks.init(): Only mono or stereo waveforms are currently supported'));
19388
- return;
19389
- }
19390
- callback(null, waveformData);
19572
+ scheduleIdle(function () {
19573
+ try {
19574
+ var waveformData = WaveformData.create(event.target.response);
19575
+ if (waveformData.channels !== 1 && waveformData.channels !== 2) {
19576
+ callback(new Error('Peaks.init(): Only mono or stereo waveforms are currently supported'));
19577
+ return;
19578
+ }
19579
+ callback(null, waveformData);
19580
+ } catch (err) {
19581
+ callback(err);
19582
+ }
19583
+ });
19391
19584
  }, function () {
19392
19585
  callback(new Error('XHR Failed'));
19393
19586
  });
@@ -19411,16 +19604,18 @@ module.exports = function (WaveformData, Utils) {
19411
19604
  callback(new Error('Peaks.init(): Unable to determine a compatible waveformData format'));
19412
19605
  return;
19413
19606
  }
19414
- try {
19415
- var createdWaveformData = WaveformData.create(data);
19416
- if (createdWaveformData.channels !== 1 && createdWaveformData.channels !== 2) {
19417
- callback(new Error('Peaks.init(): Only mono or stereo waveforms are currently supported'));
19418
- return;
19607
+ scheduleIdle(function () {
19608
+ try {
19609
+ var createdWaveformData = WaveformData.create(data);
19610
+ if (createdWaveformData.channels !== 1 && createdWaveformData.channels !== 2) {
19611
+ callback(new Error('Peaks.init(): Only mono or stereo waveforms are currently supported'));
19612
+ return;
19613
+ }
19614
+ callback(null, createdWaveformData);
19615
+ } catch (err) {
19616
+ callback(err);
19419
19617
  }
19420
- callback(null, createdWaveformData);
19421
- } catch (err) {
19422
- callback(err);
19423
- }
19618
+ });
19424
19619
  };
19425
19620
  WaveformBuilder.prototype._buildWaveformDataUsingWebAudio = function (options, callback) {
19426
19621
  var self = this;
@@ -21661,7 +21856,6 @@ module.exports = function (Source, Utils) {
21661
21856
  this._peaks = peaks;
21662
21857
  this._sources = [];
21663
21858
  this._sourcesById = {};
21664
- this._sourcesByLineId = {};
21665
21859
  this._colorIndex = 0;
21666
21860
  }
21667
21861
  SourceHandler.prototype.cutSource = function (sourceToCut, cuttingTime) {
@@ -21741,10 +21935,6 @@ module.exports = function (Source, Utils) {
21741
21935
  SourceHandler.prototype._addSource = function (source) {
21742
21936
  this._sources.push(source);
21743
21937
  this._sourcesById[source.id] = source;
21744
- if (Utils.isNullOrUndefined(this._sourcesByLineId[source.lineId])) {
21745
- this._sourcesByLineId[source.lineId] = {};
21746
- }
21747
- this._sourcesByLineId[source.lineId][source.id] = source;
21748
21938
  };
21749
21939
  SourceHandler.prototype._createSource = function (options) {
21750
21940
  if (!Utils.isObject(options)) {
@@ -21762,9 +21952,6 @@ module.exports = function (Source, Utils) {
21762
21952
  SourceHandler.prototype.getSources = function () {
21763
21953
  return this._sources;
21764
21954
  };
21765
- SourceHandler.prototype.getSourcesByLineId = function (lineId) {
21766
- return Utils.isNullOrUndefined(lineId) ? this._sourcesByLineId : this._sourcesByLineId[lineId];
21767
- };
21768
21955
  SourceHandler.prototype.getSourcesSerialized = function () {
21769
21956
  return this._sources.map(function (source) {
21770
21957
  return source.toSerializable();
@@ -21821,7 +22008,6 @@ module.exports = function (Source, Utils) {
21821
22008
  var index = indexes[i] - destroyed.length;
21822
22009
  var itemDestroyed = this._sources.splice(index, 1)[0];
21823
22010
  delete this._sourcesById[itemDestroyed.id];
21824
- delete this._sourcesByLineId[itemDestroyed.lineId][itemDestroyed.id];
21825
22011
  destroyed.push(itemDestroyed);
21826
22012
  }
21827
22013
  return destroyed;
@@ -22231,6 +22417,7 @@ module.exports = function (MouseDragHandler, PlayheadLayer, SourcesLayer, ModeLa
22231
22417
  }
22232
22418
  View.prototype._mouseUp = function () {
22233
22419
  this.clearScrollingInterval();
22420
+ this._peaks.emit('handler.view.mouseup');
22234
22421
  };
22235
22422
  View.prototype.setClickable = function (clickable) {
22236
22423
  this._isClickable = clickable;
@@ -22286,11 +22473,11 @@ module.exports = function (MouseDragHandler, PlayheadLayer, SourcesLayer, ModeLa
22286
22473
  View.prototype.overrideInteractions = function (areInteractionsAllowed) {
22287
22474
  this._playheadLayer.listening(areInteractionsAllowed);
22288
22475
  this._sourcesLayer.stopDrag();
22289
- this._sourcesLayer.draw();
22476
+ this._sourcesLayer.batchDraw();
22290
22477
  };
22291
22478
  View.prototype.allowInteractions = function () {
22292
22479
  this._sourcesLayer.stopDrag();
22293
- this._sourcesLayer.draw();
22480
+ this._sourcesLayer.batchDraw();
22294
22481
  };
22295
22482
  View.prototype.getSelectedElements = function () {
22296
22483
  return this._modeLayer.getSelectedElements();
@@ -22319,8 +22506,8 @@ module.exports = function (MouseDragHandler, PlayheadLayer, SourcesLayer, ModeLa
22319
22506
  View.prototype.isFocused = function () {
22320
22507
  return this._isFocused;
22321
22508
  };
22322
- View.prototype.drawSourcesLayer = function () {
22323
- this._sourcesLayer.draw();
22509
+ View.prototype.batchDrawSourcesLayer = function () {
22510
+ this._sourcesLayer.batchDraw();
22324
22511
  };
22325
22512
  View.prototype.refresh = function () {
22326
22513
  this._sourcesLayer.refresh();
@@ -22545,7 +22732,7 @@ module.exports = function (MouseDragHandler, PlayheadLayer, SourcesLayer, ModeLa
22545
22732
  this.setFrameOffset(frameOffset);
22546
22733
  const playheadPixel = this._playheadLayer.getPlayheadPixel();
22547
22734
  this._playheadLayer.updatePlayheadTime(this.pixelsToTime(playheadPixel));
22548
- this._axis.draw();
22735
+ this._axis.batchDraw();
22549
22736
  }
22550
22737
  const frameStartTime = this.pixelsToTime(this._frameOffset);
22551
22738
  const frameEndTime = this.pixelsToTime(this._frameOffset + this._width);
@@ -22599,7 +22786,7 @@ module.exports = function (MouseDragHandler, PlayheadLayer, SourcesLayer, ModeLa
22599
22786
  this._sourcesLayer.fitToView();
22600
22787
  this._playheadLayer.fitToView();
22601
22788
  this.updateTimeline(this._frameOffset);
22602
- this._stage.draw();
22789
+ this._stage.batchDraw();
22603
22790
  }
22604
22791
  };
22605
22792
  View.prototype.getFullHeight = function () {