UNPKG

waveform-playlist-nartj

Version:

Multiple track web audio editor and player with waveform preview

274 lines (239 loc) 9.94 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _h = _interopRequireDefault(require("virtual-dom/h")); var _aeneas = _interopRequireDefault(require("./input/aeneas")); var _aeneas2 = _interopRequireDefault(require("./output/aeneas")); var _conversions = require("../utils/conversions"); var _DragInteraction = _interopRequireDefault(require("../interaction/DragInteraction")); var _ScrollTopHook = _interopRequireDefault(require("./render/ScrollTopHook")); var _timeformat = _interopRequireDefault(require("../utils/timeformat")); var AnnotationList = /*#__PURE__*/function () { function AnnotationList(playlist, annotations) { var controls = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : []; var editable = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; var linkEndpoints = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false; var isContinuousPlay = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : false; (0, _classCallCheck2["default"])(this, AnnotationList); this.playlist = playlist; this.resizeHandlers = []; this.editable = editable; this.annotations = annotations.map(function (a) { return (// TODO support different formats later on. (0, _aeneas["default"])(a) ); }); this.setupInteractions(); this.controls = controls; this.setupEE(playlist.ee); // TODO actually make a real plugin system that's not terrible. this.playlist.isContinuousPlay = isContinuousPlay; this.playlist.linkEndpoints = linkEndpoints; this.length = this.annotations.length; } (0, _createClass2["default"])(AnnotationList, [{ key: "setupInteractions", value: function setupInteractions() { var _this = this; this.annotations.forEach(function (a, i) { var leftShift = new _DragInteraction["default"](_this.playlist, { direction: 'left', index: i }); var rightShift = new _DragInteraction["default"](_this.playlist, { direction: 'right', index: i }); _this.resizeHandlers.push(leftShift); _this.resizeHandlers.push(rightShift); }); } }, { key: "setupEE", value: function setupEE(ee) { var _this2 = this; ee.on('dragged', function (deltaTime, data) { var annotationIndex = data.index; var annotations = _this2.annotations; var note = annotations[annotationIndex]; // resizing to the left if (data.direction === 'left') { var originalVal = note.start; note.start += deltaTime; if (note.start < 0) { note.start = 0; } if (annotationIndex && annotations[annotationIndex - 1].end > note.start) { annotations[annotationIndex - 1].end = note.start; } if (_this2.playlist.linkEndpoints && annotationIndex && annotations[annotationIndex - 1].end === originalVal) { annotations[annotationIndex - 1].end = note.start; } } else { // resizing to the right var _originalVal = note.end; note.end += deltaTime; if (note.end > _this2.playlist.duration) { note.end = _this2.playlist.duration; } if (annotationIndex < annotations.length - 1 && annotations[annotationIndex + 1].start < note.end) { annotations[annotationIndex + 1].start = note.end; } if (_this2.playlist.linkEndpoints && annotationIndex < annotations.length - 1 && annotations[annotationIndex + 1].start === _originalVal) { annotations[annotationIndex + 1].start = note.end; } } _this2.playlist.drawRequest(); }); ee.on('continuousplay', function (val) { _this2.playlist.isContinuousPlay = val; }); ee.on('linkendpoints', function (val) { _this2.playlist.linkEndpoints = val; }); ee.on('annotationsrequest', function () { _this2["export"](); }); return ee; } }, { key: "export", value: function _export() { var output = this.annotations.map(function (a) { return (0, _aeneas2["default"])(a); }); var dataStr = "data:text/json;charset=utf-8,".concat(encodeURIComponent(JSON.stringify(output))); var a = document.createElement('a'); document.body.appendChild(a); a.href = dataStr; a.download = 'annotations.json'; a.click(); document.body.removeChild(a); } }, { key: "renderResizeLeft", value: function renderResizeLeft(i) { var events = _DragInteraction["default"].getEvents(); var config = { attributes: { style: 'position: absolute; height: 30px; width: 10px; top: 0; left: -2px', draggable: true } }; var handler = this.resizeHandlers[i * 2]; events.forEach(function (event) { config["on".concat(event)] = handler[event].bind(handler); }); return (0, _h["default"])('div.resize-handle.resize-w', config); } }, { key: "renderResizeRight", value: function renderResizeRight(i) { var events = _DragInteraction["default"].getEvents(); var config = { attributes: { style: 'position: absolute; height: 30px; width: 10px; top: 0; right: -2px', draggable: true } }; var handler = this.resizeHandlers[i * 2 + 1]; events.forEach(function (event) { config["on".concat(event)] = handler[event].bind(handler); }); return (0, _h["default"])('div.resize-handle.resize-e', config); } }, { key: "renderControls", value: function renderControls(note, i) { var _this3 = this; // seems to be a bug with references, or I'm missing something. var that = this; return this.controls.map(function (ctrl) { return (0, _h["default"])("i.".concat(ctrl["class"]), { attributes: { title: ctrl.title }, onclick: function onclick() { ctrl.action(note, i, that.annotations, { linkEndpoints: that.playlist.linkEndpoints }); _this3.setupInteractions(); that.playlist.drawRequest(); } }); }); } }, { key: "render", value: function render() { var _this4 = this; var boxes = (0, _h["default"])('div.annotations-boxes', { attributes: { style: 'height: 30px;' } }, this.annotations.map(function (note, i) { var samplesPerPixel = _this4.playlist.samplesPerPixel; var sampleRate = _this4.playlist.sampleRate; var pixPerSec = sampleRate / samplesPerPixel; var pixOffset = (0, _conversions.secondsToPixels)(_this4.playlist.scrollLeft, samplesPerPixel, sampleRate); var left = Math.floor(note.start * pixPerSec - pixOffset); var width = Math.ceil(note.end * pixPerSec - note.start * pixPerSec); return (0, _h["default"])('div.annotation-box', { attributes: { style: "position: absolute; height: 30px; width: ".concat(width, "px; left: ").concat(left, "px"), 'data-id': note.id } }, [_this4.renderResizeLeft(i), (0, _h["default"])('span.id', { onclick: function onclick() { if (_this4.playlist.isContinuousPlay) { _this4.playlist.ee.emit('play', _this4.annotations[i].start); } else { _this4.playlist.ee.emit('play', _this4.annotations[i].start, _this4.annotations[i].end); } } }, [note.id]), _this4.renderResizeRight(i)]); })); var boxesWrapper = (0, _h["default"])('div.annotations-boxes-wrapper', { attributes: { style: 'overflow: hidden;' } }, [boxes]); var text = (0, _h["default"])('div.annotations-text', { hook: new _ScrollTopHook["default"]() }, this.annotations.map(function (note, i) { var format = (0, _timeformat["default"])(_this4.playlist.durationFormat); var start = format(note.start); var end = format(note.end); var segmentClass = ''; if (_this4.playlist.isPlaying() && _this4.playlist.playbackSeconds >= note.start && _this4.playlist.playbackSeconds <= note.end) { segmentClass = '.current'; } var editableConfig = { attributes: { contenteditable: true }, oninput: function oninput(e) { // needed currently for references // eslint-disable-next-line no-param-reassign note.lines = [e.target.innerText]; }, onkeypress: function onkeypress(e) { if (e.which === 13 || e.keyCode === 13) { e.target.blur(); e.preventDefault(); } } }; var linesConfig = _this4.editable ? editableConfig : {}; return (0, _h["default"])("div.annotation".concat(segmentClass), [(0, _h["default"])('span.annotation-id', [note.id]), (0, _h["default"])('span.annotation-start', [start]), (0, _h["default"])('span.annotation-end', [end]), (0, _h["default"])('span.annotation-lines', linesConfig, [note.lines]), (0, _h["default"])('span.annotation-actions', _this4.renderControls(note, i))]); })); return (0, _h["default"])('div.annotations', [boxesWrapper, text]); } }]); return AnnotationList; }(); var _default = AnnotationList; exports["default"] = _default;