@checksub_team/peaks_timeline 2.3.0-alpha.0 → 2.3.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/peaks.js +243 -151
- package/src/components/axis.js +24 -13
- package/src/components/line-groups.js +0 -32
- package/src/components/line-indicator.js +11 -2
- package/src/components/mode-layer.js +50 -7
- package/src/components/playhead-layer.js +13 -3
- package/src/components/source-group.js +151 -1
- package/src/components/sources-layer.js +21 -114
- package/src/view.js +87 -20
package/src/components/axis.js
CHANGED
|
@@ -8,8 +8,9 @@
|
|
|
8
8
|
|
|
9
9
|
define([
|
|
10
10
|
'../utils',
|
|
11
|
+
'./invoker',
|
|
11
12
|
'konva'
|
|
12
|
-
], function(Utils, Konva) {
|
|
13
|
+
], function(Utils, Invoker, Konva) {
|
|
13
14
|
'use strict';
|
|
14
15
|
|
|
15
16
|
var LEFT_PADDING = 4;
|
|
@@ -29,52 +30,62 @@ define([
|
|
|
29
30
|
function Axis(peaks, view, options) {
|
|
30
31
|
this._view = view;
|
|
31
32
|
|
|
33
|
+
this._invoker = new Invoker();
|
|
34
|
+
|
|
32
35
|
var self = this;
|
|
33
36
|
|
|
34
37
|
peaks.on('playhead.moved', this._onPlayheadMoved.bind(this));
|
|
35
38
|
peaks.on('playhead.hidden', this._onPlayheadHidden.bind(this));
|
|
36
39
|
|
|
37
|
-
|
|
38
|
-
|
|
40
|
+
this._axisGridlineColor = options.axisGridlineColor;
|
|
41
|
+
this._axisLabelColor = options.axisLabelColor;
|
|
39
42
|
|
|
40
|
-
|
|
43
|
+
this._backLayer = new Konva.Layer({
|
|
41
44
|
listening: false
|
|
42
45
|
});
|
|
43
46
|
|
|
44
|
-
|
|
47
|
+
this._frontLayer = new Konva.Layer({
|
|
45
48
|
listening: false
|
|
46
49
|
});
|
|
47
50
|
|
|
48
|
-
|
|
51
|
+
this._axisShape = new Konva.Shape({
|
|
49
52
|
sceneFunc: function(context) {
|
|
50
53
|
self.drawAxis(context, view);
|
|
51
54
|
}
|
|
52
55
|
});
|
|
53
|
-
|
|
56
|
+
this._backLayer.add(this._axisShape);
|
|
54
57
|
|
|
55
|
-
|
|
58
|
+
this._timesShape = new Konva.Shape({
|
|
56
59
|
sceneFunc: function(context) {
|
|
57
60
|
self.drawTimes(context, view);
|
|
58
61
|
}
|
|
59
62
|
});
|
|
60
|
-
|
|
63
|
+
this._frontLayer.add(this._timesShape);
|
|
64
|
+
|
|
65
|
+
// Throttled draws to prevent excessive redraws.
|
|
66
|
+
this._throttledBackDraw = this._invoker.throttleTrailing(
|
|
67
|
+
this._backLayer.batchDraw.bind(this._backLayer)
|
|
68
|
+
);
|
|
69
|
+
this._throttledFrontDraw = this._invoker.throttleTrailing(
|
|
70
|
+
this._frontLayer.batchDraw.bind(this._frontLayer)
|
|
71
|
+
);
|
|
61
72
|
}
|
|
62
73
|
|
|
63
74
|
Axis.prototype._onPlayheadMoved = function(playheadX, playheadWidth) {
|
|
64
75
|
this._maskStart = playheadX + this._view.getFrameOffset();
|
|
65
76
|
this._maskEnd = playheadX + this._view.getFrameOffset() + playheadWidth;
|
|
66
|
-
this.
|
|
77
|
+
this._throttledFrontDraw();
|
|
67
78
|
};
|
|
68
79
|
|
|
69
80
|
Axis.prototype._onPlayheadHidden = function() {
|
|
70
81
|
this._maskStart = null;
|
|
71
82
|
this._maskEnd = null;
|
|
72
|
-
this.
|
|
83
|
+
this._throttledFrontDraw();
|
|
73
84
|
};
|
|
74
85
|
|
|
75
86
|
Axis.prototype.batchDraw = function() {
|
|
76
|
-
this.
|
|
77
|
-
this.
|
|
87
|
+
this._throttledBackDraw();
|
|
88
|
+
this._throttledFrontDraw();
|
|
78
89
|
};
|
|
79
90
|
|
|
80
91
|
Axis.prototype.addBackToStage = function(stage) {
|
|
@@ -347,43 +347,11 @@ define([
|
|
|
347
347
|
this._automaticallyCreatedLineId = automaticallyCreatedLineGroup.getId();
|
|
348
348
|
this._moveSourcesToPositionIfPossible(sources, newLinePosition);
|
|
349
349
|
|
|
350
|
-
// After creating and moving to the new line, nudge the vertical scroll so
|
|
351
|
-
// the pointer is closer to the center of that line.
|
|
352
|
-
this._nudgeFrameOffsetYToLineCenter(newLinePosition, this._automaticLineCreationMouseY);
|
|
353
|
-
|
|
354
350
|
// Notify that sources have been moved to a new line (for ghost preview updates)
|
|
355
351
|
this._peaks.emit('sources.delayedLineChange', sources);
|
|
356
352
|
}.bind(this), this._peaks.options.automaticLineCreationDelay);
|
|
357
353
|
};
|
|
358
354
|
|
|
359
|
-
LineGroups.prototype._nudgeFrameOffsetYToLineCenter = function(linePosition, mouseY) {
|
|
360
|
-
if (!this._peaks.options.enableVerticalScrolling) {
|
|
361
|
-
return;
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
if (Utils.isNullOrUndefined(mouseY)) {
|
|
365
|
-
return;
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
const lineGroup = this._lineGroupsByPosition[linePosition];
|
|
369
|
-
|
|
370
|
-
if (!lineGroup) {
|
|
371
|
-
return;
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
const targetCenterY = lineGroup.y() + (lineGroup.lineHeight() / 2);
|
|
375
|
-
const deltaY = targetCenterY - mouseY;
|
|
376
|
-
|
|
377
|
-
if (deltaY === 0) {
|
|
378
|
-
return;
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
const maxOffsetY = Math.max(0, this._view.getFullHeight() - this._view.getHeight());
|
|
382
|
-
const nextOffsetY = Utils.clamp(this._view.getFrameOffsetY() + deltaY, 0, maxOffsetY);
|
|
383
|
-
|
|
384
|
-
this._view.updateTimeline(null, nextOffsetY);
|
|
385
|
-
};
|
|
386
|
-
|
|
387
355
|
LineGroups.prototype.manageVerticalPosition = function(sources, startTime, endTime, mouseX, mouseY) {
|
|
388
356
|
if (Utils.isNullOrUndefined(mouseX)) {
|
|
389
357
|
return;
|
|
@@ -9,10 +9,12 @@
|
|
|
9
9
|
define([
|
|
10
10
|
'konva',
|
|
11
11
|
'./svgs',
|
|
12
|
+
'./invoker',
|
|
12
13
|
'../utils'
|
|
13
14
|
], function(
|
|
14
15
|
Konva,
|
|
15
16
|
SVGs,
|
|
17
|
+
Invoker,
|
|
16
18
|
Utils) {
|
|
17
19
|
'use strict';
|
|
18
20
|
|
|
@@ -31,6 +33,8 @@ define([
|
|
|
31
33
|
this._view = view;
|
|
32
34
|
this._container = container;
|
|
33
35
|
|
|
36
|
+
this._invoker = new Invoker();
|
|
37
|
+
|
|
34
38
|
this._width = this._peaks.options.lineIndicatorWidth;
|
|
35
39
|
this._height = this._view.getHeight();
|
|
36
40
|
|
|
@@ -58,6 +62,11 @@ define([
|
|
|
58
62
|
this._layer = new Konva.Layer();
|
|
59
63
|
this._stage.add(this._layer);
|
|
60
64
|
|
|
65
|
+
// Throttled draws to coalesce multiple updates per frame.
|
|
66
|
+
this._throttledBatchDraw = this._invoker.throttleTrailing(
|
|
67
|
+
this._layer.batchDraw.bind(this._layer)
|
|
68
|
+
);
|
|
69
|
+
|
|
61
70
|
this._indicators = {};
|
|
62
71
|
|
|
63
72
|
this._separatingLine = new Konva.Line({
|
|
@@ -69,7 +78,7 @@ define([
|
|
|
69
78
|
|
|
70
79
|
this._layer.add(this._separatingLine);
|
|
71
80
|
|
|
72
|
-
this.
|
|
81
|
+
this.batchDraw();
|
|
73
82
|
|
|
74
83
|
this._isDragging = false;
|
|
75
84
|
this._dragLineId = null;
|
|
@@ -423,7 +432,7 @@ define([
|
|
|
423
432
|
};
|
|
424
433
|
|
|
425
434
|
LineIndicator.prototype.batchDraw = function() {
|
|
426
|
-
this.
|
|
435
|
+
this._throttledBatchDraw();
|
|
427
436
|
};
|
|
428
437
|
|
|
429
438
|
LineIndicator.prototype._onWindowMove = function(event) {
|
|
@@ -8,10 +8,11 @@
|
|
|
8
8
|
|
|
9
9
|
define([
|
|
10
10
|
'./source-group',
|
|
11
|
+
'./invoker',
|
|
11
12
|
'../models/source',
|
|
12
13
|
'../utils',
|
|
13
14
|
'konva'
|
|
14
|
-
], function(SourceGroup, Source, Utils, Konva) {
|
|
15
|
+
], function(SourceGroup, Invoker, Source, Utils, Konva) {
|
|
15
16
|
'use strict';
|
|
16
17
|
|
|
17
18
|
var TIME_X_OFFSET = 20;
|
|
@@ -35,6 +36,8 @@ define([
|
|
|
35
36
|
this._playheadLayer = playheadLayer;
|
|
36
37
|
this._stage = stage;
|
|
37
38
|
|
|
39
|
+
this._invoker = new Invoker();
|
|
40
|
+
|
|
38
41
|
this._selectedElements = {};
|
|
39
42
|
this._currentLine = null;
|
|
40
43
|
|
|
@@ -42,6 +45,11 @@ define([
|
|
|
42
45
|
listening: this._mode !== 'default'
|
|
43
46
|
});
|
|
44
47
|
|
|
48
|
+
// Throttled draws to coalesce multiple updates per frame.
|
|
49
|
+
this._throttledBatchDraw = this._invoker.throttleTrailing(
|
|
50
|
+
this._layer.batchDraw.bind(this._layer)
|
|
51
|
+
);
|
|
52
|
+
|
|
45
53
|
this._prepareDefaultMode();
|
|
46
54
|
|
|
47
55
|
this._onMouseClickInDefaultMode = this._onMouseClickInDefaultMode.bind(this);
|
|
@@ -59,6 +67,10 @@ define([
|
|
|
59
67
|
this._peaks.on('handler.sources.destroy', this._onSourcesDestroy.bind(this));
|
|
60
68
|
}
|
|
61
69
|
|
|
70
|
+
ModeLayer.prototype.batchDraw = function() {
|
|
71
|
+
this._throttledBatchDraw();
|
|
72
|
+
};
|
|
73
|
+
|
|
62
74
|
ModeLayer.prototype._onSourcesDestroy = function(sources) {
|
|
63
75
|
const selectedElementsToDeselect = {};
|
|
64
76
|
|
|
@@ -262,7 +274,7 @@ define([
|
|
|
262
274
|
ModeLayer.prototype._onMouseEnterInCutMode = function() {
|
|
263
275
|
this._cutGroup.visible(true);
|
|
264
276
|
|
|
265
|
-
this.
|
|
277
|
+
this.batchDraw();
|
|
266
278
|
};
|
|
267
279
|
|
|
268
280
|
ModeLayer.prototype._updateCursorTime = function(position) {
|
|
@@ -363,13 +375,13 @@ define([
|
|
|
363
375
|
this._updateCursorTime(cuttingPosition);
|
|
364
376
|
this._updateCuttingLine(cuttingPosition);
|
|
365
377
|
|
|
366
|
-
this.
|
|
378
|
+
this.batchDraw();
|
|
367
379
|
};
|
|
368
380
|
|
|
369
381
|
ModeLayer.prototype._onMouseLeaveInCutMode = function() {
|
|
370
382
|
this._cutGroup.visible(false);
|
|
371
383
|
|
|
372
|
-
this.
|
|
384
|
+
this.batchDraw();
|
|
373
385
|
};
|
|
374
386
|
|
|
375
387
|
ModeLayer.prototype._onMouseClickInCutMode = function() {
|
|
@@ -414,18 +426,49 @@ define([
|
|
|
414
426
|
|
|
415
427
|
this._cuttingLine.visible(false);
|
|
416
428
|
|
|
429
|
+
// Avoid keeping a reference to a SourceGroup that will be destroyed
|
|
430
|
+
// as part of the cut update.
|
|
431
|
+
this._view.setHoveredElement(null);
|
|
432
|
+
|
|
417
433
|
this._peaks.cutSource(hoveredElement.getSource(), this._view.pixelsToTime(cuttingPixel));
|
|
418
434
|
|
|
419
|
-
|
|
435
|
+
// Cutting replaces Konva nodes under the cursor; Konva won't always emit
|
|
436
|
+
// enter/leave for the new nodes until the mouse moves. Re-sync hover now
|
|
437
|
+
// so subsequent leave events behave correctly.
|
|
438
|
+
this._syncHoveredElementFromPointer();
|
|
420
439
|
|
|
421
440
|
this._updateCursorTime(cuttingPosition);
|
|
422
441
|
this._updateCuttingLine(cuttingPosition);
|
|
423
442
|
|
|
424
|
-
this.
|
|
443
|
+
this.batchDraw();
|
|
425
444
|
}
|
|
426
445
|
}
|
|
427
446
|
};
|
|
428
447
|
|
|
448
|
+
ModeLayer.prototype._syncHoveredElementFromPointer = function() {
|
|
449
|
+
var pointerPos = this._stage.getPointerPosition();
|
|
450
|
+
|
|
451
|
+
if (!pointerPos) {
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
var node = this._stage.getIntersection(pointerPos);
|
|
456
|
+
|
|
457
|
+
while (node) {
|
|
458
|
+
if (node.attrs && node.attrs.sourceId) {
|
|
459
|
+
var sourceGroup = this._view.getSourceGroupById(node.attrs.sourceId);
|
|
460
|
+
|
|
461
|
+
if (sourceGroup && !sourceGroup.isHovered()) {
|
|
462
|
+
sourceGroup.startHover();
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
return;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
node = node.getParent ? node.getParent() : null;
|
|
469
|
+
}
|
|
470
|
+
};
|
|
471
|
+
|
|
429
472
|
ModeLayer.prototype.setMode = function(mode) {
|
|
430
473
|
if (this._mode === mode) {
|
|
431
474
|
return;
|
|
@@ -498,7 +541,7 @@ define([
|
|
|
498
541
|
}
|
|
499
542
|
|
|
500
543
|
this._mode = mode;
|
|
501
|
-
this.
|
|
544
|
+
this.batchDraw();
|
|
502
545
|
this._view.batchDrawSourcesLayer();
|
|
503
546
|
};
|
|
504
547
|
|
|
@@ -8,8 +8,9 @@
|
|
|
8
8
|
|
|
9
9
|
define([
|
|
10
10
|
'../utils',
|
|
11
|
+
'./invoker',
|
|
11
12
|
'konva'
|
|
12
|
-
], function(Utils, Konva) {
|
|
13
|
+
], function(Utils, Invoker, Konva) {
|
|
13
14
|
'use strict';
|
|
14
15
|
|
|
15
16
|
var HANDLE_RADIUS = 10;
|
|
@@ -38,6 +39,11 @@ define([
|
|
|
38
39
|
|
|
39
40
|
this._playheadLayer = new Konva.Layer();
|
|
40
41
|
|
|
42
|
+
this._invoker = new Invoker();
|
|
43
|
+
this._throttledBatchDraw = this._invoker.throttleTrailing(
|
|
44
|
+
this._playheadLayer.batchDraw.bind(this._playheadLayer)
|
|
45
|
+
);
|
|
46
|
+
|
|
41
47
|
this._activeSegments = {};
|
|
42
48
|
this._activeSources = {};
|
|
43
49
|
|
|
@@ -236,10 +242,14 @@ define([
|
|
|
236
242
|
|
|
237
243
|
this._time = time;
|
|
238
244
|
if (pixelHasChanged || timeHasChanged) {
|
|
239
|
-
this.
|
|
245
|
+
this.batchDraw();
|
|
240
246
|
}
|
|
241
247
|
};
|
|
242
248
|
|
|
249
|
+
PlayheadLayer.prototype.batchDraw = function() {
|
|
250
|
+
this._throttledBatchDraw();
|
|
251
|
+
};
|
|
252
|
+
|
|
243
253
|
/**
|
|
244
254
|
* Update cached pixel values and position of the playhead group.
|
|
245
255
|
* @private
|
|
@@ -375,7 +385,7 @@ define([
|
|
|
375
385
|
}
|
|
376
386
|
|
|
377
387
|
if (updated) {
|
|
378
|
-
this.
|
|
388
|
+
this.batchDraw();
|
|
379
389
|
}
|
|
380
390
|
};
|
|
381
391
|
|
|
@@ -66,6 +66,9 @@ define([
|
|
|
66
66
|
this._isHandleDragging = false;
|
|
67
67
|
this._destroyed = false;
|
|
68
68
|
|
|
69
|
+
// Optional Konva element used as a drag "ghost" preview.
|
|
70
|
+
this._dragGhost = null;
|
|
71
|
+
|
|
69
72
|
// Performance: track if draw is needed
|
|
70
73
|
this._drawScheduled = false;
|
|
71
74
|
|
|
@@ -151,11 +154,54 @@ define([
|
|
|
151
154
|
SourceGroup.prototype._onHoverEnd = function() {
|
|
152
155
|
this._hovered = false;
|
|
153
156
|
this._manualHover = false;
|
|
157
|
+
this._disableManualHoverTracking();
|
|
154
158
|
this._view.setHoveredElement(null);
|
|
155
159
|
this._hideButtons();
|
|
156
160
|
this._scheduleBatchDraw();
|
|
157
161
|
};
|
|
158
162
|
|
|
163
|
+
SourceGroup.prototype._enableManualHoverTracking = function() {
|
|
164
|
+
if (this._manualHoverTrackingEnabled) {
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
if (!this._group || this._destroyed) {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
var stage = this._group.getStage && this._group.getStage();
|
|
173
|
+
|
|
174
|
+
if (!stage) {
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
this._manualHoverTrackingEnabled = true;
|
|
179
|
+
this._manualHoverNamespace = '.manualHover.' + this._source.id;
|
|
180
|
+
|
|
181
|
+
this._manualHoverMoveHandler = function() {
|
|
182
|
+
this._manageManualHoverStop();
|
|
183
|
+
}.bind(this);
|
|
184
|
+
|
|
185
|
+
stage.on('mousemove' + this._manualHoverNamespace, this._manualHoverMoveHandler);
|
|
186
|
+
stage.on('touchmove' + this._manualHoverNamespace, this._manualHoverMoveHandler);
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
SourceGroup.prototype._disableManualHoverTracking = function() {
|
|
190
|
+
if (!this._manualHoverTrackingEnabled) {
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
var stage = this._group && this._group.getStage && this._group.getStage();
|
|
195
|
+
|
|
196
|
+
if (stage && this._manualHoverNamespace) {
|
|
197
|
+
stage.off(this._manualHoverNamespace);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
this._manualHoverTrackingEnabled = false;
|
|
201
|
+
this._manualHoverMoveHandler = null;
|
|
202
|
+
this._manualHoverNamespace = null;
|
|
203
|
+
};
|
|
204
|
+
|
|
159
205
|
SourceGroup.prototype._onDragStart = function(element) {
|
|
160
206
|
this._isDragged = true;
|
|
161
207
|
this._layer.onSourcesGroupDragStart(element);
|
|
@@ -231,7 +277,7 @@ define([
|
|
|
231
277
|
this._layer.batchDraw();
|
|
232
278
|
}
|
|
233
279
|
}.bind(this)
|
|
234
|
-
);
|
|
280
|
+
, null, false);
|
|
235
281
|
|
|
236
282
|
return {
|
|
237
283
|
x: draggedElement.absolutePosition().x,
|
|
@@ -285,6 +331,13 @@ define([
|
|
|
285
331
|
// update unwrap
|
|
286
332
|
this.updatePreviews();
|
|
287
333
|
}
|
|
334
|
+
|
|
335
|
+
// Keep the drag ghost in sync automatically while dragging.
|
|
336
|
+
// This lets SourcesLayer avoid manually updating ghosts.
|
|
337
|
+
if (this._isDragged) {
|
|
338
|
+
this.createDragGhost();
|
|
339
|
+
this.updateDragGhost();
|
|
340
|
+
}
|
|
288
341
|
};
|
|
289
342
|
|
|
290
343
|
SourceGroup.prototype.setWrapping = function(wrap, forceCreate, notify) {
|
|
@@ -753,6 +806,7 @@ define([
|
|
|
753
806
|
|
|
754
807
|
SourceGroup.prototype.startHover = function() {
|
|
755
808
|
this._manualHover = true;
|
|
809
|
+
this._enableManualHoverTracking();
|
|
756
810
|
this._group.fire('mouseenter', { evt: new MouseEvent('mouseenter') }, true);
|
|
757
811
|
};
|
|
758
812
|
|
|
@@ -762,6 +816,14 @@ define([
|
|
|
762
816
|
|
|
763
817
|
SourceGroup.prototype.setDragging = function(isDragging) {
|
|
764
818
|
this._isDragged = isDragging;
|
|
819
|
+
|
|
820
|
+
// Ghost lifecycle is tied to dragging state.
|
|
821
|
+
if (isDragging) {
|
|
822
|
+
this.createDragGhost();
|
|
823
|
+
}
|
|
824
|
+
else {
|
|
825
|
+
this.destroyDragGhost();
|
|
826
|
+
}
|
|
765
827
|
};
|
|
766
828
|
|
|
767
829
|
SourceGroup.prototype.startDrag = function() {
|
|
@@ -1271,6 +1333,90 @@ define([
|
|
|
1271
1333
|
return this._height;
|
|
1272
1334
|
};
|
|
1273
1335
|
|
|
1336
|
+
/**
|
|
1337
|
+
* Creates the drag ghost preview element if it does not exist.
|
|
1338
|
+
* The ghost shows where the source will be placed when released.
|
|
1339
|
+
*/
|
|
1340
|
+
SourceGroup.prototype.createDragGhost = function() {
|
|
1341
|
+
if (this._dragGhost) {
|
|
1342
|
+
return this._dragGhost;
|
|
1343
|
+
}
|
|
1344
|
+
|
|
1345
|
+
var frameOffset = this._view.getFrameOffset();
|
|
1346
|
+
var x = this._view.timeToPixels(this._source.startTime) - frameOffset;
|
|
1347
|
+
var width = this._view.timeToPixels(this._source.endTime - this._source.startTime);
|
|
1348
|
+
var height = this.getCurrentHeight();
|
|
1349
|
+
var y = this.getAbsoluteY();
|
|
1350
|
+
|
|
1351
|
+
this._dragGhost = new Konva.Rect({
|
|
1352
|
+
x: x,
|
|
1353
|
+
y: y,
|
|
1354
|
+
width: width,
|
|
1355
|
+
height: height,
|
|
1356
|
+
fill: this._source.backgroundColor,
|
|
1357
|
+
opacity: 0.4,
|
|
1358
|
+
stroke: this._source.selectedBorderColor,
|
|
1359
|
+
strokeWidth: 2,
|
|
1360
|
+
dash: [8, 4],
|
|
1361
|
+
cornerRadius: 8,
|
|
1362
|
+
listening: false
|
|
1363
|
+
});
|
|
1364
|
+
|
|
1365
|
+
// Add to the main sources layer (not the group) so it stays behind sources.
|
|
1366
|
+
this._layer.add(this._dragGhost);
|
|
1367
|
+
this._dragGhost.moveToBottom();
|
|
1368
|
+
|
|
1369
|
+
// Ensure initial Y snaps to the current line position.
|
|
1370
|
+
this.updateDragGhost();
|
|
1371
|
+
|
|
1372
|
+
return this._dragGhost;
|
|
1373
|
+
};
|
|
1374
|
+
|
|
1375
|
+
/**
|
|
1376
|
+
* Updates the drag ghost preview position and size.
|
|
1377
|
+
*
|
|
1378
|
+
* @param {Object} lineGroupsById Map of lineId -> Konva.Group
|
|
1379
|
+
*/
|
|
1380
|
+
SourceGroup.prototype.updateDragGhost = function(lineGroupsById) {
|
|
1381
|
+
if (!this._dragGhost) {
|
|
1382
|
+
return;
|
|
1383
|
+
}
|
|
1384
|
+
|
|
1385
|
+
// Allow callers to omit the lookup; resolve via the owning layer.
|
|
1386
|
+
if (!lineGroupsById
|
|
1387
|
+
&& this._layer
|
|
1388
|
+
&& typeof this._layer.getLineGroups === 'function') {
|
|
1389
|
+
var lineGroups = this._layer.getLineGroups();
|
|
1390
|
+
|
|
1391
|
+
if (lineGroups && typeof lineGroups.getLineGroupsById === 'function') {
|
|
1392
|
+
lineGroupsById = lineGroups.getLineGroupsById();
|
|
1393
|
+
}
|
|
1394
|
+
}
|
|
1395
|
+
|
|
1396
|
+
var frameOffset = this._view.getFrameOffset();
|
|
1397
|
+
var x = this._view.timeToPixels(this._source.startTime) - frameOffset;
|
|
1398
|
+
var width = this._view.timeToPixels(this._source.endTime - this._source.startTime);
|
|
1399
|
+
|
|
1400
|
+
this._dragGhost.x(x);
|
|
1401
|
+
this._dragGhost.width(width);
|
|
1402
|
+
this._dragGhost.height(this.getCurrentHeight());
|
|
1403
|
+
|
|
1404
|
+
if (lineGroupsById) {
|
|
1405
|
+
var lineGroup = lineGroupsById[this._source.lineId];
|
|
1406
|
+
|
|
1407
|
+
if (lineGroup) {
|
|
1408
|
+
this._dragGhost.y(lineGroup.y());
|
|
1409
|
+
}
|
|
1410
|
+
}
|
|
1411
|
+
};
|
|
1412
|
+
|
|
1413
|
+
SourceGroup.prototype.destroyDragGhost = function() {
|
|
1414
|
+
if (this._dragGhost) {
|
|
1415
|
+
this._dragGhost.destroy();
|
|
1416
|
+
this._dragGhost = null;
|
|
1417
|
+
}
|
|
1418
|
+
};
|
|
1419
|
+
|
|
1274
1420
|
SourceGroup.prototype.getHeights = function() {
|
|
1275
1421
|
return {
|
|
1276
1422
|
unwrapped: this._unwrappedHeight,
|
|
@@ -1782,6 +1928,10 @@ define([
|
|
|
1782
1928
|
};
|
|
1783
1929
|
|
|
1784
1930
|
SourceGroup.prototype.destroy = function() {
|
|
1931
|
+
this.destroyDragGhost();
|
|
1932
|
+
|
|
1933
|
+
this._disableManualHoverTracking();
|
|
1934
|
+
|
|
1785
1935
|
// Cancel any pending idle callbacks to prevent memory leaks
|
|
1786
1936
|
if (this._pendingIdleCallbacks) {
|
|
1787
1937
|
this._pendingIdleCallbacks.forEach(function(id) {
|