@checksub_team/peaks_timeline
Version:
JavaScript UI component for displaying audio waveforms
184 lines (150 loc) • 4.18 kB
JavaScript
/**
* @file
*
* Defines the {@link LineHandler} class.
*
* @module line-handler
*/
define([
'./models/line',
'./utils'
], function(Line, Utils) {
'use strict';
/**
* Line parameters.
*
* @typedef {Object} LineOptions
* @global
* @param {String} id A unique identifier for the line.
* @param {Number} position Position of the line on the timeline.
* @param {String} indicatorType Type of the line indicator.
* @param {String} indicatorText Text to display above the line indicator.
* @param {String} indicatorSubText Text to display below the line indicator.
* @param {Boolean} locked Whether the line is locked in place.
*/
/**
* Handles all functionality related to the adding, removing and manipulation
* of lines.
*
* @class
* @alias LineHandler
*
* @param {Peaks} peaks The parent Peaks object.
*/
function LineHandler(peaks) {
this._peaks = peaks;
this._lines = [];
this._linesById = {};
}
/**
* Adds a new line object.
*
* @private
* @param {Line} line
*/
LineHandler.prototype._addLine = function(line) {
this._linesById[line.id] = line;
};
/**
* Creates a new line object.
*
* @private
* @param {LineOptions} options
* @return {Line}
*/
LineHandler.prototype._createLine = function(options) {
if (!Utils.isObject(options)) {
throw new TypeError('peaks.lines.add(): expected a Line object parameter');
}
var line = new Line(
this._peaks,
Utils.isNullOrUndefined(options.id) ? Utils.createUuidv4() : options.id,
options.position,
options.indicatorType,
options.indicatorText,
options.indicatorSubText,
options.locked
);
return line;
};
/**
* Returns all lines.
*
* @returns {Array<Line>}
*/
LineHandler.prototype.getLines = function() {
return Object.values(this._linesById);
};
/**
* Returns all lines, indexed by their id.
*
* @returns {Object<String, Line>}
*/
LineHandler.prototype.getLinesById = function() {
return this._linesById;
};
/**
* Returns the line with the given id, or <code>null</code> if not found.
*
* @param {String} id
* @returns {Line|null}
*/
LineHandler.prototype.getLine = function(id) {
return this._linesById[id] || null;
};
/**
* Adds one or more lines to the timeline.
*
* @param {LineOptions|Array<LineOptions>} lineOrLines
*/
LineHandler.prototype.add = function(/* lineOrLines */) {
var lines = Array.isArray(arguments[0]) ?
arguments[0] :
Array.prototype.slice.call(arguments);
lines = lines.map(function(lineOptions) {
var line = this._createLine(lineOptions);
if (Utils.objectHasProperty(this._linesById, line.id)) {
var existingLine = this._linesById[line.id];
throw new Error('peaks.lines.add(): duplicate id. \n\n Line I = ' +
JSON.stringify(
existingLine.toSerializable()
) + ' Line II = ' +
JSON.stringify(
line.toSerializable()
)
);
}
return line;
}.bind(this));
lines.forEach(function(line) {
this._addLine(line);
}.bind(this));
this._peaks.emit('handler.lines.add', lines);
return lines;
};
/**
* Removes any lines with the given id(s).
*
* @param {String} id
* @param {Array<String>} ids
* @returns {Array<Line>} The removed {@link Line} objects.
*/
LineHandler.prototype.removeById = function(/* lineIdOrIds */) {
var lineIds = Array.isArray(arguments[0]) ?
arguments[0] :
Array.prototype.slice.call(arguments);
const lines = lineIds.map(function(lineId) {
const line = this._linesById[lineId];
if (!line) {
throw new Error('peaks.lines.removeById(): line with id ' + lineId + ' not found');
}
return line;
}.bind(this));
lines.forEach(function(line) {
delete this._linesById[line.id];
}.bind(this));
this._peaks.emit('handler.lines.remove', lines);
return lines;
};
return LineHandler;
});