@checksub_team/peaks_timeline 1.4.35 → 1.4.36

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
@@ -1,678 +1,678 @@
1
- /**
2
- * @file
3
- *
4
- * Defines the {@link line} class.
5
- *
6
- * @module line
7
- */
8
-
9
- define([
10
- 'konva',
11
- './utils'
12
- ], function(Konva, Utils) {
13
- 'use strict';
14
-
15
- function Line(peaks, view, y, id, position) {
16
- this._peaks = peaks;
17
- this._view = view;
18
-
19
- this._id = id;
20
- this._position = position;
21
-
22
- this._firstSourceId = null;
23
- this._sources = {};
24
-
25
- this._sourcesGroup = {};
26
- this._wrapped = false;
27
- this._y = y;
28
-
29
- this._group = new Konva.Group({
30
- x: 0,
31
- y: y - this._view.getFrameOffsetY(),
32
- draggable: true,
33
- dragBoundFunc: function() {
34
- return {
35
- x: this.absolutePosition().x,
36
- y: this.absolutePosition().y
37
- };
38
- }
39
- });
40
-
41
- this._sourceHeights = {};
42
- this._height = this._peaks.options.emptyLineHeight;
43
- this._unwrappedCount = 0;
44
- }
45
-
46
- Line.prototype.getPosition = function() {
47
- return this._position;
48
- };
49
-
50
- Line.prototype.getId = function() {
51
- return this._id;
52
- };
53
-
54
- Line.prototype.isEmpty = function() {
55
- return Object.keys(this._sources).length === 0;
56
- };
57
-
58
- Line.prototype.isSegmentsLine = function() {
59
- return Boolean(this._segmentsGroup);
60
- };
61
-
62
- Line.prototype.updateSegments = function(frameStartTime, frameEndTime) {
63
- if (this.isSegmentsLine()) {
64
- this._segmentsGroup.updateSegments(frameStartTime, frameEndTime);
65
- }
66
- };
67
-
68
- Line.prototype.lineLength = function() {
69
- var length = 0;
70
-
71
- if (this.isSegmentsLine()) {
72
- return this._segmentsGroup.getSegmentsGroupLength();
73
- }
74
-
75
- for (var sourceId in this._sources) {
76
- if (Utils.objectHasProperty(this._sources, sourceId)) {
77
- var sourceGroupLength = this._view.timeToPixels(
78
- this._sources[sourceId].source.endTime
79
- );
80
-
81
- if (sourceGroupLength > length) {
82
- length = sourceGroupLength;
83
- }
84
- }
85
- }
86
-
87
- return length;
88
- };
89
-
90
- Line.prototype.lineHeight = function() {
91
- return this._height;
92
- };
93
-
94
- Line.prototype.changeHeight = function(from, to) {
95
- if (this._sourceHeights[from]) {
96
- var oldHeight = this._height;
97
-
98
- if (this._sourceHeights[to]) {
99
- this._sourceHeights[to] += this._sourceHeights[from];
100
- }
101
- else {
102
- this._sourceHeights[to] = this._sourceHeights[from];
103
- }
104
-
105
- if (to > this._height) {
106
- this._height = to;
107
- }
108
- else if (from === this._height) {
109
- this._height = 0;
110
- for (var height in this._sourceHeights) {
111
- if (Utils.objectHasProperty(this._sourceHeights, height)) {
112
- var parsedHeight = parseInt(height, 10);
113
-
114
- if (parsedHeight !== from) {
115
- if (parsedHeight > this._height) {
116
- this._height = parsedHeight;
117
- }
118
- }
119
- }
120
- }
121
- }
122
-
123
- if (this._height !== oldHeight) {
124
- this._peaks.emit('line.heightChanged', this._position);
125
- }
126
-
127
- delete this._sourceHeights[from];
128
- }
129
- };
130
-
131
- Line.prototype.updateLineHeight = function(sourceGroup, action) {
132
- var oldHeight = this._height;
133
- var sourceGroupHeight;
134
-
135
- switch (action) {
136
- case 'add':
137
- sourceGroupHeight = sourceGroup.getCurrentHeight();
138
-
139
- if (this._sourceHeights[sourceGroupHeight]) {
140
- this._sourceHeights[sourceGroupHeight]++;
141
- }
142
- else {
143
- this._sourceHeights[sourceGroupHeight] = 1;
144
- if (sourceGroupHeight > this._height) {
145
- this._height = sourceGroupHeight;
146
- }
147
- }
148
- break;
149
- case 'remove':
150
- if (Object.keys(this._sources).length === 0) {
151
- this._height = this._peaks.options.emptyLineHeight;
152
- this._sourceHeights = {};
153
- }
154
- else {
155
- sourceGroupHeight = sourceGroup.getCurrentHeight();
156
-
157
- this._sourceHeights[sourceGroupHeight]--;
158
-
159
- if (this._sourceHeights[sourceGroupHeight] === 0
160
- && sourceGroupHeight === this._height) {
161
- delete this._sourceHeights[sourceGroupHeight];
162
- this._height = 0;
163
- for (var height in this._sourceHeights) {
164
- if (Utils.objectHasProperty(this._sourceHeights, height)) {
165
- var parsedHeight = parseInt(height, 10);
166
-
167
- if (parsedHeight > this._height) {
168
- this._height = parsedHeight;
169
- }
170
- }
171
- }
172
- }
173
- }
174
- break;
175
- }
176
-
177
- if (this._height !== oldHeight) {
178
- this._peaks.emit('line.heightChanged', this._position);
179
- }
180
- };
181
-
182
- Line.prototype.isVisible = function() {
183
- return this._y < this._view.getFrameOffsetY() + this._view.getHeight()
184
- && this._view.getFrameOffsetY() < this._y + this._height;
185
- };
186
-
187
- Line.prototype.addToLayer = function(layer) {
188
- layer.add(this._group);
189
- };
190
-
191
- Line.prototype.addSourceGroup = function(sourceGroup) {
192
- var source = sourceGroup.getSource();
193
-
194
- this._sourcesGroup[source.id] = sourceGroup;
195
-
196
- if (!this._sources[source.id]) {
197
- var newSource = {
198
- source: source,
199
- prevSourceId: null,
200
- nextSourceId: null
201
- };
202
-
203
- if (this._firstSourceId) {
204
- var currentSource = null;
205
-
206
- do {
207
- if (!currentSource) {
208
- currentSource = this._sources[this._firstSourceId];
209
- }
210
- else {
211
- currentSource = this._sources[currentSource.nextSourceId];
212
- }
213
-
214
- if (source.endTime <= currentSource.source.startTime) {
215
- var startLimit = currentSource.prevSourceId
216
- ? this._sources[currentSource.prevSourceId].source.endTime
217
- : 0;
218
-
219
- var newTimes = this._canBePlacedBetween(
220
- source.startTime,
221
- source.endTime,
222
- startLimit,
223
- currentSource.source.startTime
224
- );
225
-
226
- if (newTimes) {
227
- source.updateTimes(newTimes.startTime, newTimes.endTime);
228
-
229
- if (currentSource.prevSourceId) {
230
- this._sources[currentSource.prevSourceId].nextSourceId = source.id;
231
- newSource.prevSourceId = currentSource.prevSourceId;
232
- }
233
- else {
234
- this._firstSourceId = source.id;
235
- }
236
-
237
- currentSource.prevSourceId = source.id;
238
- newSource.nextSourceId = currentSource.source.id;
239
-
240
- this._sources[source.id] = newSource;
241
- break;
242
- }
243
- }
244
- } while (currentSource.nextSourceId);
245
-
246
- if (!newSource.prevSourceId && !newSource.nextSourceId) {
247
- if (source.startTime < currentSource.source.endTime) {
248
- // Overlapping with last source
249
- var timeWidth = source.endTime - source.startTime;
250
-
251
- source.updateTimes(
252
- currentSource.source.endTime,
253
- currentSource.source.endTime + timeWidth
254
- );
255
- }
256
- currentSource.nextSourceId = source.id;
257
- newSource.prevSourceId = currentSource.source.id;
258
- this._sources[source.id] = newSource;
259
- }
260
- }
261
- else {
262
- this._firstSourceId = source.id;
263
- this._sources[source.id] = newSource;
264
- }
265
-
266
- this.updateLineHeight(sourceGroup, 'add');
267
- }
268
-
269
- if (!sourceGroup.getParent() || !sourceGroup.isDescendantOf(this._group)) {
270
- sourceGroup.addToGroup(this._group);
271
- }
272
- };
273
-
274
- Line.prototype.addSegments = function(segmentsGroup) {
275
- this._segmentsGroup = segmentsGroup;
276
-
277
- this._height = this._segmentsGroup.getCurrentHeight();
278
-
279
- segmentsGroup.addToGroup(this._group);
280
- };
281
-
282
- Line.prototype.refreshSegmentsHeight = function() {
283
- if (this.isSegmentsLine) {
284
- var oldHeight = this._height;
285
-
286
- this._height = this._segmentsGroup.getCurrentHeight();
287
-
288
- if (this._height !== oldHeight) {
289
- this._peaks.emit('line.heightChanged', this._position);
290
- }
291
- }
292
- };
293
-
294
- Line.prototype._canBePlacedBetween = function(startTime, endTime, startLimit, endLimit) {
295
- var timeWidth = endTime - startTime;
296
- var newTimes = null;
297
-
298
- if ((!endLimit && startTime > startLimit) || (startTime > startLimit && endTime < endLimit)) {
299
- // Can be placed at its wanted position with wanted start/end time
300
- newTimes = {
301
- startTime: startTime,
302
- endTime: endTime
303
- };
304
- }
305
- else if (endLimit - startLimit >= timeWidth) {
306
- // Can be placed at its wanted position but not with its wanted start/end time
307
- if (startTime > startLimit) {
308
- newTimes = {
309
- startTime: endLimit - timeWidth,
310
- endTime: endLimit
311
- };
312
- }
313
- else {
314
- newTimes = {
315
- startTime: startLimit,
316
- endTime: startLimit + timeWidth
317
- };
318
- }
319
- }
320
-
321
- return newTimes;
322
- };
323
-
324
- Line.prototype.removeSourceGroup = function(source, isPermanent) {
325
- var sourceGroup = this._sourcesGroup[source.id];
326
-
327
- delete this._sourcesGroup[source.id];
328
-
329
- if (isPermanent) {
330
- if (this._sources[source.id].prevSourceId) {
331
- this._sources[this._sources[source.id].prevSourceId].nextSourceId
332
- = this._sources[source.id].nextSourceId;
333
- }
334
-
335
- if (this._sources[source.id].nextSourceId) {
336
- this._sources[this._sources[source.id].nextSourceId].prevSourceId
337
- = this._sources[source.id].prevSourceId;
338
- }
339
-
340
- if (this._firstSourceId === source.id) {
341
- this._firstSourceId = this._sources[source.id].nextSourceId;
342
- }
343
-
344
- delete this._sources[source.id];
345
-
346
- this.updateLineHeight(sourceGroup, 'remove');
347
- }
348
-
349
- return sourceGroup;
350
- };
351
-
352
- Line.prototype.getKonvaGroup = function() {
353
- return this._group;
354
- };
355
-
356
- Line.prototype.getY = function() {
357
- return this._group.y();
358
- };
359
-
360
- Line.prototype.getInitialY = function() {
361
- return this._y;
362
- };
363
-
364
- Line.prototype.y = function(value, changeInitialY) {
365
- this._group.y(value);
366
- if (changeInitialY) {
367
- this._y = value;
368
- }
369
- };
370
-
371
- Line.prototype.moveOnY = function(dy) {
372
- this._y += dy;
373
- this._group.y(this._group.y() + dy);
374
- };
375
-
376
- Line.prototype.manageSourceOrder = function(source, newStartX, newEndX) {
377
- var cursorX = this._view.getPointerPosition().x;
378
- var tmpXs;
379
-
380
- var newXs = {
381
- startX: newStartX,
382
- endX: newEndX
383
- };
384
-
385
- var sourceWidth = this._view.timeToPixels(source.endTime - source.startTime);
386
-
387
- if (newStartX !== null && newEndX !== null) {
388
- if (this._sources[source.id].prevSourceId) {
389
- // there is another source to the left
390
- var previousStartX = this._view.timeToPixels(
391
- this._sources[this._sources[source.id].prevSourceId].source.startTime
392
- );
393
-
394
- if (cursorX + this._view.getFrameOffset() < previousStartX) {
395
- // we want to change order
396
- tmpXs = this._changeSourcePosition(
397
- source,
398
- sourceWidth,
399
- cursorX + this._view.getFrameOffset()
400
- );
401
-
402
- if (tmpXs) {
403
- newXs.startX = tmpXs.startTime;
404
- newXs.endX = tmpXs.endTime;
405
- }
406
- }
407
- }
408
-
409
- if (this._sources[source.id].nextSourceId) {
410
- // there is another source to the right
411
- var nextEndX = this._view.timeToPixels(
412
- this._sources[this._sources[source.id].nextSourceId].source.endTime
413
- );
414
-
415
- if (cursorX + this._view.getFrameOffset() > nextEndX) {
416
- // we want to change order
417
- tmpXs = this._changeSourcePosition(
418
- source,
419
- sourceWidth,
420
- cursorX + this._view.getFrameOffset()
421
- );
422
-
423
- if (tmpXs) {
424
- newXs.startX = tmpXs.startTime;
425
- newXs.endX = tmpXs.endTime;
426
- }
427
- }
428
- }
429
- }
430
-
431
- return newXs;
432
- };
433
-
434
- Line.prototype._changeSourcePosition = function(source, sourceWidth, x) {
435
- if (this._firstSourceId) {
436
- var currentRange = {
437
- start: null,
438
- end: null
439
- };
440
- var startLimit = null;
441
- var endLimit = null;
442
-
443
- do {
444
- if (!currentRange.end) {
445
- currentRange.end = this._sources[this._firstSourceId];
446
- }
447
- else {
448
- currentRange.start = currentRange.end;
449
- currentRange.end = this._sources[currentRange.start.nextSourceId];
450
- }
451
-
452
- if (currentRange.start) {
453
- startLimit = this._view.timeToPixels(
454
- currentRange.start.source.endTime
455
- );
456
- }
457
- else {
458
- startLimit = 0;
459
- }
460
-
461
- if (currentRange.end) {
462
- endLimit = this._view.timeToPixels(
463
- currentRange.end.source.startTime
464
- );
465
- }
466
- else {
467
- endLimit = null;
468
- }
469
-
470
- if (x > startLimit && (endLimit === null || x < endLimit)) {
471
- var newTimes = this._canBePlacedBetween(
472
- x,
473
- x + sourceWidth,
474
- startLimit,
475
- endLimit
476
- );
477
-
478
- if (newTimes) {
479
- source.updateTimes(
480
- this._view.pixelsToTime(newTimes.startTime),
481
- this._view.pixelsToTime(newTimes.endTime)
482
- );
483
- var prevSourceId = currentRange.start
484
- ? currentRange.start.source.id
485
- : null;
486
-
487
- this._moveSource(this._sources[source.id].source, prevSourceId);
488
- return newTimes;
489
- }
490
- }
491
- } while (currentRange.end);
492
- }
493
-
494
- return null;
495
- };
496
-
497
- Line.prototype._moveSource = function(source, prevSourceId) {
498
- // Remove source from the list
499
- var sourceObj = this._sources[source.id];
500
- var prevSource = this._sources[sourceObj.prevSourceId];
501
- var nextSource = this._sources[sourceObj.nextSourceId];
502
-
503
- if (prevSource) {
504
- this._sources[sourceObj.prevSourceId].nextSourceId = sourceObj.nextSourceId;
505
- }
506
- else {
507
- this._firstSourceId = sourceObj.nextSourceId;
508
- }
509
-
510
- if (nextSource) {
511
- this._sources[sourceObj.nextSourceId].prevSourceId = sourceObj.prevSourceId;
512
- }
513
-
514
- delete this._sources[source.id];
515
-
516
- // Add source back to the list
517
- sourceObj.prevSourceId = prevSourceId;
518
-
519
- if (prevSourceId) {
520
- sourceObj.nextSourceId = this._sources[prevSourceId].nextSourceId;
521
- this._sources[prevSourceId].nextSourceId = source.id;
522
- }
523
- else {
524
- sourceObj.nextSourceId = this._firstSourceId;
525
- this._firstSourceId = source.id;
526
- }
527
-
528
- if (sourceObj.nextSourceId) {
529
- this._sources[sourceObj.nextSourceId].prevSourceId = source.id;
530
- }
531
-
532
- this._sources[source.id] = sourceObj;
533
- };
534
-
535
- Line.prototype.manageCollision = function(source, newStartX, newEndX) {
536
- var newStartTime = null;
537
- var newEndTime = null;
538
- var startLimited = false;
539
- var endLimited = false;
540
- var timeWidth = this._view.pixelsToTime(newEndX - newStartX);
541
-
542
- var newXs = {
543
- startX: newStartX,
544
- endX: newEndX,
545
- updateWidth: false,
546
- updateTimelineLength: false
547
- };
548
-
549
- if (newStartX !== null) {
550
- // startMarker changed
551
- newStartTime = this._view.pixelsToTime(newStartX);
552
-
553
- if (source.startTime > newStartTime) {
554
- // startMarker moved to the left
555
- if (this._sources[source.id].prevSourceId) {
556
- // there is another source to the left
557
- var previousSource = this._sources[this._sources[source.id].prevSourceId]
558
- .source;
559
-
560
- if (newStartTime < previousSource.endTime) {
561
- // there is collision
562
- newStartTime = previousSource.endTime;
563
- startLimited = true;
564
- }
565
- }
566
- else {
567
- if (newStartTime < 0) {
568
- newStartTime = 0;
569
- startLimited = true;
570
- }
571
- }
572
- }
573
- }
574
-
575
- if (newEndX !== null) {
576
- // endMarker changed
577
- newEndTime = this._view.pixelsToTime(newEndX);
578
-
579
- if (source.endTime < newEndTime) {
580
- // endMarker moved to the right
581
- if (this._sources[source.id].nextSourceId) {
582
- // there is another source to the right
583
- var nextSource = this._sources[this._sources[source.id].nextSourceId]
584
- .source;
585
-
586
- if (newEndTime > nextSource.startTime) {
587
- // there is collision
588
- newEndTime = nextSource.startTime;
589
- endLimited = true;
590
- }
591
- }
592
- }
593
- }
594
-
595
- // Update the other edge if dragging and collision
596
- if (newStartTime !== null && newEndTime !== null) {
597
- if (startLimited) {
598
- newEndTime = newStartTime + timeWidth;
599
- }
600
-
601
- if (endLimited) {
602
- newStartTime = newEndTime - timeWidth;
603
- }
604
- }
605
-
606
- // Check for minimal size of source
607
- if (newStartTime !== null && newEndTime === null) {
608
- if (source.endTime - newStartTime < source.minSize) {
609
- newStartTime = source.endTime - source.minSize;
610
- }
611
- }
612
- else if (newEndTime !== null && newStartTime === null) {
613
- if (newEndTime - source.startTime < source.minSize) {
614
- newEndTime = source.startTime + source.minSize;
615
- }
616
- }
617
- else {
618
- if (newEndTime - newStartTime < source.minSize) {
619
- if (source.endTime !== newEndTime) {
620
- newEndTime = newStartTime + source.minSize;
621
- }
622
- if (source.startTime !== newStartTime) {
623
- newStartTime = newEndTime - source.minSize;
624
- }
625
- }
626
- }
627
-
628
- if (newStartTime !== null) {
629
- newXs.startX = this._view.timeToPixels(newStartTime);
630
- }
631
-
632
- if (newEndTime !== null) {
633
- newXs.endX = this._view.timeToPixels(newEndTime);
634
-
635
- if (this._sources[source.id].nextSourceId === null) {
636
- newXs.updateTimelineLength = true;
637
- }
638
- }
639
-
640
- if ((newXs.startX !== null && newXs.endX === null)
641
- || (newXs.startX === null && newXs.endX !== null)) {
642
- newXs.updateWidth = true;
643
- }
644
-
645
- return newXs;
646
- };
647
-
648
- // Line.prototype.rescale = function() {
649
- // for (var sourceId in this._sourcesGroup) {
650
- // if (Utils.objectHasProperty(this._sourcesGroup, sourceId)) {
651
- // this._sourcesGroup[sourceId].rescale();
652
- // }
653
- // }
654
- // };
655
-
656
- Line.prototype.updatePosition = function(pos) {
657
- for (var sourceId in this._sources) {
658
- if (Utils.objectHasProperty(this._sources, sourceId)) {
659
- this._sources[sourceId].source.position = pos;
660
- }
661
- }
662
-
663
- this._position = pos;
664
- };
665
-
666
- Line.prototype.destroy = function() {
667
- this._firstSourceId = null;
668
- this._sources = {};
669
- this._sourcesGroup = {};
670
- this._group.destroy();
671
- };
672
-
673
- Line.prototype.allowInteractions = function(bool) {
674
- this._group.listening(bool);
675
- };
676
-
677
- return Line;
678
- });
1
+ /**
2
+ * @file
3
+ *
4
+ * Defines the {@link line} class.
5
+ *
6
+ * @module line
7
+ */
8
+
9
+ define([
10
+ 'konva',
11
+ './utils'
12
+ ], function(Konva, Utils) {
13
+ 'use strict';
14
+
15
+ function Line(peaks, view, y, id, position) {
16
+ this._peaks = peaks;
17
+ this._view = view;
18
+
19
+ this._id = id;
20
+ this._position = position;
21
+
22
+ this._firstSourceId = null;
23
+ this._sources = {};
24
+
25
+ this._sourcesGroup = {};
26
+ this._wrapped = false;
27
+ this._y = y;
28
+
29
+ this._group = new Konva.Group({
30
+ x: 0,
31
+ y: y - this._view.getFrameOffsetY(),
32
+ draggable: true,
33
+ dragBoundFunc: function() {
34
+ return {
35
+ x: this.absolutePosition().x,
36
+ y: this.absolutePosition().y
37
+ };
38
+ }
39
+ });
40
+
41
+ this._sourceHeights = {};
42
+ this._height = this._peaks.options.emptyLineHeight;
43
+ this._unwrappedCount = 0;
44
+ }
45
+
46
+ Line.prototype.getPosition = function() {
47
+ return this._position;
48
+ };
49
+
50
+ Line.prototype.getId = function() {
51
+ return this._id;
52
+ };
53
+
54
+ Line.prototype.isEmpty = function() {
55
+ return Object.keys(this._sources).length === 0;
56
+ };
57
+
58
+ Line.prototype.isSegmentsLine = function() {
59
+ return Boolean(this._segmentsGroup);
60
+ };
61
+
62
+ Line.prototype.updateSegments = function(frameStartTime, frameEndTime) {
63
+ if (this.isSegmentsLine()) {
64
+ this._segmentsGroup.updateSegments(frameStartTime, frameEndTime);
65
+ }
66
+ };
67
+
68
+ Line.prototype.lineLength = function() {
69
+ var length = 0;
70
+
71
+ if (this.isSegmentsLine()) {
72
+ return this._segmentsGroup.getSegmentsGroupLength();
73
+ }
74
+
75
+ for (var sourceId in this._sources) {
76
+ if (Utils.objectHasProperty(this._sources, sourceId)) {
77
+ var sourceGroupLength = this._view.timeToPixels(
78
+ this._sources[sourceId].source.endTime
79
+ );
80
+
81
+ if (sourceGroupLength > length) {
82
+ length = sourceGroupLength;
83
+ }
84
+ }
85
+ }
86
+
87
+ return length;
88
+ };
89
+
90
+ Line.prototype.lineHeight = function() {
91
+ return this._height;
92
+ };
93
+
94
+ Line.prototype.changeHeight = function(from, to) {
95
+ if (this._sourceHeights[from]) {
96
+ var oldHeight = this._height;
97
+
98
+ if (this._sourceHeights[to]) {
99
+ this._sourceHeights[to] += this._sourceHeights[from];
100
+ }
101
+ else {
102
+ this._sourceHeights[to] = this._sourceHeights[from];
103
+ }
104
+
105
+ if (to > this._height) {
106
+ this._height = to;
107
+ }
108
+ else if (from === this._height) {
109
+ this._height = 0;
110
+ for (var height in this._sourceHeights) {
111
+ if (Utils.objectHasProperty(this._sourceHeights, height)) {
112
+ var parsedHeight = parseInt(height, 10);
113
+
114
+ if (parsedHeight !== from) {
115
+ if (parsedHeight > this._height) {
116
+ this._height = parsedHeight;
117
+ }
118
+ }
119
+ }
120
+ }
121
+ }
122
+
123
+ if (this._height !== oldHeight) {
124
+ this._peaks.emit('line.heightChanged', this._position);
125
+ }
126
+
127
+ delete this._sourceHeights[from];
128
+ }
129
+ };
130
+
131
+ Line.prototype.updateLineHeight = function(sourceGroup, action) {
132
+ var oldHeight = this._height;
133
+ var sourceGroupHeight;
134
+
135
+ switch (action) {
136
+ case 'add':
137
+ sourceGroupHeight = sourceGroup.getCurrentHeight();
138
+
139
+ if (this._sourceHeights[sourceGroupHeight]) {
140
+ this._sourceHeights[sourceGroupHeight]++;
141
+ }
142
+ else {
143
+ this._sourceHeights[sourceGroupHeight] = 1;
144
+ if (sourceGroupHeight > this._height) {
145
+ this._height = sourceGroupHeight;
146
+ }
147
+ }
148
+ break;
149
+ case 'remove':
150
+ if (Object.keys(this._sources).length === 0) {
151
+ this._height = this._peaks.options.emptyLineHeight;
152
+ this._sourceHeights = {};
153
+ }
154
+ else {
155
+ sourceGroupHeight = sourceGroup.getCurrentHeight();
156
+
157
+ this._sourceHeights[sourceGroupHeight]--;
158
+
159
+ if (this._sourceHeights[sourceGroupHeight] === 0
160
+ && sourceGroupHeight === this._height) {
161
+ delete this._sourceHeights[sourceGroupHeight];
162
+ this._height = 0;
163
+ for (var height in this._sourceHeights) {
164
+ if (Utils.objectHasProperty(this._sourceHeights, height)) {
165
+ var parsedHeight = parseInt(height, 10);
166
+
167
+ if (parsedHeight > this._height) {
168
+ this._height = parsedHeight;
169
+ }
170
+ }
171
+ }
172
+ }
173
+ }
174
+ break;
175
+ }
176
+
177
+ if (this._height !== oldHeight) {
178
+ this._peaks.emit('line.heightChanged', this._position);
179
+ }
180
+ };
181
+
182
+ Line.prototype.isVisible = function() {
183
+ return this._y < this._view.getFrameOffsetY() + this._view.getHeight()
184
+ && this._view.getFrameOffsetY() < this._y + this._height;
185
+ };
186
+
187
+ Line.prototype.addToLayer = function(layer) {
188
+ layer.add(this._group);
189
+ };
190
+
191
+ Line.prototype.addSourceGroup = function(sourceGroup) {
192
+ var source = sourceGroup.getSource();
193
+
194
+ this._sourcesGroup[source.id] = sourceGroup;
195
+
196
+ if (!this._sources[source.id]) {
197
+ var newSource = {
198
+ source: source,
199
+ prevSourceId: null,
200
+ nextSourceId: null
201
+ };
202
+
203
+ if (this._firstSourceId) {
204
+ var currentSource = null;
205
+
206
+ do {
207
+ if (!currentSource) {
208
+ currentSource = this._sources[this._firstSourceId];
209
+ }
210
+ else {
211
+ currentSource = this._sources[currentSource.nextSourceId];
212
+ }
213
+
214
+ if (source.endTime <= currentSource.source.startTime) {
215
+ var startLimit = currentSource.prevSourceId
216
+ ? this._sources[currentSource.prevSourceId].source.endTime
217
+ : 0;
218
+
219
+ var newTimes = this._canBePlacedBetween(
220
+ source.startTime,
221
+ source.endTime,
222
+ startLimit,
223
+ currentSource.source.startTime
224
+ );
225
+
226
+ if (newTimes) {
227
+ source.updateTimes(newTimes.startTime, newTimes.endTime);
228
+
229
+ if (currentSource.prevSourceId) {
230
+ this._sources[currentSource.prevSourceId].nextSourceId = source.id;
231
+ newSource.prevSourceId = currentSource.prevSourceId;
232
+ }
233
+ else {
234
+ this._firstSourceId = source.id;
235
+ }
236
+
237
+ currentSource.prevSourceId = source.id;
238
+ newSource.nextSourceId = currentSource.source.id;
239
+
240
+ this._sources[source.id] = newSource;
241
+ break;
242
+ }
243
+ }
244
+ } while (currentSource.nextSourceId);
245
+
246
+ if (!newSource.prevSourceId && !newSource.nextSourceId) {
247
+ if (source.startTime < currentSource.source.endTime) {
248
+ // Overlapping with last source
249
+ var timeWidth = source.endTime - source.startTime;
250
+
251
+ source.updateTimes(
252
+ currentSource.source.endTime,
253
+ currentSource.source.endTime + timeWidth
254
+ );
255
+ }
256
+ currentSource.nextSourceId = source.id;
257
+ newSource.prevSourceId = currentSource.source.id;
258
+ this._sources[source.id] = newSource;
259
+ }
260
+ }
261
+ else {
262
+ this._firstSourceId = source.id;
263
+ this._sources[source.id] = newSource;
264
+ }
265
+
266
+ this.updateLineHeight(sourceGroup, 'add');
267
+ }
268
+
269
+ if (!sourceGroup.getParent() || !sourceGroup.isDescendantOf(this._group)) {
270
+ sourceGroup.addToGroup(this._group);
271
+ }
272
+ };
273
+
274
+ Line.prototype.addSegments = function(segmentsGroup) {
275
+ this._segmentsGroup = segmentsGroup;
276
+
277
+ this._height = this._segmentsGroup.getCurrentHeight();
278
+
279
+ segmentsGroup.addToGroup(this._group);
280
+ };
281
+
282
+ Line.prototype.refreshSegmentsHeight = function() {
283
+ if (this.isSegmentsLine) {
284
+ var oldHeight = this._height;
285
+
286
+ this._height = this._segmentsGroup.getCurrentHeight();
287
+
288
+ if (this._height !== oldHeight) {
289
+ this._peaks.emit('line.heightChanged', this._position);
290
+ }
291
+ }
292
+ };
293
+
294
+ Line.prototype._canBePlacedBetween = function(startTime, endTime, startLimit, endLimit) {
295
+ var timeWidth = endTime - startTime;
296
+ var newTimes = null;
297
+
298
+ if ((!endLimit && startTime > startLimit) || (startTime > startLimit && endTime < endLimit)) {
299
+ // Can be placed at its wanted position with wanted start/end time
300
+ newTimes = {
301
+ startTime: startTime,
302
+ endTime: endTime
303
+ };
304
+ }
305
+ else if (endLimit - startLimit >= timeWidth) {
306
+ // Can be placed at its wanted position but not with its wanted start/end time
307
+ if (startTime > startLimit) {
308
+ newTimes = {
309
+ startTime: endLimit - timeWidth,
310
+ endTime: endLimit
311
+ };
312
+ }
313
+ else {
314
+ newTimes = {
315
+ startTime: startLimit,
316
+ endTime: startLimit + timeWidth
317
+ };
318
+ }
319
+ }
320
+
321
+ return newTimes;
322
+ };
323
+
324
+ Line.prototype.removeSourceGroup = function(source, isPermanent) {
325
+ var sourceGroup = this._sourcesGroup[source.id];
326
+
327
+ delete this._sourcesGroup[source.id];
328
+
329
+ if (isPermanent) {
330
+ if (this._sources[source.id].prevSourceId) {
331
+ this._sources[this._sources[source.id].prevSourceId].nextSourceId
332
+ = this._sources[source.id].nextSourceId;
333
+ }
334
+
335
+ if (this._sources[source.id].nextSourceId) {
336
+ this._sources[this._sources[source.id].nextSourceId].prevSourceId
337
+ = this._sources[source.id].prevSourceId;
338
+ }
339
+
340
+ if (this._firstSourceId === source.id) {
341
+ this._firstSourceId = this._sources[source.id].nextSourceId;
342
+ }
343
+
344
+ delete this._sources[source.id];
345
+
346
+ this.updateLineHeight(sourceGroup, 'remove');
347
+ }
348
+
349
+ return sourceGroup;
350
+ };
351
+
352
+ Line.prototype.getKonvaGroup = function() {
353
+ return this._group;
354
+ };
355
+
356
+ Line.prototype.getY = function() {
357
+ return this._group.y();
358
+ };
359
+
360
+ Line.prototype.getInitialY = function() {
361
+ return this._y;
362
+ };
363
+
364
+ Line.prototype.y = function(value, changeInitialY) {
365
+ this._group.y(value);
366
+ if (changeInitialY) {
367
+ this._y = value;
368
+ }
369
+ };
370
+
371
+ Line.prototype.moveOnY = function(dy) {
372
+ this._y += dy;
373
+ this._group.y(this._group.y() + dy);
374
+ };
375
+
376
+ Line.prototype.manageSourceOrder = function(source, newStartX, newEndX) {
377
+ var cursorX = this._view.getPointerPosition().x;
378
+ var tmpXs;
379
+
380
+ var newXs = {
381
+ startX: newStartX,
382
+ endX: newEndX
383
+ };
384
+
385
+ var sourceWidth = this._view.timeToPixels(source.endTime - source.startTime);
386
+
387
+ if (newStartX !== null && newEndX !== null) {
388
+ if (this._sources[source.id].prevSourceId) {
389
+ // there is another source to the left
390
+ var previousStartX = this._view.timeToPixels(
391
+ this._sources[this._sources[source.id].prevSourceId].source.startTime
392
+ );
393
+
394
+ if (cursorX + this._view.getFrameOffset() < previousStartX) {
395
+ // we want to change order
396
+ tmpXs = this._changeSourcePosition(
397
+ source,
398
+ sourceWidth,
399
+ cursorX + this._view.getFrameOffset()
400
+ );
401
+
402
+ if (tmpXs) {
403
+ newXs.startX = tmpXs.startTime;
404
+ newXs.endX = tmpXs.endTime;
405
+ }
406
+ }
407
+ }
408
+
409
+ if (this._sources[source.id].nextSourceId) {
410
+ // there is another source to the right
411
+ var nextEndX = this._view.timeToPixels(
412
+ this._sources[this._sources[source.id].nextSourceId].source.endTime
413
+ );
414
+
415
+ if (cursorX + this._view.getFrameOffset() > nextEndX) {
416
+ // we want to change order
417
+ tmpXs = this._changeSourcePosition(
418
+ source,
419
+ sourceWidth,
420
+ cursorX + this._view.getFrameOffset()
421
+ );
422
+
423
+ if (tmpXs) {
424
+ newXs.startX = tmpXs.startTime;
425
+ newXs.endX = tmpXs.endTime;
426
+ }
427
+ }
428
+ }
429
+ }
430
+
431
+ return newXs;
432
+ };
433
+
434
+ Line.prototype._changeSourcePosition = function(source, sourceWidth, x) {
435
+ if (this._firstSourceId) {
436
+ var currentRange = {
437
+ start: null,
438
+ end: null
439
+ };
440
+ var startLimit = null;
441
+ var endLimit = null;
442
+
443
+ do {
444
+ if (!currentRange.end) {
445
+ currentRange.end = this._sources[this._firstSourceId];
446
+ }
447
+ else {
448
+ currentRange.start = currentRange.end;
449
+ currentRange.end = this._sources[currentRange.start.nextSourceId];
450
+ }
451
+
452
+ if (currentRange.start) {
453
+ startLimit = this._view.timeToPixels(
454
+ currentRange.start.source.endTime
455
+ );
456
+ }
457
+ else {
458
+ startLimit = 0;
459
+ }
460
+
461
+ if (currentRange.end) {
462
+ endLimit = this._view.timeToPixels(
463
+ currentRange.end.source.startTime
464
+ );
465
+ }
466
+ else {
467
+ endLimit = null;
468
+ }
469
+
470
+ if (x > startLimit && (endLimit === null || x < endLimit)) {
471
+ var newTimes = this._canBePlacedBetween(
472
+ x,
473
+ x + sourceWidth,
474
+ startLimit,
475
+ endLimit
476
+ );
477
+
478
+ if (newTimes) {
479
+ source.updateTimes(
480
+ this._view.pixelsToTime(newTimes.startTime),
481
+ this._view.pixelsToTime(newTimes.endTime)
482
+ );
483
+ var prevSourceId = currentRange.start
484
+ ? currentRange.start.source.id
485
+ : null;
486
+
487
+ this._moveSource(this._sources[source.id].source, prevSourceId);
488
+ return newTimes;
489
+ }
490
+ }
491
+ } while (currentRange.end);
492
+ }
493
+
494
+ return null;
495
+ };
496
+
497
+ Line.prototype._moveSource = function(source, prevSourceId) {
498
+ // Remove source from the list
499
+ var sourceObj = this._sources[source.id];
500
+ var prevSource = this._sources[sourceObj.prevSourceId];
501
+ var nextSource = this._sources[sourceObj.nextSourceId];
502
+
503
+ if (prevSource) {
504
+ this._sources[sourceObj.prevSourceId].nextSourceId = sourceObj.nextSourceId;
505
+ }
506
+ else {
507
+ this._firstSourceId = sourceObj.nextSourceId;
508
+ }
509
+
510
+ if (nextSource) {
511
+ this._sources[sourceObj.nextSourceId].prevSourceId = sourceObj.prevSourceId;
512
+ }
513
+
514
+ delete this._sources[source.id];
515
+
516
+ // Add source back to the list
517
+ sourceObj.prevSourceId = prevSourceId;
518
+
519
+ if (prevSourceId) {
520
+ sourceObj.nextSourceId = this._sources[prevSourceId].nextSourceId;
521
+ this._sources[prevSourceId].nextSourceId = source.id;
522
+ }
523
+ else {
524
+ sourceObj.nextSourceId = this._firstSourceId;
525
+ this._firstSourceId = source.id;
526
+ }
527
+
528
+ if (sourceObj.nextSourceId) {
529
+ this._sources[sourceObj.nextSourceId].prevSourceId = source.id;
530
+ }
531
+
532
+ this._sources[source.id] = sourceObj;
533
+ };
534
+
535
+ Line.prototype.manageCollision = function(source, newStartX, newEndX) {
536
+ var newStartTime = null;
537
+ var newEndTime = null;
538
+ var startLimited = false;
539
+ var endLimited = false;
540
+ var timeWidth = this._view.pixelsToTime(newEndX - newStartX);
541
+
542
+ var newXs = {
543
+ startX: newStartX,
544
+ endX: newEndX,
545
+ updateWidth: false,
546
+ updateTimelineLength: false
547
+ };
548
+
549
+ if (newStartX !== null) {
550
+ // startMarker changed
551
+ newStartTime = this._view.pixelsToTime(newStartX);
552
+
553
+ if (source.startTime > newStartTime) {
554
+ // startMarker moved to the left
555
+ if (this._sources[source.id].prevSourceId) {
556
+ // there is another source to the left
557
+ var previousSource = this._sources[this._sources[source.id].prevSourceId]
558
+ .source;
559
+
560
+ if (newStartTime < previousSource.endTime) {
561
+ // there is collision
562
+ newStartTime = previousSource.endTime;
563
+ startLimited = true;
564
+ }
565
+ }
566
+ else {
567
+ if (newStartTime < 0) {
568
+ newStartTime = 0;
569
+ startLimited = true;
570
+ }
571
+ }
572
+ }
573
+ }
574
+
575
+ if (newEndX !== null) {
576
+ // endMarker changed
577
+ newEndTime = this._view.pixelsToTime(newEndX);
578
+
579
+ if (source.endTime < newEndTime) {
580
+ // endMarker moved to the right
581
+ if (this._sources[source.id].nextSourceId) {
582
+ // there is another source to the right
583
+ var nextSource = this._sources[this._sources[source.id].nextSourceId]
584
+ .source;
585
+
586
+ if (newEndTime > nextSource.startTime) {
587
+ // there is collision
588
+ newEndTime = nextSource.startTime;
589
+ endLimited = true;
590
+ }
591
+ }
592
+ }
593
+ }
594
+
595
+ // Update the other edge if dragging and collision
596
+ if (newStartTime !== null && newEndTime !== null) {
597
+ if (startLimited) {
598
+ newEndTime = newStartTime + timeWidth;
599
+ }
600
+
601
+ if (endLimited) {
602
+ newStartTime = newEndTime - timeWidth;
603
+ }
604
+ }
605
+
606
+ // Check for minimal size of source
607
+ if (newStartTime !== null && newEndTime === null) {
608
+ if (source.endTime - newStartTime < source.minSize) {
609
+ newStartTime = source.endTime - source.minSize;
610
+ }
611
+ }
612
+ else if (newEndTime !== null && newStartTime === null) {
613
+ if (newEndTime - source.startTime < source.minSize) {
614
+ newEndTime = source.startTime + source.minSize;
615
+ }
616
+ }
617
+ else {
618
+ if (newEndTime - newStartTime < source.minSize) {
619
+ if (source.endTime !== newEndTime) {
620
+ newEndTime = newStartTime + source.minSize;
621
+ }
622
+ if (source.startTime !== newStartTime) {
623
+ newStartTime = newEndTime - source.minSize;
624
+ }
625
+ }
626
+ }
627
+
628
+ if (newStartTime !== null) {
629
+ newXs.startX = this._view.timeToPixels(newStartTime);
630
+ }
631
+
632
+ if (newEndTime !== null) {
633
+ newXs.endX = this._view.timeToPixels(newEndTime);
634
+
635
+ if (this._sources[source.id].nextSourceId === null) {
636
+ newXs.updateTimelineLength = true;
637
+ }
638
+ }
639
+
640
+ if ((newXs.startX !== null && newXs.endX === null)
641
+ || (newXs.startX === null && newXs.endX !== null)) {
642
+ newXs.updateWidth = true;
643
+ }
644
+
645
+ return newXs;
646
+ };
647
+
648
+ // Line.prototype.rescale = function() {
649
+ // for (var sourceId in this._sourcesGroup) {
650
+ // if (Utils.objectHasProperty(this._sourcesGroup, sourceId)) {
651
+ // this._sourcesGroup[sourceId].rescale();
652
+ // }
653
+ // }
654
+ // };
655
+
656
+ Line.prototype.updatePosition = function(pos) {
657
+ for (var sourceId in this._sources) {
658
+ if (Utils.objectHasProperty(this._sources, sourceId)) {
659
+ this._sources[sourceId].source.position = pos;
660
+ }
661
+ }
662
+
663
+ this._position = pos;
664
+ };
665
+
666
+ Line.prototype.destroy = function() {
667
+ this._firstSourceId = null;
668
+ this._sources = {};
669
+ this._sourcesGroup = {};
670
+ this._group.destroy();
671
+ };
672
+
673
+ Line.prototype.allowInteractions = function(bool) {
674
+ this._group.listening(bool);
675
+ };
676
+
677
+ return Line;
678
+ });