UNPKG

@checksub_team/peaks_timeline

Version:

JavaScript UI component for displaying audio waveforms

394 lines (356 loc) 11.3 kB
/** * @file * * Defines the {@link Segment} class. * * @module segment */ define([ './utils' ], function(Utils) { 'use strict'; function validateSegment(peaks, options, context) { var shouldNotifyUpdate = false; if (!Utils.isValidTime(options.startTime)) { throw new TypeError('peaks.segments.' + context + ': startTime should be a valid number'); } if (!Utils.isValidTime(options.endTime)) { options.endTime = options.startTime; shouldNotifyUpdate = true; } options.startTime = Utils.roundTime(options.startTime); options.endTime = Utils.roundTime(options.endTime); if (options.startTime < 0) { options.startTime = 0; shouldNotifyUpdate = true; } if (options.endTime < 0) { options.endTime = 0; shouldNotifyUpdate = true; } else if (options.endTime - options.startTime < peaks.options.minSegmentSize) { options.endTime = options.startTime + peaks.options.minSegmentSize; shouldNotifyUpdate = true; } options.startTime = Utils.roundTime(options.startTime); options.endTime = Utils.roundTime(options.endTime); if (options.opacity < 0 || options.opacity > 1) { throw new RangeError('peaks.segments.' + context + ': opacity should be between 0 and 1'); } if (Utils.isNullOrUndefined(options.labelText)) { options.labelText = ''; } else if (!Utils.isString(options.labelText)) { throw new TypeError('peaks.segments.' + context + ': labelText must be a string'); } if (!Utils.isInteger(options.line)) { throw new TypeError('peaks.segments.' + context + ': line must be an integer'); } if (Utils.isNullOrUndefined(options.editable)) { options.editable = true; } else if (!Utils.isBoolean(options.editable)) { throw new TypeError('peaks.segments.' + context + ': editable must be a boolean'); } if (Utils.isNullOrUndefined(options.hoverColor)) { options.hoverColor = Utils.shadeColor(options.color, 20); } else if (!Utils.isValidColor(options.hoverColor)) { throw new TypeError('peaks.segments.' + context + ': hoverColor must be a boolean'); } if (Utils.isNullOrUndefined(options.warningColor)) { options.warningColor = '#E48023'; } else if (!Utils.isValidColor(options.warningColor)) { throw new TypeError('peaks.segments.' + context + ': warningColor must be a boolean'); } return shouldNotifyUpdate; } /** * A segment is a region of time, with associated label and color. * * @class * @alias Segment * * @param {Peaks} peaks A reference to the Peaks instance. * @param {String} id A unique identifier for the segment. * @param {Number} startTime Segment start time, in seconds. * @param {Number} endTime Segment end time, in seconds. * @param {String} labelText Segment label text. * @param {String} color Segment waveform color. * @param {Number} opacity Segment waveform opacity. * @param {Boolean} editable If <code>true</code> the segment start and * end times can be adjusted via the user interface. * @param {Boolean} allowDeletion If <code>true</code> the segment can be * deleted using the delete key. * @param {Number} line The id of the line to add the segment to. * @param {Array<String>} indicators Array containing the colors * of all indicators. */ function Segment(peaks, id, startTime, endTime, duration, labelText, color, textColor, handleTextColor, hoverColor, warningColor, opacity, borderColor, borderWidth, borderRadius, editable, allowDeletion, line, indicators) { var opts = { startTime: startTime, endTime: endTime, duration: duration, labelText: labelText, color: color, textColor: textColor, handleTextColor: handleTextColor, hoverColor: hoverColor, warningColor: warningColor, opacity: opacity, borderColor: borderColor, borderWidth: borderWidth, borderRadius: borderRadius, editable: editable, allowDeletion: allowDeletion, line: line, indicators: indicators }; var shouldNotifyUpdate = validateSegment(peaks, opts, 'add()'); this._peaks = peaks; this._id = id; this._startTime = opts.startTime; this._endTime = opts.endTime; this._duration = opts.duration; this._labelText = opts.labelText; this._color = opts.color; this._hoverColor = opts.hoverColor; this._textColor = opts.textColor; this._handleTextColor = opts.handleTextColor; this._warningColor = opts.warningColor; this._opacity = opts.opacity; this._borderColor = opts.borderColor; this._borderWidth = opts.borderWidth; this._borderRadius = opts.borderRadius; this._editable = opts.editable; this._allowDeletion = opts.allowDeletion; this._line = opts.line; this._indicators = opts.indicators; this._minSize = peaks.options.minSegmentSize; this._relativeId = 0; this._selected = false; if (shouldNotifyUpdate) { peaks.emit('segments.updated', [this]); } } Object.defineProperties(Segment.prototype, { id: { enumerable: true, get: function() { return this._id; } }, startTime: { enumerable: true, get: function() { return this._startTime; }, set: function(time) { this._startTime = Utils.roundTime(time); } }, endTime: { enumerable: true, get: function() { return this._endTime; }, set: function(time) { this._endTime = Utils.roundTime(time); } }, duration: { enumerable: true, get: function() { return this._duration; }, set: function(duration) { this._duration = Utils.roundTime(duration); } }, labelText: { enumerable: true, get: function() { return this._labelText; } }, color: { enumerable: true, get: function() { return this._color; } }, hoverColor: { enumerable: true, get: function() { return this._hoverColor; } }, textColor: { enumerable: true, get: function() { return this._textColor; } }, handleTextColor: { enumerable: true, get: function() { return this._handleTextColor; } }, warningColor: { enumerable: true, get: function() { return this._warningColor; } }, opacity: { enumerable: true, get: function() { return this._opacity; } }, borderColor: { enumerable: true, get: function() { return this._borderColor; } }, borderWidth: { enumerable: true, get: function() { return this._borderWidth; } }, borderRadius: { enumerable: true, get: function() { return this._borderRadius; } }, editable: { enumerable: true, get: function() { return this._editable; } }, allowDeletion: { enumerable: true, get: function() { return this._allowDeletion; } }, line: { enumerable: true, get: function() { return this._line; } }, indicators: { enumerable: true, get: function() { return this._indicators; } }, minSize: { enumerable: true, get: function() { return this._minSize; } }, relativeId: { enumerable: true, get: function() { return this._relativeId; }, set: function(newId) { this._relativeId = newId; } }, selected: { enumerable: true, get: function() { return this._selected; }, set: function(selected) { this._selected = selected; } } }); Segment.prototype.update = function(options) { var opts = { startTime: this.startTime, endTime: this.endTime, duration: this.duration, labelText: this.labelText, color: this.color, textColor: this.textColor, handleTextColor: this.handleTextColor, hoverColor: this.hoverColor, warningColor: this.warningColor, opacity: this.opacity, borderColor: this.borderColor, borderWidth: this.borderWidth, borderRadius: this.borderRadius, editable: this.editable, allowDeletion: this.allowDeletion, line: this.line, indicators: this.indicators }; Utils.extend(opts, options); validateSegment(this._peaks, opts, 'update()'); this._startTime = opts.startTime; this._endTime = opts.endTime; this._duration = opts.duration; this._labelText = opts.labelText; this._color = opts.color; this._textColor = opts.textColor; this._handleTextColor = opts.handleTextColor; this._hoverColor = opts.hoverColor; this._warningColor = opts.warningColor; this._opacity = opts.opacity; this._borderColor = opts.borderColor; this._borderWidth = opts.borderWidth; this._borderRadius = opts.borderRadius; this._editable = opts.editable; this._allowDeletion = opts.allowDeletion; this._line = opts.line; this._indicators = opts.indicators; this._peaks.emit('segment.updated', this); }; Segment.prototype.setSelected = function(selected) { this._selected = selected; this._peaks.emit('segment.selected', this); }; /** * Returns <code>true</code> if the segment overlaps a given time region. * * @param {Number} startTime The start of the time region, in seconds. * @param {Number} endTime The end of the time region, in seconds. * @returns {Boolean} * * @see http://wiki.c2.com/?TestIfDateRangesOverlap */ Segment.prototype.isVisible = function(startTime, endTime) { return this.startTime < endTime && startTime < this.endTime; }; /** * Update the indicators of this segment. * * @param {Array<String>} newIndicators The new indicators. */ Segment.prototype.setIndicators = function(newIndicators) { this._indicators = newIndicators; this._peaks.emit('segment.setIndicators', this); }; /** * Returns <code>true</code> if a warning should be shown */ Segment.prototype.shouldShowWarning = function() { return this.duration > Utils.roundTime(this.endTime - this.startTime); }; return Segment; });