@checksub_team/peaks_timeline
Version:
JavaScript UI component for displaying audio waveforms
436 lines (345 loc) • 13.4 kB
JavaScript
/**
* @file
*
* Defines the {@link lines} class.
*
* @module lines
*/
define([
'./segments-group',
'./line',
'./line-indicator',
'./utils'
], function(
SegmentsGroup,
Line,
LineIndicator,
Utils) {
'use strict';
function Lines(peaks, view, layer) {
this._peaks = peaks;
this._view = view;
this._layer = layer;
this._linesBySourceId = {};
this._linesByPosition = {};
this._autoAddToLayer = false;
this._areSourceInteractionsAllowed = true;
this._areSegmentInteractionsAllowed = true;
this._segmentsGroups = {};
this._segmentsGroupToLine = {};
this._lineId = 0;
this._lineIndicator = new LineIndicator(
peaks,
view,
document.getElementById('line-indicator-container')
);
this._peaks.on('line.heightChanged', this._onLineHeightChanged.bind(this));
this._peaks.on('line.add', this._onLineAdd.bind(this));
this._peaks.on('line.remove', this._onLineRemove.bind(this));
this._peaks.on('segment.updated', this._onSegmentsUpdate.bind(this));
this._peaks.on('segments.add', this._onSegmentsAdd.bind(this));
this._peaks.on('segments.remove', this._onSegmentsRemove.bind(this));
this._peaks.on('segments.remove_all', this._onSegmentsRemoveAll.bind(this));
this._peaks.on('segments.dragend', this._onSegmentUpdated.bind(this));
}
Lines.prototype.fitToView = function() {
this._lineIndicator.fitToView();
};
Lines.prototype._onSegmentsAdd = function(segments) {
var self = this;
segments.forEach(function(segment) {
if (!self._segmentsGroups[segment.line]) {
self._segmentsGroups[segment.line] = new SegmentsGroup(self._peaks, self._view, true);
}
self._segmentsGroups[segment.line].onSegmentsAdd([segment]);
if (Utils.objectHasProperty(self._segmentsGroupToLine, segment.line)) {
self._segmentsGroupToLine[segment.line].refreshSegmentsHeight();
}
});
};
Lines.prototype._onSegmentsUpdate = function(segment) {
this._segmentsGroups[segment.line].onSegmentsUpdate(segment);
};
Lines.prototype._onSegmentUpdated = function(segment) {
this._segmentsGroups[segment.line].onSegmentUpdated();
};
Lines.prototype._onSegmentsRemove = function(segments) {
var self = this;
segments.forEach(function(segment) {
self._segmentsGroups[segment.line].onSegmentsRemove([segment]);
});
};
Lines.prototype._onSegmentsRemoveAll = function(lineId) {
this._segmentsGroups[lineId].onSegmentsRemoveAll();
if (Utils.objectHasProperty(this._segmentsGroupToLine, lineId)) {
this._segmentsGroupToLine[lineId].refreshSegmentsHeight();
}
};
Lines.prototype._onLineHeightChanged = function(position) {
this._updateLinesPosition(position);
this._view.updateTimeline();
};
Lines.prototype._onLineAdd = function(position) {
this._createLine(position);
this._setInteractions(position);
this._updateLinesPosition(position);
};
Lines.prototype._onLineRemove = function(position) {
var oldLine = this.removeLine(position);
var lineNewY = oldLine.getY();
this._updateLinesPosition(position, lineNewY);
};
Lines.prototype.changeLineHeight = function(from, to) {
for (var position in this._linesByPosition) {
if (Utils.objectHasProperty(this._linesByPosition, position)) {
if (!this._linesByPosition[position].isSegmentsLine()) {
this._linesByPosition[position].changeHeight(from, to);
}
}
}
};
Lines.prototype.addSourceGroup = function(sourceGroup, position) {
if (!this._linesByPosition[position] || this._linesByPosition[position].isSegmentsLine()) {
this._createLine(position);
this._setInteractions(position);
}
sourceGroup.getSource().position = position;
this._linesByPosition[position].addSourceGroup(sourceGroup);
this._linesBySourceId[sourceGroup.getSource().id] = this._linesByPosition[position];
};
Lines.prototype.addSegments = function(lineId, position) {
this._createLine(position);
this._linesByPosition[position].allowInteractions(this._areSegmentInteractionsAllowed);
this._linesByPosition[position].addSegments(this._segmentsGroups[lineId]);
this._segmentsGroupToLine[lineId] = this._linesByPosition[position];
this._setInteractions(position);
this._updateLinesPosition(position);
};
Lines.prototype.removeSourceGroup = function(source, isPermanent) {
var sourceGroup = this._linesByPosition[source.position].removeSourceGroup(source, isPermanent);
if (isPermanent) {
delete this._linesBySourceId[source.id];
this._updateLinesPosition(source.position);
}
return sourceGroup;
};
Lines.prototype.removeLine = function(pos) {
var oldLine = this._linesByPosition[pos];
oldLine.destroy();
delete this._linesByPosition[pos];
this._lineIndicator.removeIndicator(oldLine.getId(), false);
return oldLine;
};
Lines.prototype.isLineVisible = function(position) {
return this._linesByPosition[position].isVisible();
};
Lines.prototype.getVisibleLines = function() {
var positions = {};
for (var position in this._linesByPosition) {
if (Utils.objectHasProperty(this._linesByPosition, position)) {
if (this._linesByPosition[position].isVisible()) {
positions[position] = true;
}
}
}
return positions;
};
Lines.prototype.getSourcesOnLineAfter = function(lineId, time) {
return this._linesByPosition[lineId].getSourcesAfter(time);
};
Lines.prototype.getSegmentsGroups = function() {
return this._segmentsGroups;
};
Lines.prototype.addToLayer = function(layer) {
for (var position in this._linesByPosition) {
if (Utils.objectHasProperty(this._linesByPosition, position)) {
this._linesByPosition[position].addToLayer(layer);
}
}
this._autoAddToLayer = true;
};
Lines.prototype.updateLines = function(position) {
this._updateLinesPosition(position);
};
Lines.prototype._updateLinesPosition = function(position, forceNewY) {
var line = this._linesByPosition[position];
var dy = null;
var newY;
if (forceNewY) {
newY = forceNewY;
}
else {
newY = line.getY() + line.lineHeight() + this._peaks.options.interline;
}
for (var pos in this._linesByPosition) {
if (Utils.objectHasProperty(this._linesByPosition, pos)) {
if (parseInt(pos, 10) > position) {
if (dy === null) {
dy = newY - this._linesByPosition[pos].getY();
this._linesByPosition[pos].moveOnY(dy);
}
else {
this._linesByPosition[pos].moveOnY(dy);
}
}
}
}
this._lineIndicator.updateIndicators();
this._lineIndicator.draw();
this._view.drawSourcesLayer();
};
Lines.prototype.setOffsetY = function(frameOffset) {
for (var position in this._linesByPosition) {
if (Utils.objectHasProperty(this._linesByPosition, position)) {
var line = this._linesByPosition[position];
line.y(line.getInitialY() - frameOffset);
}
}
this._lineIndicator.updateIndicators();
this._lineIndicator.draw();
};
Lines.prototype.height = function() {
var height = 2 * this._peaks.options.padding;
for (var position in this._linesByPosition) {
if (Utils.objectHasProperty(this._linesByPosition, position)) {
height += this._linesByPosition[position].lineHeight() + this._peaks.options.interline;
}
}
height -= this._peaks.options.interline;
return height;
};
Lines.prototype.linesLength = function() {
var length = 0;
for (var position in this._linesByPosition) {
if (Utils.objectHasProperty(this._linesByPosition, position)) {
var lineLength = this._linesByPosition[position].lineLength();
if (lineLength > length) {
length = lineLength;
}
}
}
return length;
};
Lines.prototype.manageVerticalPosition = function(source, newY) {
if (newY !== null && newY !== undefined) {
var pos = this.getLineOnPosition(newY);
if (pos[0] === pos[1]
&& pos[0] !== source.position
&& !this._linesByPosition[pos[0]].isSegmentsLine()) {
this.moveSourceToPosition(source, pos[0]);
}
}
};
Lines.prototype.getLineByPosition = function(pos) {
return this._linesByPosition[pos];
};
Lines.prototype.getLineOnPosition = function(y) {
var height;
var pos = [-1, Number.MAX_VALUE];
for (var position in this._linesByPosition) {
if (Utils.objectHasProperty(this._linesByPosition, position)) {
height = this._linesByPosition[position].lineHeight();
if (y > this._linesByPosition[position].getY()) {
pos[0] = Math.max(pos[0], parseInt(position, 10));
}
if (y < this._linesByPosition[position].getY() + height) {
pos[1] = Math.min(pos[1], parseInt(position, 10));
}
}
}
return pos;
};
Lines.prototype.moveSourceToPosition = function(source, pos) {
var sourceGroup = this._linesByPosition[source.position].removeSourceGroup(source, true);
delete this._linesBySourceId[source.id];
sourceGroup.moveTo(this._linesByPosition[pos].getKonvaGroup());
this._updateLinesPosition(source.position);
this.addSourceGroup(sourceGroup, pos);
};
Lines.prototype._getNextLineId = function() {
this._lineId++;
return this._lineId;
};
Lines.prototype._createLine = function(position) {
var y = this._peaks.options.padding;
var currentPos;
var newLinesByPosition = Object.assign({},this._linesByPosition);
for (var pos in this._linesByPosition) {
if (Utils.objectHasProperty(this._linesByPosition, pos)) {
currentPos = parseInt(pos, 10);
if (currentPos < position) {
y += this._linesByPosition[pos].lineHeight() + this._peaks.options.interline;
}
else {
if (this._linesByPosition[position]) {
this._linesByPosition[currentPos].updatePosition(currentPos + 1);
newLinesByPosition[currentPos + 1] = this._linesByPosition[currentPos];
}
}
}
}
var line = new Line(this._peaks, this._view, y, this._getNextLineId(), position);
this._lineIndicator.addIndicator(line);
if (this._autoAddToLayer) {
line.addToLayer(this._layer);
}
newLinesByPosition[position] = line;
this._linesByPosition = newLinesByPosition;
};
Lines.prototype.updateSegments = function(frameStartTime, frameEndTime) {
for (var lineId in this._segmentsGroups) {
if (Utils.objectHasProperty(this._segmentsGroups, lineId)) {
this._segmentsGroups[lineId].updateSegments(frameStartTime, frameEndTime);
}
}
};
Lines.prototype.manageCollision = function(source, newStartX, newEndX) {
return this._linesBySourceId[source.id].manageCollision(source, newStartX, newEndX);
};
Lines.prototype.manageSourceOrder = function(source, newStartX, newEndX) {
return this._linesBySourceId[source.id].manageSourceOrder(source, newStartX, newEndX);
};
// Lines.prototype.rescale = function() {
// for (var position in this._linesByPosition) {
// if (Utils.objectHasProperty(this._linesByPosition, position)) {
// this._linesByPosition[position].rescale();
// }
// }
// };
Lines.prototype._setInteractions = function(position) {
var line = this._linesByPosition[position];
if (this._areInteractionsOverridden) {
line.allowInteractions(this._areInteractionsAllowed);
}
else {
line.allowInteractions(
line.isSegmentsLine() ?
this._areSegmentInteractionsAllowed :
this._areSourceInteractionsAllowed
);
}
};
Lines.prototype.overrideInteractions = function(bool, areInteractionsAllowed) {
this._areInteractionsOverridden = typeof bool !== 'undefined' ?
bool : this._areInteractionsOverridden;
this._areInteractionsAllowed = typeof areInteractionsAllowed !== 'undefined' ?
areInteractionsAllowed : this._areInteractionsAllowed;
for (var position in this._linesByPosition) {
if (Utils.objectHasProperty(this._linesByPosition, position)) {
this._setInteractions(position);
}
}
};
Lines.prototype.allowInteractions = function(forSources, forSegments) {
this._areSourceInteractionsAllowed = typeof forSources !== 'undefined' ?
forSources : this._areSourceInteractionsAllowed;
this._areSegmentInteractionsAllowed = typeof forSegments !== 'undefined' ?
forSegments : this._areSegmentInteractionsAllowed;
for (var position in this._linesByPosition) {
if (Utils.objectHasProperty(this._linesByPosition, position)) {
this._setInteractions(position);
}
}
};
return Lines;
});