@checksub_team/peaks_timeline 1.4.17

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.
@@ -0,0 +1,975 @@
1
+ /**
2
+ * @file
3
+ *
4
+ * Defines the {@link SourceGroup} class.
5
+ *
6
+ * @module source-group
7
+ */
8
+
9
+ define([
10
+ './waveform-builder',
11
+ './waveform-shape',
12
+ './utils',
13
+ 'konva'
14
+ ], function(
15
+ WaveformBuilder,
16
+ WaveformShape,
17
+ Utils,
18
+ Konva) {
19
+ 'use strict';
20
+
21
+ var SPACING_BETWEEN_PREVIEW_AND_BORDER_RATIO = 0.15;
22
+ var SPACING_BETWEEN_PREVIEWS = 1.5;
23
+ var HANDLE_WIDTH = 8;
24
+ var CORNER_RADIUS = 8;
25
+ var SELECTED_BORDER_WIDTH = 6;
26
+
27
+ /**
28
+ * Creates a source group for the given source.
29
+ *
30
+ * @class
31
+ * @alias SourceGroup
32
+ *
33
+ * @param {Source} source
34
+ * @param {Peaks} peaks
35
+ * @param {SourcesLayer} layer
36
+ * @param {WaveformOverview|WaveformZoomView} view
37
+ */
38
+
39
+ function SourceGroup(source, peaks, layer, view) {
40
+ this._source = source;
41
+ this._peaks = peaks;
42
+ this._layer = layer;
43
+ this._view = view;
44
+
45
+ var self = this;
46
+
47
+ this._x = this._view.timeToPixels(source.startTime);
48
+ this._width = this._view.timeToPixels(source.endTime - source.startTime);
49
+ this._unwrappedHeight = source.binaryHeight && source.previewHeight ?
50
+ source.binaryHeight + source.previewHeight :
51
+ this._peaks.options.lineHeight;
52
+ this._wrappedHeight = this._peaks.options.wrappedLineHeight;
53
+
54
+ this._previewList = [];
55
+
56
+ this._group = new Konva.Group({
57
+ x: this._x,
58
+ draggable: this._source.draggable,
59
+ dragBoundFunc: function() {
60
+ return {
61
+ x: this.absolutePosition().x,
62
+ y: this.absolutePosition().y
63
+ };
64
+ },
65
+ clipFunc: function(ctx) {
66
+ self.drawSourceShape(ctx);
67
+ }
68
+ });
69
+
70
+ this._group.on('dragstart', this._onSourceGroupDragStart.bind(this));
71
+ this._group.on('mouseover', function() {
72
+ self._view.setHoveredElement(self);
73
+ if (self._view.getCurrentMode() === 'cut') {
74
+ self.toggleDragging(false);
75
+ self.toggleResizing(false);
76
+ }
77
+ });
78
+ this._group.on('mouseout', function() {
79
+ self._view.setHoveredElement(null);
80
+ if (self._view.getCurrentMode() === 'cut') {
81
+ self.toggleDragging(true);
82
+ self.toggleResizing(true);
83
+ }
84
+ });
85
+ this._group.on('dragend', this._onSourceGroupDragEnd.bind(this));
86
+
87
+ this._addWrap(true);
88
+ this._addUnwrap(true);
89
+ this._addHandles(true);
90
+
91
+ this.setWrapping(source.wrapped);
92
+ }
93
+
94
+ SourceGroup.prototype.rescale = function() {
95
+ this.update();
96
+
97
+ this._previewList.forEach(function(preview) {
98
+ if (preview.loaded) {
99
+ switch (preview.type) {
100
+ case 'audio':
101
+ preview.group.getChildren()[0].rescale();
102
+ break;
103
+ case 'video':
104
+ case 'image':
105
+ default:
106
+ // No resampling
107
+ }
108
+ }
109
+ });
110
+ };
111
+
112
+ SourceGroup.prototype._onSourceGroupDragStart = function() {
113
+ this._dragged = true;
114
+ this._mouseDownX = this._view.getPointerPosition().x;
115
+ this._initialStartTime = this._source.startTime;
116
+ this._initialStartPixel = this._view.timeToPixels(this._initialStartTime);
117
+ this._initialEndTime = this._source.endTime;
118
+ this._initialEndPixel = this._view.timeToPixels(this._initialEndTime);
119
+ this._initialFrameOffset = this._view.getFrameOffset();
120
+ };
121
+
122
+ SourceGroup.prototype._onSourceGroupDragEnd = function() {
123
+ this._dragged = false;
124
+ this._view.updateTimelineLength();
125
+ this._peaks.emit('sources.updated');
126
+ };
127
+
128
+ SourceGroup.prototype._onSourceGroupDrag = function(draggedElement) {
129
+ var self = this;
130
+
131
+ var pos = this._view.updateWithAutoScroll(
132
+ draggedElement,
133
+ function() {
134
+ var mousePos = Math.min(
135
+ self._view.getWidth() - self._peaks.options.autoScrollThreshold * self._view.getWidth(),
136
+ Math.max(
137
+ 0,
138
+ self._view.getPointerPosition().x
139
+ )
140
+ );
141
+
142
+ var diff = mousePos - self._mouseDownX;
143
+
144
+ self._layer.updateSource(
145
+ self._source,
146
+ self._initialStartPixel + diff + (self._view.getFrameOffset() - self._initialFrameOffset),
147
+ self._initialEndPixel + diff + (self._view.getFrameOffset() - self._initialFrameOffset),
148
+ self._view.getPointerPosition().y
149
+ );
150
+
151
+ self._view.setTimelineLength(
152
+ self._view.timeToPixels(self._source.endTime) + self._view.getWidth()
153
+ );
154
+ }
155
+ );
156
+
157
+ return {
158
+ x: pos.x,
159
+ y: pos.y
160
+ };
161
+ };
162
+
163
+ SourceGroup.prototype._onSourceGroupHandleDrag = function(draggedElement, dragPos, leftHandle) {
164
+ var self = this;
165
+
166
+ var pos = this._view.updateWithAutoScroll(
167
+ draggedElement,
168
+ function() {
169
+ self._layer.updateSource(
170
+ self._source,
171
+ leftHandle ? dragPos.x + self._view.getFrameOffset() : null,
172
+ leftHandle ? null : dragPos.x + draggedElement.width() + self._view.getFrameOffset()
173
+ );
174
+ }
175
+ );
176
+
177
+ this._view.setTimelineLength(
178
+ this._view.timeToPixels(this._source.endTime) + this._view.getWidth()
179
+ );
180
+
181
+ return {
182
+ x: pos.x,
183
+ y: pos.y
184
+ };
185
+ };
186
+
187
+ SourceGroup.prototype.update = function() {
188
+ var startPixel = this._view.timeToPixels(this._source.startTime);
189
+ var endPixel = this._view.timeToPixels(this._source.endTime);
190
+ var frameOffset = this._view.timeToPixels(this._view.getTimeOffset());
191
+
192
+ this._group.x(startPixel - frameOffset);
193
+
194
+ this._x = startPixel;
195
+
196
+ var newWidth = endPixel - startPixel;
197
+
198
+ if (newWidth !== this._width) {
199
+ this._width = newWidth;
200
+
201
+ // update handles
202
+ this._rightHandle.x(newWidth - HANDLE_WIDTH);
203
+
204
+ // update unwrap
205
+ this.updatePreviews();
206
+
207
+ // update wrap
208
+ var title = this._wrap.getChildren(function(node) {
209
+ return node.getClassName() === 'Text';
210
+ });
211
+
212
+ if (title) {
213
+ title.width(newWidth - 10);
214
+ }
215
+ }
216
+ };
217
+
218
+ SourceGroup.prototype.setWrapping = function(wrap) {
219
+ if (wrap) {
220
+ this.wrap();
221
+ this._height = this._wrappedHeight;
222
+ }
223
+ else {
224
+ this.unwrap();
225
+ this._height = this._unwrappedHeight;
226
+ }
227
+
228
+ this.setHandlesWrapping(wrap);
229
+ };
230
+
231
+ SourceGroup.prototype.setHandlesWrapping = function(wrap) {
232
+ if (wrap) {
233
+ this._leftHandle.height(this._wrappedHeight);
234
+ this._rightHandle.height(this._wrappedHeight);
235
+ }
236
+ else {
237
+ this._leftHandle.height(this._unwrappedHeight);
238
+ this._rightHandle.height(this._unwrappedHeight);
239
+ }
240
+ };
241
+
242
+ SourceGroup.prototype._addHandles = function(forceCreate) {
243
+ var self = this;
244
+
245
+ if (!this._leftHandle || forceCreate) {
246
+ this._leftHandle = new Konva.Rect({
247
+ x: 0,
248
+ width: HANDLE_WIDTH,
249
+ height: this._unwrappedHeight,
250
+ visible: true,
251
+ draggable: this._source.resizable,
252
+ dragBoundFunc: function(pos) {
253
+ return self._onSourceGroupHandleDrag(this, pos, true);
254
+ }
255
+ });
256
+
257
+ if (this._source.resizable) {
258
+ this._leftHandle.on('dragend', function() {
259
+ if (this._scrollingInterval) {
260
+ clearInterval(this._scrollingInterval);
261
+ this._scrollingInterval = null;
262
+ }
263
+ });
264
+
265
+ this._leftHandle.on('mouseover', function() {
266
+ self._view.setCursor('ew-resize');
267
+ });
268
+
269
+ this._leftHandle.on('mouseout', function() {
270
+ self._view.setCursor('default');
271
+ });
272
+ }
273
+ }
274
+
275
+ if (!this._rightHandle || forceCreate) {
276
+ this._rightHandle = new Konva.Rect({
277
+ x: this._width - HANDLE_WIDTH,
278
+ width: HANDLE_WIDTH,
279
+ height: this._unwrappedHeight,
280
+ visible: true,
281
+ draggable: this._source.resizable,
282
+ dragBoundFunc: function(pos) {
283
+ return self._onSourceGroupHandleDrag(this, pos, false);
284
+ }
285
+ });
286
+
287
+ if (this._source.resizable) {
288
+ this._rightHandle.on('dragend', function() {
289
+ if (this._scrollingInterval) {
290
+ clearInterval(this._scrollingInterval);
291
+ this._scrollingInterval = null;
292
+ }
293
+ });
294
+
295
+ this._rightHandle.on('mouseover', function() {
296
+ self._view.setCursor('ew-resize');
297
+ });
298
+
299
+ this._rightHandle.on('mouseout', function() {
300
+ self._view.setCursor('default');
301
+ });
302
+ }
303
+ }
304
+
305
+ this._group.add(this._leftHandle);
306
+ this._group.add(this._rightHandle);
307
+ };
308
+
309
+ SourceGroup.prototype._addUnwrap = function(forceCreate) {
310
+ if (!this._unwrap || forceCreate) {
311
+ this._unwrap = this._createUnwrap();
312
+ this._unwrap.visible(false);
313
+ }
314
+
315
+ this._group.add(this._unwrap);
316
+ };
317
+
318
+ SourceGroup.prototype.toggleDragging = function(bool) {
319
+ var background;
320
+
321
+ if (this._wrap) {
322
+ background = this._wrap.getChildren(function(node) {
323
+ return node.getClassName() === 'Shape';
324
+ });
325
+
326
+ if (background) {
327
+ background.draggable(bool);
328
+ }
329
+ }
330
+ if (this._unwrap) {
331
+ background = this._unwrap.getChildren(function(node) {
332
+ return node.getClassName() === 'Shape';
333
+ });
334
+
335
+ if (background) {
336
+ background.draggable(bool);
337
+ }
338
+ }
339
+ };
340
+
341
+ SourceGroup.prototype.toggleResizing = function(bool) {
342
+ if (this._leftHandle) {
343
+ this._leftHandle.draggable(bool);
344
+ }
345
+ if (this._rightHandle) {
346
+ this._rightHandle.draggable(bool);
347
+ }
348
+ };
349
+
350
+ SourceGroup.prototype.drawSourceShape = function(ctx, shape) {
351
+ var radius = Math.max(
352
+ 1,
353
+ Math.min(
354
+ this._width / 2,
355
+ Math.min(
356
+ CORNER_RADIUS,
357
+ this._height / 2
358
+ )
359
+ )
360
+ );
361
+ var x = Math.max(
362
+ 0,
363
+ this._view.getFrameOffset() - this._x - radius
364
+ );
365
+ var width = Math.min(
366
+ this._width - x,
367
+ this._view.getOriginalWidth() + radius - Math.max(
368
+ 0,
369
+ this._x - this._view.getFrameOffset()
370
+ )
371
+ );
372
+ var xWidth = x + width;
373
+
374
+ ctx.beginPath();
375
+ ctx.moveTo(x + radius, 0);
376
+ ctx.lineTo(xWidth - radius, 0);
377
+ ctx.quadraticCurveTo(xWidth, 0, xWidth, radius);
378
+ ctx.lineTo(xWidth, this._height - radius);
379
+ ctx.quadraticCurveTo(xWidth, this._height, xWidth - radius, this._height);
380
+ ctx.lineTo(x + radius, this._height);
381
+ ctx.quadraticCurveTo(x, this._height, x, this._height - radius);
382
+ ctx.lineTo(x, radius);
383
+ ctx.quadraticCurveTo(x, 0, x + radius, 0);
384
+ ctx.closePath();
385
+
386
+ if (shape) {
387
+ ctx.fillStrokeShape(shape);
388
+ }
389
+ };
390
+
391
+ SourceGroup.prototype._createUnwrap = function() {
392
+ var unwrap = new Konva.Group({
393
+ width: this._width,
394
+ height: this._unwrappedHeight,
395
+ draggable: this._source.draggable,
396
+ dragBoundFunc: function() {
397
+ return {
398
+ x: this.absolutePosition().x,
399
+ y: this.absolutePosition().y
400
+ };
401
+ }
402
+ });
403
+
404
+ var self = this;
405
+
406
+ var background = new Konva.Shape({
407
+ fill: this._source.color,
408
+ stroke: this._source.borderColor,
409
+ strokeWidth: this._source.borderWidth,
410
+ sceneFunc: function(ctx, shape) {
411
+ self.drawSourceShape(ctx, shape);
412
+ },
413
+ draggable: this._source.draggable,
414
+ dragBoundFunc: function() {
415
+ return self._onSourceGroupDrag(this);
416
+ }
417
+ });
418
+
419
+ if (this._source.draggable) {
420
+ background.on('mouseenter', function() {
421
+ self._view.setCursor('pointer');
422
+ });
423
+ background.on('mouseout', function() {
424
+ self._view.setCursor('default');
425
+ });
426
+
427
+ background.on('dragstart', function() {
428
+ this._scrollInterval = null;
429
+ });
430
+
431
+ background.on('dragend', function() {
432
+ if (this._scrollingInterval) {
433
+ clearInterval(this._scrollingInterval);
434
+ this._scrollingInterval = null;
435
+ }
436
+ });
437
+ }
438
+
439
+ unwrap.add(background);
440
+
441
+ return unwrap;
442
+ };
443
+
444
+ SourceGroup.prototype._addWrap = function(forceCreate) {
445
+ if (!this._wrap || forceCreate) {
446
+ this._wrap = this._createWrap();
447
+ this._wrap.visible(false);
448
+ }
449
+
450
+ this._group.add(this._wrap);
451
+ };
452
+
453
+ SourceGroup.prototype._createWrap = function() {
454
+ var wrap = new Konva.Group({
455
+ width: this._width,
456
+ height: this._wrappedHeight,
457
+ draggable: this._source.draggable,
458
+ dragBoundFunc: function() {
459
+ return {
460
+ x: this.absolutePosition().x,
461
+ y: this.absolutePosition().y
462
+ };
463
+ }
464
+ });
465
+
466
+ var self = this;
467
+
468
+ var background = new Konva.Shape({
469
+ fill: this._source.color,
470
+ stroke: this._source.borderColor,
471
+ strokeWidth: this._source.borderWidth,
472
+ sceneFunc: function(ctx, shape) {
473
+ self.drawSourceShape(ctx, shape);
474
+ },
475
+ draggable: this._source.draggable,
476
+ dragBoundFunc: function() {
477
+ return self._onSourceGroupDrag(this);
478
+ }
479
+ });
480
+
481
+ if (this._source.draggable) {
482
+ background.on('mouseenter', function() {
483
+ self._view.setCursor('pointer');
484
+ });
485
+ background.on('mouseout', function() {
486
+ self._view.setCursor('default');
487
+ });
488
+
489
+ background.on('dragstart', function() {
490
+ this._scrollInterval = null;
491
+ });
492
+
493
+ background.on('dragend', function() {
494
+ if (this._scrollingInterval) {
495
+ clearInterval(this._scrollingInterval);
496
+ this._scrollingInterval = null;
497
+ }
498
+ });
499
+ }
500
+
501
+ var title = new Konva.Text({
502
+ x: 5,
503
+ width: this._width - 10,
504
+ height: this._wrappedHeight,
505
+ text: Utils.removeLineBreaks(this._source.title),
506
+ textAlign: 'left',
507
+ verticalAlign: 'middle',
508
+ fontSize: 14,
509
+ fontFamily: 'Open Sans',
510
+ fill: this._source.textColor,
511
+ wrap: 'none',
512
+ ellipsis: true,
513
+ listening: false
514
+ });
515
+
516
+ wrap.add(background);
517
+ wrap.add(title);
518
+
519
+ return wrap;
520
+ };
521
+
522
+ SourceGroup.prototype.getWidth = function() {
523
+ return this._width;
524
+ };
525
+
526
+ SourceGroup.prototype.getX = function() {
527
+ return this._x;
528
+ };
529
+
530
+ SourceGroup.prototype.getY = function() {
531
+ return this._group.absolutePosition().y;
532
+ };
533
+
534
+ SourceGroup.prototype.x = function(value) {
535
+ if (value) {
536
+ return this._group.x(value);
537
+ }
538
+ else {
539
+ return this._group.x();
540
+ }
541
+ };
542
+
543
+ SourceGroup.prototype.y = function(value) {
544
+ if (value) {
545
+ return this._group.y(value);
546
+ }
547
+ else {
548
+ return this._group.y();
549
+ }
550
+ };
551
+
552
+ SourceGroup.prototype.getSource = function() {
553
+ return this._source;
554
+ };
555
+
556
+ SourceGroup.prototype.startDrag = function() {
557
+ return this._group.startDrag();
558
+ };
559
+
560
+ SourceGroup.prototype.stopDrag = function() {
561
+ return this._group.stopDrag();
562
+ };
563
+
564
+ SourceGroup.prototype.addToGroup = function(group) {
565
+ group.add(this._group);
566
+ };
567
+
568
+ SourceGroup.prototype.isDescendantOf = function(group) {
569
+ group.isAncestorOf(this._group);
570
+ };
571
+
572
+ SourceGroup.prototype.moveTo = function(group) {
573
+ this._group.moveTo(group);
574
+ };
575
+
576
+ SourceGroup.prototype.getParent = function() {
577
+ return this._group.getParent();
578
+ };
579
+
580
+ SourceGroup.prototype.remove = function() {
581
+ this._group.remove();
582
+ };
583
+
584
+ SourceGroup.prototype.add = function(element) {
585
+ this._group.add(element);
586
+ };
587
+
588
+ SourceGroup.prototype.addImagePreview = function(content, url, redraw) {
589
+ var preview = {
590
+ type: 'image',
591
+ group: new Konva.Group({
592
+ height: this._unwrappedHeight,
593
+ listening: false
594
+ })
595
+ };
596
+
597
+ var imageData = this._layer.getLoadedData(url);
598
+
599
+ if (!imageData) {
600
+ imageData = new Image();
601
+
602
+ var self = this;
603
+
604
+ imageData.onload = function() {
605
+ self._layer.setLoadedData(url, this);
606
+ preview.loaded = true;
607
+ self._createImagePreview(preview, imageData, redraw);
608
+ };
609
+
610
+ imageData.src = content;
611
+ }
612
+ else {
613
+ preview.loaded = true;
614
+ this._createImagePreview(preview, imageData, redraw);
615
+ }
616
+ };
617
+
618
+ SourceGroup.prototype.addVideoPreview = function(content, url, redraw) {
619
+ var preview = {
620
+ type: 'video',
621
+ group: new Konva.Group({
622
+ y: this._source.binaryUrl && this._source.previewUrl ? this._source.binaryHeight : 0,
623
+ height: this._source.binaryUrl && this._source.previewUrl ?
624
+ this._source.previewHeight : this._unwrappedHeight,
625
+ listening: false
626
+ })
627
+ };
628
+
629
+ var imageData = this._layer.getLoadedData(url);
630
+
631
+ if (!imageData) {
632
+ var video = document.createElement('video');
633
+ var self = this;
634
+
635
+ video.onloadeddata = function() {
636
+ this.currentTime = this.duration / 2;
637
+
638
+ var canvas = document.createElement('canvas');
639
+
640
+ canvas.width = this.videoWidth;
641
+ canvas.height = this.videoHeight;
642
+ canvas.getContext('2d').drawImage(this, 0, 0, canvas.width, canvas.height);
643
+
644
+ imageData = new Image();
645
+
646
+ imageData.onload = function() {
647
+ self._layer.setLoadedData(url, this);
648
+ preview.loaded = true;
649
+ self._createImagePreview(preview, imageData, redraw);
650
+ };
651
+
652
+ imageData.src = canvas.toDataURL();
653
+ };
654
+
655
+ video.src = content;
656
+ }
657
+ else {
658
+ preview.loaded = true;
659
+ this._createImagePreview(preview, imageData, redraw);
660
+ }
661
+ };
662
+
663
+ SourceGroup.prototype.addAudioPreview = function(type, content, url, redraw) {
664
+ var preview = {
665
+ type: 'audio',
666
+ group: new Konva.Group({
667
+ height: this._source.binaryUrl && this._source.previewUrl ?
668
+ this._source.binaryHeight : this._unwrappedHeight,
669
+ listening: false
670
+ })
671
+ };
672
+
673
+ var self = this;
674
+
675
+ var audioData = this._layer.getLoadedData(url);
676
+
677
+ if (!audioData) {
678
+ var waveformBuilder = new WaveformBuilder(this._peaks);
679
+ var options = Object.assign({},this._peaks.options);
680
+
681
+ if (type === 'audio') {
682
+ options.objectUrl = content;
683
+ }
684
+ else {
685
+ options.dataUri = content;
686
+ }
687
+
688
+ waveformBuilder.init(options, function(err, originalWaveformData) {
689
+ if (err) {
690
+ throw err;
691
+ }
692
+
693
+ originalWaveformData.hasAudio = self._hasAudio(originalWaveformData);
694
+
695
+ if (originalWaveformData.hasAudio) {
696
+ var newScale = originalWaveformData.sample_rate / self._view.getTimeToPixelsMaxZoom();
697
+
698
+ if (newScale > originalWaveformData.scale) {
699
+ self._minScale = newScale;
700
+ }
701
+ else {
702
+ self._minScale = originalWaveformData.scale;
703
+ }
704
+
705
+ self._view.setTimeToPixelsMaxZoom(originalWaveformData.sample_rate / self._minScale);
706
+ }
707
+
708
+ self._layer.setLoadedData(url, originalWaveformData);
709
+ preview.loaded = true;
710
+ self._createAudioPreview(preview, originalWaveformData, redraw);
711
+ });
712
+ }
713
+ else {
714
+ preview.loaded = true;
715
+ this._createAudioPreview(preview, audioData, redraw);
716
+ }
717
+ };
718
+
719
+ SourceGroup.prototype._hasAudio = function(waveformData) {
720
+ var channels = waveformData.channels;
721
+ var channel, someIsNotZero = false;
722
+
723
+ for (var i = 0; i < channels; i++) {
724
+ channel = waveformData.channel(i);
725
+
726
+ someIsNotZero = channel.min_array().some(function(item) {
727
+ return item !== 0;
728
+ });
729
+
730
+ if (!someIsNotZero) {
731
+ someIsNotZero = channel.max_array().some(function(item) {
732
+ return item !== 0;
733
+ });
734
+ }
735
+
736
+ if (someIsNotZero) {
737
+ break;
738
+ }
739
+ }
740
+
741
+ return someIsNotZero;
742
+ };
743
+
744
+ SourceGroup.prototype._createAudioPreview = function(preview, waveformData, redraw) {
745
+ if (waveformData.hasAudio) {
746
+ var waveform = new WaveformShape({
747
+ view: this._view,
748
+ color: this._peaks.options.zoomWaveformColor,
749
+ waveformData: waveformData,
750
+ source: this._source,
751
+ height: preview.group.height()
752
+ });
753
+
754
+ preview.group.add(waveform);
755
+ this._unwrap.add(preview.group);
756
+
757
+ if (redraw) {
758
+ this._group.draw();
759
+ }
760
+
761
+ this._previewList.push(preview);
762
+ }
763
+ };
764
+
765
+ SourceGroup.prototype.setSelected = function(isSelected) {
766
+ // update unwrap
767
+ var background = this._unwrap.getChildren(function(node) {
768
+ return node.getClassName() === 'Shape';
769
+ });
770
+
771
+ if (background) {
772
+ if (isSelected) {
773
+ background.stroke(this._source.selectedColor);
774
+ background.strokeWidth(SELECTED_BORDER_WIDTH);
775
+ }
776
+ else {
777
+ background.stroke(this._source.borderColor);
778
+ background.strokeWidth(this._source.borderWidth);
779
+ }
780
+ }
781
+
782
+ // update wrap
783
+ background = this._wrap.getChildren(function(node) {
784
+ return node.getClassName() === 'Shape';
785
+ });
786
+
787
+ if (background) {
788
+ if (isSelected) {
789
+ background.stroke(this._source.selectedColor);
790
+ background.strokeWidth(SELECTED_BORDER_WIDTH);
791
+ }
792
+ else {
793
+ background.stroke(this._source.borderColor);
794
+ background.strokeWidth(this._source.borderWidth);
795
+ }
796
+ }
797
+
798
+ this._view.drawSourcesLayer();
799
+ };
800
+
801
+ SourceGroup.prototype.updatePreviews = function() {
802
+ var self = this;
803
+
804
+ this._previewList.forEach(function(preview) {
805
+ if (preview.loaded) {
806
+ switch (preview.type) {
807
+ case 'video':
808
+ case 'image':
809
+ // image or video preview
810
+ if (self._unwrappedHeight !== preview.imageData.referenceHeight) {
811
+ preview.imageData.referenceHeight = preview.group.height();
812
+ preview.imageData.borderSpacing = SPACING_BETWEEN_PREVIEW_AND_BORDER_RATIO
813
+ * preview.imageData.referenceHeight;
814
+ preview.imageData.height = preview.imageData.referenceHeight
815
+ - (2 * preview.imageData.borderSpacing);
816
+ preview.imageData.width = preview.imageData.height
817
+ * preview.imageData.dimRatio;
818
+ preview.imageData.imageSpacing = preview.imageData.width
819
+ * SPACING_BETWEEN_PREVIEWS;
820
+ }
821
+
822
+ var interImageSpacing = preview.imageData.width + preview.imageData.imageSpacing;
823
+ var imageNumber;
824
+
825
+ if (self._width > preview.imageData.borderSpacing) {
826
+ imageNumber = Math.trunc(
827
+ (self._width - preview.imageData.borderSpacing)
828
+ / interImageSpacing
829
+ ) + 1;
830
+ }
831
+ else {
832
+ imageNumber = 0;
833
+ }
834
+
835
+ var imageList = preview.group.getChildren();
836
+
837
+ var i = 0;
838
+
839
+ for (i = 0; i < imageNumber; i++) {
840
+ if (imageList.length > i) {
841
+ imageList[i].visible(true);
842
+ }
843
+ else {
844
+ var imagePreview = new Konva.Image({
845
+ x: preview.imageData.borderSpacing + i * interImageSpacing,
846
+ y: preview.imageData.borderSpacing,
847
+ image: preview.imageData.image,
848
+ width: preview.imageData.width,
849
+ height: preview.imageData.height,
850
+ listening: false,
851
+ visible: true
852
+ });
853
+
854
+ preview.group.add(imagePreview);
855
+ }
856
+ }
857
+
858
+ for (i = imageNumber; i < imageList.length; i++) {
859
+ imageList[i].visible(false);
860
+ }
861
+ }
862
+ }
863
+ });
864
+ };
865
+
866
+ SourceGroup.prototype._createImagePreview = function(preview, image, redraw) {
867
+ preview.imageData = {
868
+ image: image,
869
+ referenceHeight: null,
870
+ dimRatio: null,
871
+ borderSpacing: null,
872
+ height: null,
873
+ width: null,
874
+ imageSpacing: null
875
+ };
876
+
877
+ preview.imageData.referenceHeight = preview.group.height();
878
+ preview.imageData.dimRatio = image.width / image.height;
879
+ preview.imageData.borderSpacing = SPACING_BETWEEN_PREVIEW_AND_BORDER_RATIO
880
+ * preview.imageData.referenceHeight;
881
+ preview.imageData.height = preview.imageData.referenceHeight
882
+ - (2 * preview.imageData.borderSpacing);
883
+ preview.imageData.width = preview.imageData.height * preview.imageData.dimRatio;
884
+ preview.imageData.imageSpacing = preview.imageData.width * SPACING_BETWEEN_PREVIEWS;
885
+
886
+ var currentX = preview.imageData.borderSpacing;
887
+
888
+ while (currentX < this._width) {
889
+ var imagePreview = new Konva.Image({
890
+ x: currentX,
891
+ y: preview.imageData.borderSpacing,
892
+ image: image,
893
+ width: preview.imageData.width,
894
+ height: preview.imageData.height,
895
+ listening: false
896
+ });
897
+
898
+ preview.group.add(imagePreview);
899
+
900
+ currentX += preview.imageData.width + preview.imageData.imageSpacing;
901
+ }
902
+
903
+ this._unwrap.add(preview.group);
904
+
905
+ if (redraw) {
906
+ this._group.draw();
907
+ }
908
+
909
+ this._previewList.push(preview);
910
+ };
911
+
912
+ SourceGroup.prototype.isWrapped = function() {
913
+ return this._source.wrapped;
914
+ };
915
+
916
+ SourceGroup.prototype.getCurrentHeight = function() {
917
+ return this._height;
918
+ };
919
+
920
+ SourceGroup.prototype.wrap = function(notify) {
921
+ if (!this._wrap.visible()) {
922
+ if (this._wrap) {
923
+ this._wrap.visible(true);
924
+ if (this._unwrap) {
925
+ this._unwrap.visible(false);
926
+ }
927
+
928
+ this._source.wrapped = true;
929
+
930
+ if (notify) {
931
+ this._peaks.emit('source.wrappingChanged', this);
932
+ }
933
+ }
934
+ }
935
+ };
936
+
937
+ SourceGroup.prototype.unwrap = function(notify) {
938
+ if (!this._unwrap.visible()) {
939
+ if (this._unwrap) {
940
+ this._unwrap.visible(true);
941
+ if (this._wrap) {
942
+ this._wrap.visible(false);
943
+ }
944
+
945
+ this._source.wrapped = false;
946
+
947
+ if (notify) {
948
+ this._peaks.emit('source.wrappingChanged', this);
949
+ }
950
+ }
951
+ }
952
+ };
953
+
954
+ SourceGroup.prototype.setVisible = function(boolean) {
955
+ this._group.visible(boolean);
956
+ };
957
+
958
+ SourceGroup.prototype.setListening = function(boolean) {
959
+ this._group.listening(boolean);
960
+ };
961
+
962
+ SourceGroup.prototype.isVisible = function() {
963
+ return this._group.visible();
964
+ };
965
+
966
+ SourceGroup.prototype.isDragged = function() {
967
+ return this._dragged;
968
+ };
969
+
970
+ SourceGroup.prototype.destroy = function() {
971
+ this._group.destroy();
972
+ };
973
+
974
+ return SourceGroup;
975
+ });