@checksub_team/peaks_timeline 1.8.3 → 1.9.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/src/line.js CHANGED
@@ -655,6 +655,28 @@ define([
655
655
  // }
656
656
  // };
657
657
 
658
+ Line.prototype.getSourcesAfter = function(time) {
659
+ const sources = [];
660
+ var currentId = this._firstSourceId;
661
+
662
+ while (currentId) {
663
+ var lineSource = this._sources[currentId];
664
+
665
+ if (lineSource.source.startTime >= time) {
666
+ while (currentId) {
667
+ lineSource = this._sources[currentId];
668
+
669
+ sources.push(lineSource.source);
670
+ currentId = lineSource.nextSourceId;
671
+ }
672
+ break;
673
+ }
674
+ currentId = lineSource.nextSourceId;
675
+ }
676
+
677
+ return sources;
678
+ };
679
+
658
680
  Line.prototype.updatePosition = function(pos) {
659
681
  for (var sourceId in this._sources) {
660
682
  if (Utils.objectHasProperty(this._sources, sourceId)) {
package/src/lines.js CHANGED
@@ -185,6 +185,10 @@ define([
185
185
  return positions;
186
186
  };
187
187
 
188
+ Lines.prototype.getSourcesOnLineAfter = function(lineId, time) {
189
+ return this._linesByPosition[lineId].getSourcesAfter(time);
190
+ };
191
+
188
192
  Lines.prototype.getSegmentsGroups = function() {
189
193
  return this._segmentsGroups;
190
194
  };
package/src/main.js CHANGED
@@ -715,14 +715,24 @@ define([
715
715
  .allowInteractions(forSources, forSegments);
716
716
  };
717
717
 
718
+ Peaks.prototype.getSelectedElements = function() {
719
+ return this.view
720
+ .getSelectedElements();
721
+ };
722
+
718
723
  Peaks.prototype.selectSourceById = function(sourceId) {
719
724
  return this.view
720
725
  .selectSourceById(sourceId);
721
726
  };
722
727
 
723
- Peaks.prototype.deselectSource = function() {
728
+ Peaks.prototype.selectSourcesOnLineAfter = function(lineId, time) {
729
+ return this.view
730
+ .selectSourcesOnLineAfter(lineId, time);
731
+ };
732
+
733
+ Peaks.prototype.deselectAll = function() {
724
734
  return this.view
725
- .deselectElement();
735
+ .deselectAll();
726
736
  };
727
737
 
728
738
  Peaks.prototype._addWindowResizeHandler = function() {
package/src/mode-layer.js CHANGED
@@ -8,9 +8,10 @@
8
8
 
9
9
  define([
10
10
  './utils',
11
+ './source',
11
12
  './source-group',
12
13
  'konva'
13
- ], function(Utils, SourceGroup, Konva) {
14
+ ], function(Utils, Source, SourceGroup, Konva) {
14
15
  'use strict';
15
16
 
16
17
  var TIME_X_OFFSET = 20;
@@ -34,6 +35,9 @@ define([
34
35
  this._playheadLayer = playheadLayer;
35
36
  this._stage = stage;
36
37
 
38
+ this._selectedElements = {};
39
+ this._currentLine = null;
40
+
37
41
  this._layer = new Konva.Layer({
38
42
  listening: this._mode !== 'default'
39
43
  });
@@ -63,37 +67,71 @@ define([
63
67
  stage.add(this._layer);
64
68
  };
65
69
 
66
- ModeLayer.prototype.selectElement = function(element, notify) {
67
- this.deselectElement(notify);
68
- if (element) {
69
- this._selectedElement = element;
70
- this._selectedElement.setSelected(true);
70
+ ModeLayer.prototype.selectElements = function(elements, notify) {
71
+ const sources = [];
72
+ const segments = [];
73
+ const self = this;
74
+
75
+ this.deselectAll(true);
76
+
77
+ elements.forEach(function(element) {
78
+ self._selectedElements[element.id] = element;
79
+ element.setSelected(true);
71
80
  if (notify) {
72
- if (element instanceof SourceGroup) {
73
- this._peaks.emit('source.selected', this._selectedElement.getSource());
81
+ if (element instanceof Source) {
82
+ sources.push(element);
74
83
  }
75
84
  else {
76
- this._peaks.emit('segment.selected', this._selectedElement.getSegment());
85
+ segments.push(element);
77
86
  }
78
87
  }
88
+ });
89
+
90
+ if (notify) {
91
+ if (sources.length) {
92
+ this._peaks.emit('sources.selected', sources);
93
+ }
94
+ if (segments.length) {
95
+ this._peaks.emit('segments.selected', segments);
96
+ }
79
97
  }
80
98
  };
81
99
 
82
- ModeLayer.prototype.deselectElement = function(notify) {
83
- if (this._selectedElement) {
84
- this._selectedElement.setSelected(false);
85
- if (notify) {
86
- if (this._selectedElement instanceof SourceGroup) {
87
- this._peaks.emit('source.deselected', this._selectedElement.getSource());
88
- }
89
- else {
90
- this._peaks.emit('segment.deselected', this._selectedElement.getSegment());
100
+ ModeLayer.prototype.deselectAll = function(notify) {
101
+ const sources = [];
102
+ const segments = [];
103
+
104
+ for (var id in this._selectedElements) {
105
+ if (Utils.objectHasProperty(this._selectedElements, id)) {
106
+ const element = this._selectedElements[id];
107
+
108
+ element.setSelected(false);
109
+ if (notify) {
110
+ if (element instanceof Source) {
111
+ sources.push(element);
112
+ }
113
+ else {
114
+ segments.push(element);
115
+ }
91
116
  }
117
+ delete this._selectedElements[id];
118
+ }
119
+ }
120
+
121
+ if (notify) {
122
+ if (sources.length) {
123
+ this._peaks.emit('sources.deselected', sources);
124
+ }
125
+ if (segments.length) {
126
+ this._peaks.emit('segments.deselected', segments);
92
127
  }
93
- this._selectedElement = null;
94
128
  }
95
129
  };
96
130
 
131
+ ModeLayer.prototype.getSelectedElements = function() {
132
+ return this._selectedElements;
133
+ };
134
+
97
135
  ModeLayer.prototype._prepareDefaultMode = function() {
98
136
  this._selectedElement = null;
99
137
  };
@@ -149,30 +187,39 @@ define([
149
187
  };
150
188
 
151
189
  ModeLayer.prototype._onMouseClickInDefaultMode = function() {
152
- var hoveredElement = this._view.getHoveredElement();
190
+ const hoveredKonvaElement = this._view.getHoveredElement();
153
191
 
154
- if (hoveredElement) {
155
- this.selectElement(hoveredElement, true);
192
+ if (hoveredKonvaElement) {
193
+ if (hoveredKonvaElement instanceof SourceGroup) {
194
+ this.selectElements([hoveredKonvaElement.getSource()], true);
195
+ }
196
+ else {
197
+ this.selectElements([hoveredKonvaElement.getSegment()], true);
198
+ }
156
199
  }
157
200
  else {
158
- this.deselectElement(true);
201
+ this.deselectAll(true);
202
+ this._view.drawSourcesLayer(); // Redraw sources layer to remove selection
159
203
  }
160
204
  };
161
205
 
162
206
  ModeLayer.prototype._onKeyboardDelete = function() {
163
- if (this._selectedElement) {
164
- var selectedElement = this._selectedElement;
207
+ const selectedElements = Object.values(this._selectedElements);
208
+
209
+ // We allow deletion if there is ONLY 1 element selected
210
+ if (selectedElements.length) {
211
+ var selectedElement = selectedElements[0];
165
212
 
166
- this.deselectElement(true);
213
+ this.deselectAll(true);
167
214
 
168
- if (selectedElement instanceof SourceGroup) {
215
+ if (selectedElement instanceof Source) {
169
216
  if (selectedElement.isDeletable()) {
170
- this._peaks.destroySource(selectedElement.getSource().id);
217
+ this._peaks.destroySource(selectedElement.id);
171
218
  }
172
219
  }
173
220
  else {
174
221
  if (selectedElement.getSegment().allowDeletion) {
175
- this._peaks.destroySegment(selectedElement.getSegment().id);
222
+ this._peaks.destroySegment(selectedElement.id);
176
223
  }
177
224
  }
178
225
  }
@@ -379,7 +426,7 @@ define([
379
426
  break;
380
427
  }
381
428
 
382
- this.deselectElement(true);
429
+ this.deselectAll(true);
383
430
 
384
431
  // Set new mode
385
432
  switch (mode) {
@@ -139,8 +139,7 @@ define([
139
139
  )
140
140
  );
141
141
 
142
- var autoPos = self._view.updateWithAutoScroll(
143
- this,
142
+ self._view.updateWithAutoScroll(
144
143
  function() {
145
144
  time = Math.max(
146
145
  0,
@@ -157,8 +156,8 @@ define([
157
156
  );
158
157
 
159
158
  return {
160
- x: autoPos.x,
161
- y: autoPos.y
159
+ x: Math.max(pos.x, 0),
160
+ y: 0
162
161
  };
163
162
  }
164
163
  });
@@ -180,7 +179,6 @@ define([
180
179
  PlayheadLayer.prototype._onPlayheadDragStart = function() {
181
180
  this._view.enableAutoScroll(false);
182
181
  this._dragging = true;
183
- this._scrollInterval = null;
184
182
  };
185
183
 
186
184
  PlayheadLayer.prototype._onPlayheadDragEnd = function() {
@@ -46,7 +46,6 @@ define([
46
46
  this._endMarker = null;
47
47
  this._shapeGroup = null;
48
48
  this._rectangle = null;
49
- this._isSelected = false;
50
49
  this._indicators = {};
51
50
 
52
51
  var self = this;
@@ -89,20 +88,7 @@ define([
89
88
  this._shapeGroup.add(this._rectangle);
90
89
 
91
90
  this._shapeGroup.dragBoundFunc(function() {
92
- var diff = self._view.getPointerPosition().x - self._mouseDownX;
93
-
94
- self._group.updateSegment(
95
- self._segment,
96
- self._initialStartPixel + diff, self._initialEndPixel + diff
97
- );
98
-
99
- self._startMarker.timeUpdated(self._segment.startTime);
100
- self._endMarker.timeUpdated(self._segment.endTime);
101
-
102
- return {
103
- x: this.absolutePosition().x,
104
- y: this.absolutePosition().y
105
- };
91
+ return self._onShapeGroupDrag(this);
106
92
  });
107
93
 
108
94
  // Set up event handlers to show/hide the segment label text when the user
@@ -138,6 +124,23 @@ define([
138
124
  this.createIndicators();
139
125
  }
140
126
 
127
+ SegmentShape.prototype._onShapeGroupDrag = function(draggedElement) {
128
+ const diff = this._view.getPointerPosition().x - this._mouseDownX;
129
+
130
+ this._group.updateSegment(
131
+ this._segment,
132
+ this._initialStartPixel + diff, this._initialEndPixel + diff
133
+ );
134
+
135
+ this._startMarker.timeUpdated(this._segment.startTime);
136
+ this._endMarker.timeUpdated(this._segment.endTime);
137
+
138
+ return {
139
+ x: draggedElement.absolutePosition().x,
140
+ y: draggedElement.absolutePosition().y
141
+ };
142
+ };
143
+
141
144
  SegmentShape.prototype._cornerRadius = function() {
142
145
  return this._segment.borderRadius !== undefined && this._segment.borderRadius !== null ?
143
146
  this._segment.borderRadius :
@@ -452,10 +455,6 @@ define([
452
455
  this._peaks.emit('segments.dragend', this._segment, startMarker);
453
456
  };
454
457
 
455
- SegmentShape.prototype.setSelected = function(isSelected) {
456
- this._isSelected = isSelected;
457
- };
458
-
459
458
  SegmentShape.prototype.fitToView = function() {
460
459
  if (this._startMarker) {
461
460
  this._startMarker.fitToView();
package/src/segment.js CHANGED
@@ -150,6 +150,7 @@ define([
150
150
  this._indicators = opts.indicators;
151
151
  this._minSize = peaks.options.minSegmentSize;
152
152
  this._relativeId = 0;
153
+ this._selected = false;
153
154
 
154
155
  if (shouldNotifyUpdate) {
155
156
  peaks.emit('segments.updated', [this]);
@@ -340,6 +341,11 @@ define([
340
341
  this._peaks.emit('segment.updated', this);
341
342
  };
342
343
 
344
+ Segment.prototype.setSelected = function(selected) {
345
+ this._selected = selected;
346
+ // this._peaks.emit('segment.update', this); // It's currently useless
347
+ };
348
+
343
349
  /**
344
350
  * Returns <code>true</code> if the segment overlaps a given time region.
345
351
  *
@@ -58,16 +58,16 @@ define([
58
58
 
59
59
  this._group = new Konva.Group({
60
60
  x: this._x,
61
+ sourceId: this._source.id,
61
62
  draggable: this._source.draggable,
62
63
  dragBoundFunc: function() {
63
- return {
64
- x: this.absolutePosition().x,
65
- y: this.absolutePosition().y
66
- };
64
+ return self._layer.onSourcesGroupDrag(this);
67
65
  }
68
66
  });
69
67
 
70
- this._group.on('dragstart', this._onSourceGroupDragStart.bind(this));
68
+ this._group.on('dragstart', this._layer.onSourcesGroupDragStart.bind(this._layer));
69
+ this._group.on('dragend', this._layer.onSourcesGroupDragEnd.bind(this._layer));
70
+
71
71
  this._group.on('mouseover', function() {
72
72
  self._view.setHoveredElement(self);
73
73
  if (self._view.getCurrentMode() === 'cut') {
@@ -82,7 +82,6 @@ define([
82
82
  self.toggleResizing(true);
83
83
  }
84
84
  });
85
- this._group.on('dragend', this._onSourceGroupDragEnd.bind(this));
86
85
 
87
86
  this._group.add(new Konva.Group());
88
87
 
@@ -99,6 +98,8 @@ define([
99
98
 
100
99
  this.setWrapping(source.wrapped);
101
100
 
101
+ this._setSelected();
102
+
102
103
  this._indicatorsGroup = new Konva.Group();
103
104
  this._group.add(this._indicatorsGroup);
104
105
 
@@ -123,78 +124,25 @@ define([
123
124
  // });
124
125
  // };
125
126
 
126
- SourceGroup.prototype._onSourceGroupDragStart = function() {
127
- this._dragged = true;
128
- this._mouseDownX = this._view.getPointerPosition().x;
129
- this._initialStartTime = this._source.startTime;
130
- this._initialStartPixel = this._view.timeToPixels(this._initialStartTime);
131
- this._initialEndTime = this._source.endTime;
132
- this._initialEndPixel = this._view.timeToPixels(this._initialEndTime);
133
- this._initialFrameOffset = this._view.getFrameOffset();
134
- };
135
-
136
- SourceGroup.prototype._onSourceGroupDragEnd = function() {
127
+ SourceGroup.prototype.prepareDragEnd = function() {
137
128
  var handleWidth = Math.min(this._peaks.options.sourceHandleWidth, this._width / 2);
138
129
 
139
130
  this._leftHandle.width(handleWidth);
140
131
  this._rightHandle.width(handleWidth);
141
132
  this._rightHandle.x(this._width - handleWidth);
142
-
143
- this._view.drawSourcesLayer();
144
-
145
- this._dragged = false;
146
- this._view.updateTimelineLength();
147
-
148
- this._peaks.emit('sources.updated', [this._source]);
149
- };
150
-
151
- SourceGroup.prototype._onSourceGroupDrag = function(draggedElement) {
152
- var self = this;
153
-
154
- var pos = this._view.updateWithAutoScroll(
155
- draggedElement,
156
- function() {
157
- var mousePos = Math.min(
158
- self._view.getWidth() - self._peaks.options.autoScrollThreshold * self._view.getWidth(),
159
- Math.max(
160
- 0,
161
- self._view.getPointerPosition().x
162
- )
163
- );
164
-
165
- var diff = mousePos - self._mouseDownX;
166
-
167
- self._layer.updateSource(
168
- self._source,
169
- self._initialStartPixel + diff + (self._view.getFrameOffset() - self._initialFrameOffset),
170
- self._initialEndPixel + diff + (self._view.getFrameOffset() - self._initialFrameOffset),
171
- self._view.getPointerPosition().y
172
- );
173
-
174
- self._view.setTimelineLength(
175
- self._view.timeToPixels(self._source.endTime) + self._view.getWidth()
176
- );
177
- }
178
- );
179
-
180
- return {
181
- x: pos.x,
182
- y: pos.y
183
- };
184
133
  };
185
134
 
186
135
  SourceGroup.prototype._onSourceGroupHandleDrag = function(draggedElement, dragPos, leftHandle) {
187
- var self = this;
188
-
189
- var pos = this._view.updateWithAutoScroll(
190
- draggedElement,
136
+ this._view.updateWithAutoScroll(
191
137
  function() {
192
- self._layer.updateSource(
193
- self._source,
194
- leftHandle ? dragPos.x + self._view.getFrameOffset() : null,
195
- leftHandle ? null : dragPos.x + draggedElement.width() + self._view.getFrameOffset()
196
- );
197
- }
138
+ if (this._layer.updateSource(
139
+ this._source,
140
+ leftHandle ? dragPos.x + this._view.getFrameOffset() : null,
141
+ leftHandle ? null : dragPos.x + draggedElement.width() + this._view.getFrameOffset()
142
+ )) {
143
+ this._layer.draw();
144
+ }
145
+ }.bind(this)
198
146
  );
199
147
 
200
148
  this._view.setTimelineLength(
@@ -202,8 +150,8 @@ define([
202
150
  );
203
151
 
204
152
  return {
205
- x: pos.x,
206
- y: pos.y
153
+ x: draggedElement.absolutePosition().x,
154
+ y: draggedElement.absolutePosition().y
207
155
  };
208
156
  };
209
157
 
@@ -273,13 +221,6 @@ define([
273
221
  });
274
222
 
275
223
  if (this._source.resizable) {
276
- this._leftHandle.on('dragend', function() {
277
- if (this._scrollingInterval) {
278
- clearInterval(this._scrollingInterval);
279
- this._scrollingInterval = null;
280
- }
281
- });
282
-
283
224
  this._leftHandle.on('mouseover', function() {
284
225
  self._view.setCursor('ew-resize');
285
226
  });
@@ -303,13 +244,6 @@ define([
303
244
  });
304
245
 
305
246
  if (this._source.resizable) {
306
- this._rightHandle.on('dragend', function() {
307
- if (this._scrollingInterval) {
308
- clearInterval(this._scrollingInterval);
309
- this._scrollingInterval = null;
310
- }
311
- });
312
-
313
247
  this._rightHandle.on('mouseover', function() {
314
248
  self._view.setCursor('ew-resize');
315
249
  });
@@ -419,13 +353,6 @@ define([
419
353
  var unwrap = new Konva.Group({
420
354
  width: this._width,
421
355
  height: this._unwrappedHeight,
422
- draggable: this._source.draggable,
423
- dragBoundFunc: function() {
424
- return {
425
- x: this.absolutePosition().x,
426
- y: this.absolutePosition().y
427
- };
428
- },
429
356
  clipFunc: function(ctx) {
430
357
  self.drawSourceShape(ctx, null, true);
431
358
  }
@@ -438,17 +365,6 @@ define([
438
365
  unwrap.on('mouseout', function() {
439
366
  self._view.setCursor('default');
440
367
  });
441
-
442
- unwrap.on('dragstart', function() {
443
- this._scrollInterval = null;
444
- });
445
-
446
- unwrap.on('dragend', function() {
447
- if (this._scrollingInterval) {
448
- clearInterval(this._scrollingInterval);
449
- this._scrollingInterval = null;
450
- }
451
- });
452
368
  }
453
369
 
454
370
  var background = new Konva.Group();
@@ -457,10 +373,6 @@ define([
457
373
  fill: this._source.backgroundColor,
458
374
  sceneFunc: function(ctx, shape) {
459
375
  self.drawSourceShape(ctx, shape, true);
460
- },
461
- draggable: this._source.draggable,
462
- dragBoundFunc: function() {
463
- return self._onSourceGroupDrag(this);
464
376
  }
465
377
  }));
466
378
 
@@ -499,13 +411,6 @@ define([
499
411
  var wrap = new Konva.Group({
500
412
  width: this._width,
501
413
  height: this._wrappedHeight,
502
- draggable: this._source.draggable,
503
- dragBoundFunc: function() {
504
- return {
505
- x: this.absolutePosition().x,
506
- y: this.absolutePosition().y
507
- };
508
- },
509
414
  clipFunc: function(ctx) {
510
415
  self.drawSourceShape(ctx, null, true);
511
416
  }
@@ -518,17 +423,6 @@ define([
518
423
  wrap.on('mouseout', function() {
519
424
  self._view.setCursor('default');
520
425
  });
521
-
522
- wrap.on('dragstart', function() {
523
- this._scrollInterval = null;
524
- });
525
-
526
- wrap.on('dragend', function() {
527
- if (this._scrollingInterval) {
528
- clearInterval(this._scrollingInterval);
529
- this._scrollingInterval = null;
530
- }
531
- });
532
426
  }
533
427
 
534
428
  var background = new Konva.Group();
@@ -537,10 +431,6 @@ define([
537
431
  fill: this._source.backgroundColor,
538
432
  sceneFunc: function(ctx, shape) {
539
433
  self.drawSourceShape(ctx, shape, true);
540
- },
541
- draggable: this._source.draggable,
542
- dragBoundFunc: function() {
543
- return self._onSourceGroupDrag(this);
544
434
  }
545
435
  }));
546
436
 
@@ -851,9 +741,9 @@ define([
851
741
  });
852
742
  };
853
743
 
854
- SourceGroup.prototype.setSelected = function(isSelected) {
744
+ SourceGroup.prototype._setSelected = function() {
855
745
  if (this._border) {
856
- if (isSelected) {
746
+ if (this._source._selected) {
857
747
  this._border.fill(this._source.selectedColor);
858
748
  this._borderWidth = this._peaks.options.sourceSelectedBorderWidth;
859
749
  }
@@ -870,7 +760,7 @@ define([
870
760
  });
871
761
 
872
762
  if (unwrap_background) {
873
- if (isSelected) {
763
+ if (this._source._selected) {
874
764
  unwrap_background.stroke(this._source.selectedColor);
875
765
  unwrap_background.strokeWidth(this._peaks.options.sourceSelectedBorderWidth);
876
766
  }
@@ -887,7 +777,7 @@ define([
887
777
  });
888
778
 
889
779
  if (wrap_background) {
890
- if (isSelected) {
780
+ if (this._source._selected) {
891
781
  wrap_background.stroke(this._source.selectedColor);
892
782
  wrap_background.strokeWidth(this._peaks.options.sourceSelectedBorderWidth);
893
783
  }
@@ -897,8 +787,7 @@ define([
897
787
  }
898
788
  }
899
789
  }
900
-
901
- this._view.drawSourcesLayer();
790
+ // this.setDraggingBehavior();
902
791
  };
903
792
 
904
793
  SourceGroup.prototype.updatePreviews = function() {
@@ -1032,10 +921,6 @@ define([
1032
921
  return this._group.visible();
1033
922
  };
1034
923
 
1035
- SourceGroup.prototype.isDragged = function() {
1036
- return this._dragged;
1037
- };
1038
-
1039
924
  SourceGroup.prototype.isCuttable = function() {
1040
925
  return this._source.cuttable;
1041
926
  };
@@ -1048,6 +933,10 @@ define([
1048
933
  this._group.destroy();
1049
934
  };
1050
935
 
936
+ SourceGroup.prototype.getLine = function() {
937
+ return this._source.position;
938
+ };
939
+
1051
940
  SourceGroup.prototype.createIndicators = function() {
1052
941
  var newIndicatorsColors = this._source.indicators;
1053
942
 
package/src/source.js CHANGED
@@ -354,6 +354,7 @@ define([
354
354
  this._binaryHeight = opts.binaryHeight;
355
355
  this._indicators = opts.indicators;
356
356
  this._minSize = peaks.options.minSourceSize;
357
+ this._selected = false;
357
358
  }
358
359
 
359
360
  Object.defineProperties(Source.prototype, {
@@ -864,6 +865,11 @@ define([
864
865
  this._peaks.emit('source.update', this);
865
866
  };
866
867
 
868
+ Source.prototype.setSelected = function(selected) {
869
+ this._selected = selected;
870
+ this._peaks.emit('source.update', this);
871
+ };
872
+
867
873
  /**
868
874
  * Returns <code>true</code> if the source overlaps a given time region.
869
875
  *