UNPKG

@xzdarcy/react-timeline-editor

Version:

[![npm version](https://img.shields.io/npm/v/@xzdarcy/react-timeline-editor.svg?style=flat-square)](https://www.npmjs.com/package/@xzdarcy/react-timeline-editor) [![npm downloads](https://img.shields.io/npm/dm/@xzdarcy/react-timeline-editor.svg?style=flat

1,782 lines (1,496 loc) 96.6 kB
import React, { useRef, useEffect, cloneElement, useImperativeHandle, useState, useLayoutEffect } from 'react'; import { AutoSizer, Grid, ScrollSync } from 'react-virtualized'; import { prefixNames } from 'framework-utils'; import interact from 'interactjs'; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } function _objectSpread2(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); } function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _possibleConstructorReturn(self, call) { if (call && (typeof call === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); } function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); } function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } /** * 事件派发器 */ var Emitter = /*#__PURE__*/function () { function Emitter(events) { _classCallCheck(this, Emitter); this.events = {}; this.events = events.handlers; } _createClass(Emitter, [{ key: "on", value: function on(names, handler) { var _this = this; var events = names instanceof Array ? names : names.split(' '); events.forEach(function (name) { if (!_this.events[name]) { throw new Error("The event ".concat(name, " does not exist")); } _this.events[name].push(handler); }); return this; } }, { key: "trigger", value: function trigger(name, params) { if (!(name in this.events)) { throw new Error("The event ".concat(String(name), " cannot be triggered")); } return this.events[name].reduce(function (r, e) { return e(params) !== false && r; }, true); // return false if at least one event is false } }, { key: "bind", value: function bind(name) { if (this.events[name]) { throw new Error("The event ".concat(name, " is already bound")); } this.events[name] = []; } }, { key: "exist", value: function exist(name) { return Array.isArray(this.events[name]); } }, { key: "off", value: function off(name, handler) { if (this.events[name]) { var listener = this.events[name]; if (!handler) this.events[name] = [];else { var index = listener.indexOf(handler); if (index !== -1) listener.splice(index, 1); } } } }, { key: "offAll", value: function offAll() { this.events = Object.fromEntries(Object.keys(this.events).map(function (name) { return [name, []]; })); } }]); return Emitter; }(); var Events = /*#__PURE__*/_createClass(function Events() { var handlers = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; _classCallCheck(this, Events); this.handlers = {}; this.handlers = _objectSpread2({ beforeSetTime: [], afterSetTime: [], setTimeByTick: [], beforeSetPlayRate: [], afterSetPlayRate: [], setActiveActionIds: [], play: [], paused: [], ended: [] }, handlers); }); var PLAYING = 'playing'; var PAUSED = 'paused'; /** * 时间轴播放器 * 可脱离编辑器单独运行 * @export * @class TimelineEngine * @extends {Emitter<EventTypes>} */ var TimelineEngine = /*#__PURE__*/function (_Emitter) { _inherits(TimelineEngine, _Emitter); var _super = _createSuper(TimelineEngine); function TimelineEngine() { var _this; _classCallCheck(this, TimelineEngine); _this = _super.call(this, new Events()); _this._timerId = void 0; _this._playRate = 1; _this._currentTime = 0; _this._playState = 'paused'; _this._prev = void 0; _this._effectMap = {}; _this._actionMap = {}; _this._actionSortIds = []; _this._next = 0; _this._activeActionIds = []; return _this; } /** requestAnimationFrame timerId */ _createClass(TimelineEngine, [{ key: "isPlaying", get: /** 是否正在播放 */ function get() { return this._playState === 'playing'; } /** 是否暂停中 */ }, { key: "isPaused", get: function get() { return this._playState === 'paused'; } }, { key: "effects", set: function set(effects) { this._effectMap = effects; } }, { key: "data", set: function set(data) { if (this.isPlaying) this.pause(); this._dealData(data); this._dealClear(); this._dealEnter(this._currentTime); } /** * 设置播放速率 * @memberof TimelineEngine */ }, { key: "setPlayRate", value: function setPlayRate(rate) { if (rate <= 0) { console.error('Error: rate cannot be less than 0!'); return; } var result = this.trigger('beforeSetPlayRate', { rate: rate, engine: this }); if (!result) return false; this._playRate = rate; this.trigger('afterSetPlayRate', { rate: rate, engine: this }); return true; } /** * 获取播放速率 * @memberof TimelineEngine */ }, { key: "getPlayRate", value: function getPlayRate() { return this._playRate; } /** * 重新渲染当前时间 * @return {*} * @memberof TimelineEngine */ }, { key: "reRender", value: function reRender() { if (this.isPlaying) return; this._tickAction(this._currentTime); } /** * 设置播放时间 * @param {number} time * @param {boolean} [isTick] 是否是tick触发 * @memberof TimelineEngine */ }, { key: "setTime", value: function setTime(time, isTick) { var result = isTick || this.trigger('beforeSetTime', { time: time, engine: this }); if (!result) return false; this._currentTime = time; this._next = 0; this._dealLeave(time); this._dealEnter(time); if (isTick) this.trigger('setTimeByTick', { time: time, engine: this });else this.trigger('afterSetTime', { time: time, engine: this }); return true; } /** * 获取当前时间 * @return {*} {number} * @memberof TimelineEngine */ }, { key: "getTime", value: function getTime() { return this._currentTime; } /** * 运行: 开始时间为当前time * @param param * @return {boolean} {boolean} */ }, { key: "play", value: function play(param) { var _this2 = this; var toTime = param.toTime, autoEnd = param.autoEnd; var currentTime = this.getTime(); /** 当前状体啊正在播放中 or 运行终止时间小于开始时间 直接返回*/ if (this.isPlaying || toTime && toTime <= currentTime) return false; // 设置运行状态 this._playState = PLAYING; // activeIds 运行 start this._startOrStop('start'); // 触发事件 this.trigger('play', { engine: this }); this._timerId = requestAnimationFrame(function (time) { _this2._prev = time; _this2._tick({ now: time, autoEnd: autoEnd, to: toTime }); }); return true; } /** * 暂停播放 * @memberof TimelineEngine */ }, { key: "pause", value: function pause() { if (this.isPlaying) { this._playState = PAUSED; // activeIds 运行 stop this._startOrStop('stop'); this.trigger('paused', { engine: this }); } cancelAnimationFrame(this._timerId); } /** 播放完成 */ }, { key: "_end", value: function _end() { this.pause(); this.trigger('ended', { engine: this }); } }, { key: "_startOrStop", value: function _startOrStop(type) { for (var i = 0; i < this._activeActionIds.length; i++) { var actionId = this._activeActionIds[i]; var action = this._actionMap[actionId]; var effect = this._effectMap[action === null || action === void 0 ? void 0 : action.effectId]; if (type === 'start') { var _effect$source; (effect === null || effect === void 0 ? void 0 : (_effect$source = effect.source) === null || _effect$source === void 0 ? void 0 : _effect$source.start) && effect.source.start({ action: action, effect: effect, engine: this, isPlaying: this.isPlaying, time: this.getTime() }); } else if (type === 'stop') { var _effect$source2; (effect === null || effect === void 0 ? void 0 : (_effect$source2 = effect.source) === null || _effect$source2 === void 0 ? void 0 : _effect$source2.stop) && effect.source.stop({ action: action, effect: effect, engine: this, isPlaying: this.isPlaying, time: this.getTime() }); } } } /** 每帧执行 */ }, { key: "_tick", value: function _tick(data) { var _this3 = this; if (this.isPaused) return; var now = data.now, autoEnd = data.autoEnd, to = data.to; // 计算当前时间 var currentTime = this.getTime() + Math.min(1000, now - this._prev) / 1000 * this._playRate; this._prev = now; // 设置当前时间 if (to && to <= currentTime) currentTime = to; this.setTime(currentTime, true); // 执行动作 this._tickAction(currentTime); // 自动停止情况下,判断是否所有动作执行完毕 if (!to && autoEnd && this._next >= this._actionSortIds.length && this._activeActionIds.length === 0) { this._end(); return; } // 判断是否终止 if (to && to <= currentTime) { this._end(); } if (this.isPaused) return; this._timerId = requestAnimationFrame(function (time) { _this3._tick({ now: time, autoEnd: autoEnd, to: to }); }); } /** tick运行actions */ }, { key: "_tickAction", value: function _tickAction(time) { this._dealEnter(time); this._dealLeave(time); // render var length = this._activeActionIds.length; for (var i = 0; i < length; i++) { var _effect$source3; var actionId = this._activeActionIds[i]; var action = this._actionMap[actionId]; var effect = this._effectMap[action.effectId]; if (effect && ((_effect$source3 = effect.source) === null || _effect$source3 === void 0 ? void 0 : _effect$source3.update)) { effect.source.update({ time: time, action: action, isPlaying: this.isPlaying, effect: effect, engine: this }); } } } /** 重置active数据 */ }, { key: "_dealClear", value: function _dealClear() { while (this._activeActionIds.length) { var _effect$source4; var actionId = this._activeActionIds.shift(); var action = this._actionMap[actionId]; var effect = this._effectMap[action === null || action === void 0 ? void 0 : action.effectId]; if (effect === null || effect === void 0 ? void 0 : (_effect$source4 = effect.source) === null || _effect$source4 === void 0 ? void 0 : _effect$source4.leave) { effect.source.leave({ action: action, effect: effect, engine: this, isPlaying: this.isPlaying, time: this.getTime() }); } } this._next = 0; } /** 处理action time enter */ }, { key: "_dealEnter", value: function _dealEnter(time) { // add to active while (this._actionSortIds[this._next]) { var actionId = this._actionSortIds[this._next]; var action = this._actionMap[actionId]; if (!action.disable) { // 判断动作开始时间是否到达 if (action.start > time) break; // 动作可以执行开始 if (action.end > time && !this._activeActionIds.includes(actionId)) { var _effect$source5; var effect = this._effectMap[action.effectId]; if (effect && ((_effect$source5 = effect.source) === null || _effect$source5 === void 0 ? void 0 : _effect$source5.enter)) { effect.source.enter({ action: action, effect: effect, isPlaying: this.isPlaying, time: time, engine: this }); } this._activeActionIds.push(actionId); } } this._next++; } } /** 处理action time leave */ }, { key: "_dealLeave", value: function _dealLeave(time) { var i = 0; while (this._activeActionIds[i]) { var actionId = this._activeActionIds[i]; var action = this._actionMap[actionId]; // 不在播放区域内 if (action.start > time || action.end < time) { var _effect$source6; var effect = this._effectMap[action.effectId]; if (effect && ((_effect$source6 = effect.source) === null || _effect$source6 === void 0 ? void 0 : _effect$source6.leave)) { effect.source.leave({ action: action, effect: effect, isPlaying: this.isPlaying, time: time, engine: this }); } this._activeActionIds.splice(i, 1); continue; } i++; } } /** 处理数据 */ }, { key: "_dealData", value: function _dealData(data) { var actions = []; data.map(function (row) { actions.push.apply(actions, _toConsumableArray(row.actions)); }); var sortActions = actions.sort(function (a, b) { return a.start - b.start; }); var actionMap = {}; var actionSortIds = []; sortActions.forEach(function (action) { actionSortIds.push(action.id); actionMap[action.id] = _objectSpread2({}, action); }); this._actionMap = actionMap; this._actionSortIds = actionSortIds; } }]); return TimelineEngine; }(Emitter); var PREFIX = "timeline-editor"; /** 开始时光标所在时间 */ var START_CURSOR_TIME = 0; /** 默认刻度 */ var DEFAULT_SCALE = 1; /** 默认刻度分割数量 */ var DEFAULT_SCALE_SPLIT_COUNT = 10; /** 默认刻度显示宽度 */ var DEFAULT_SCALE_WIDTH = 160; /** 默认刻度左侧开始距离 */ var DEFAULT_START_LEFT = 20; /** 默认移动最小像素 */ var DEFAULT_MOVE_GRID = 1; /** 默认吸附像素 */ var DEFAULT_ADSORPTION_DISTANCE = 8; /** 默认动作行高度 */ var DEFAULT_ROW_HEIGHT = 32; /** 最小scale数量 */ var MIN_SCALE_COUNT = 20; /** 每次新增scale个数 */ var ADD_SCALE_COUNT = 5; var LogLevel; (function (LogLevel) { LogLevel[LogLevel["VERBOSE"] = 0] = "VERBOSE"; LogLevel[LogLevel["LOG"] = 1] = "LOG"; LogLevel[LogLevel["INFO"] = 2] = "INFO"; LogLevel[LogLevel["WARN"] = 3] = "WARN"; LogLevel[LogLevel["ERROR"] = 4] = "ERROR"; LogLevel[LogLevel["FATAL"] = 5] = "FATAL"; LogLevel[LogLevel["SILENT"] = Infinity] = "SILENT"; })(LogLevel || (LogLevel = {})); var LogLevels = { VERBOSE: LogLevel.VERBOSE, LOG: LogLevel.LOG, INFO: LogLevel.INFO, WARN: LogLevel.WARN, ERROR: LogLevel.ERROR, SILENT: LogLevel.SILENT }; function colorize(hex, x) { return "color:".concat(hex, ";font-size:").concat(x, "px;"); } var ConsoleLogger = /*#__PURE__*/function () { /** * ConsoleLogger * @param {string} prefix Logger prefix * @return {ConsoleLogger} */ function ConsoleLogger(prefix) { _classCallCheck(this, ConsoleLogger); this.Levels = LogLevels; this.level = LogLevel.LOG; this.prefix = ''; this.enabled = true; this.debugColor = colorize('#cccccc', 12); this.logColor = colorize('#bbbbbb', 12); this.infoColor = colorize('#2196f3', 12); this.warnColor = colorize('#ff00ff', 12); this.errorColor = colorize('#e91e63', 12); this.fatalColor = colorize('#9a0101', 13); this.setPrefix(prefix); this.level = ConsoleLogger.level; ConsoleLogger.instances.push(this); } _createClass(ConsoleLogger, [{ key: "setPrefix", value: /** * set logger prefix * @param prefix */ function setPrefix(prefix) { this.prefix = prefix; } /** * enable logger with optional log level * @param level */ }, { key: "enable", value: function enable() { var level = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.level; this.level = level; this.enabled = true; } /** * disable logger */ }, { key: "disable", value: function disable() { this.enabled = false; } /** * Set log level * @param {LogLevel} level * @return {void} */ }, { key: "setLevel", value: function setLevel(level) { this.level = level; } /** * trace * @param title * @param args */ }, { key: "trace", value: function trace(title) { if (!this.enabled || this.level > LogLevel.VERBOSE) { return; } for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { args[_key - 1] = arguments[_key]; } if (ConsoleLogger.noColor) { var _console; (_console = console).trace.apply(_console, ["[".concat(this.prefix, "] ").concat(title)].concat(args)); } else { var _console2; (_console2 = console).trace.apply(_console2, ["%c[".concat(this.prefix, "] ").concat(title), this.debugColor].concat(args)); } } /** * debug * @param title * @param args */ }, { key: "debug", value: function debug(title) { if (!this.enabled || this.level > LogLevel.VERBOSE) { return; } for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { args[_key2 - 1] = arguments[_key2]; } if (ConsoleLogger.noColor) { var _console3; (_console3 = console).debug.apply(_console3, ["[".concat(this.prefix, "] ").concat(title)].concat(args)); } else { var _console4; (_console4 = console).debug.apply(_console4, ["%c[".concat(this.prefix, "] ").concat(title), this.debugColor].concat(args)); } } /** * log * @param title * @param args */ }, { key: "log", value: function log(title) { if (!this.enabled || this.level > LogLevel.LOG) { return; } for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) { args[_key3 - 1] = arguments[_key3]; } if (ConsoleLogger.noColor) { var _console5; (_console5 = console).log.apply(_console5, ["[".concat(this.prefix, "] ").concat(title)].concat(args)); } else { var _console6; (_console6 = console).log.apply(_console6, ["%c[".concat(this.prefix, "] ").concat(title), this.logColor].concat(args)); } } /** * info * @param title * @param args */ }, { key: "info", value: function info(title) { if (!this.enabled || this.level > LogLevel.INFO) { return; } for (var _len4 = arguments.length, args = new Array(_len4 > 1 ? _len4 - 1 : 0), _key4 = 1; _key4 < _len4; _key4++) { args[_key4 - 1] = arguments[_key4]; } if (ConsoleLogger.noColor) { var _console7; (_console7 = console).info.apply(_console7, ["[".concat(this.prefix, "] ").concat(title)].concat(args)); } else { var _console8; (_console8 = console).info.apply(_console8, ["%c[".concat(this.prefix, "] ").concat(title), this.infoColor].concat(args)); } } /** * warn * @param title * @param args */ }, { key: "warn", value: function warn(title) { if (!this.enabled || this.level > LogLevel.WARN) { return; } for (var _len5 = arguments.length, args = new Array(_len5 > 1 ? _len5 - 1 : 0), _key5 = 1; _key5 < _len5; _key5++) { args[_key5 - 1] = arguments[_key5]; } if (ConsoleLogger.noColor) { var _console9; (_console9 = console).warn.apply(_console9, ["[".concat(this.prefix, "] ").concat(title)].concat(args)); } else { var _console10; (_console10 = console).warn.apply(_console10, ["%c[".concat(this.prefix, "] ").concat(title), this.warnColor].concat(args)); } } /** * error * @param title * @param args */ }, { key: "error", value: function error(title) { if (!this.enabled || this.level > LogLevel.ERROR) { return; } for (var _len6 = arguments.length, args = new Array(_len6 > 1 ? _len6 - 1 : 0), _key6 = 1; _key6 < _len6; _key6++) { args[_key6 - 1] = arguments[_key6]; } if (ConsoleLogger.noColor) { var _console11; (_console11 = console).error.apply(_console11, ["[".concat(this.prefix, "] ").concat(title)].concat(args)); } else { var _console12; (_console12 = console).error.apply(_console12, ["%c[".concat(this.prefix, "] ").concat(title), this.errorColor].concat(args)); } } /** * fatal error * @param title * @param args */ }, { key: "fatal", value: function fatal(title) { if (!this.enabled || this.level > LogLevel.FATAL) { return; } for (var _len7 = arguments.length, args = new Array(_len7 > 1 ? _len7 - 1 : 0), _key7 = 1; _key7 < _len7; _key7++) { args[_key7 - 1] = arguments[_key7]; } if (ConsoleLogger.noColor) { var _console13; (_console13 = console).error.apply(_console13, ["[".concat(this.prefix, "] ").concat(title)].concat(args)); } else { var _console14; (_console14 = console).error.apply(_console14, ["%c[".concat(this.prefix, "] ").concat(title), this.fatalColor].concat(args)); } } /** * start a group with label * @param label */ }, { key: "group", value: function group() { if (console.group) { var _console15; (_console15 = console).group.apply(_console15, arguments); } } /** * end a group */ }, { key: "groupEnd", value: function groupEnd() { if (console.groupEnd) { console.groupEnd(); } } /** * collapse log group * @param label */ }, { key: "groupCollapsed", value: function groupCollapsed() { if (console.groupCollapsed) { var _console16; (_console16 = console).groupCollapsed.apply(_console16, arguments); } } }], [{ key: "setLevel", value: function setLevel(level) { this.level = level; this.instances.forEach(function (logger) { return logger.setLevel(level); }); } }, { key: "enable", value: function enable(level) { if (level) { this.level = level; } this.instances.forEach(function (logger) { return logger.enable(); }); } }, { key: "disable", value: function disable() { this.instances.forEach(function (logger) { return logger.disable(); }); } }]); return ConsoleLogger; }(); ConsoleLogger.instances = []; ConsoleLogger.level = LogLevel.LOG; ConsoleLogger.Levels = LogLevels; ConsoleLogger.noColor = false; var logger = new ConsoleLogger('timeline'); function checkProps(props) { var _props$editorData = props.editorData, editorData = _props$editorData === void 0 ? [] : _props$editorData, _props$effects = props.effects, effects = _props$effects === void 0 ? {} : _props$effects, _props$scrollTop = props.scrollTop, scrollTop = _props$scrollTop === void 0 ? 0 : _props$scrollTop, _props$scale = props.scale, scale = _props$scale === void 0 ? DEFAULT_SCALE : _props$scale, _props$scaleSplitCoun = props.scaleSplitCount, scaleSplitCount = _props$scaleSplitCoun === void 0 ? DEFAULT_SCALE_SPLIT_COUNT : _props$scaleSplitCoun, _props$scaleWidth = props.scaleWidth, scaleWidth = _props$scaleWidth === void 0 ? DEFAULT_SCALE_WIDTH : _props$scaleWidth, _props$startLeft = props.startLeft, startLeft = _props$startLeft === void 0 ? DEFAULT_START_LEFT : _props$startLeft, _props$minScaleCount = props.minScaleCount, minScaleCount = _props$minScaleCount === void 0 ? MIN_SCALE_COUNT : _props$minScaleCount, _props$maxScaleCount = props.maxScaleCount, maxScaleCount = _props$maxScaleCount === void 0 ? Infinity : _props$maxScaleCount, _props$rowHeight = props.rowHeight, rowHeight = _props$rowHeight === void 0 ? DEFAULT_ROW_HEIGHT : _props$rowHeight; if (scale <= 0) { logger.error('Error: scale must be greater than 0!'); scale = DEFAULT_SCALE; } if (scrollTop < 0) { logger.warn('Warning: scrollTop cannot be less than 0!'); scrollTop = 0; } if (scaleSplitCount <= 0) { logger.warn('Warning: scaleSplitCount cannot be less than 1!'); scaleSplitCount = 1; } if (scaleWidth <= 0) { logger.warn('Warning: scaleWidth must be greater than 0!'); scaleWidth = DEFAULT_SCALE_WIDTH; } if (startLeft < 0) { logger.warn('Warning: startLeft cannot be less than 0!'); startLeft = 0; } if (minScaleCount < 1) { logger.warn('Warning: minScaleCount must be greater than 1!'); minScaleCount = MIN_SCALE_COUNT; } minScaleCount = parseInt(minScaleCount + ''); if (maxScaleCount < minScaleCount) { logger.warn('Warning: maxScaleCount cannot be less than minScaleCount!'); maxScaleCount = minScaleCount; } maxScaleCount = maxScaleCount === Infinity ? Infinity : parseInt(maxScaleCount + ''); if (rowHeight <= 0) { logger.warn('Warning: rowHeight must be greater than 0!'); rowHeight = DEFAULT_ROW_HEIGHT; } var temp = _objectSpread2({}, props); delete temp['style']; return _objectSpread2(_objectSpread2({}, temp), {}, { editorData: editorData, effects: effects, scrollTop: scrollTop, scale: scale, scaleSplitCount: scaleSplitCount, scaleWidth: scaleWidth, startLeft: startLeft, minScaleCount: minScaleCount, maxScaleCount: maxScaleCount, rowHeight: rowHeight }); } /** 时间转像素 */ function parserTimeToPixel(data, param) { var startLeft = param.startLeft, scale = param.scale, scaleWidth = param.scaleWidth; return startLeft + data / scale * scaleWidth; } /** 像素转时间 */ function parserPixelToTime(data, param) { var startLeft = param.startLeft, scale = param.scale, scaleWidth = param.scaleWidth; return (data - startLeft) / scaleWidth * scale; } /** 位置 + 宽度 转 start + end */ function parserTransformToTime(data, param) { var left = data.left, width = data.width; var start = parserPixelToTime(left, param); var end = parserPixelToTime(left + width, param); return { start: start, end: end }; } /** start + end 转 位置 + 宽度 */ function parserTimeToTransform(data, param) { var start = data.start, end = data.end; var left = parserTimeToPixel(start, param); var width = parserTimeToPixel(end, param) - left; return { left: left, width: width }; } /** 根据数据获取刻度个数 */ function getScaleCountByRows(data, param) { var max = 0; data.forEach(function (row) { row.actions.forEach(function (action) { max = Math.max(max, action.end); }); }); var count = Math.ceil(max / param.scale); return count + ADD_SCALE_COUNT; } /** 根据时间获取目前刻度数 */ function getScaleCountByPixel(data, param) { var startLeft = param.startLeft, scaleWidth = param.scaleWidth; var count = Math.ceil((data - startLeft) / scaleWidth); return Math.max(count + ADD_SCALE_COUNT, param.scaleCount); } /** 获取动作全部时间的位置集合 */ function parserActionsToPositions(actions, param) { var positions = []; actions.forEach(function (item) { positions.push(parserTimeToPixel(item.start, param)); positions.push(parserTimeToPixel(item.end, param)); }); return positions; } function prefix() { for (var _len = arguments.length, classNames = new Array(_len), _key = 0; _key < _len; _key++) { classNames[_key] = arguments[_key]; } return prefixNames.apply(void 0, ["".concat(PREFIX, "-")].concat(classNames)); } var DEFAULT_SPEED = 1; var MAX_SPEED = 3; var CRITICAL_SIZE = 10; function useAutoScroll(target) { var leftBoundRef = useRef(Number.MIN_SAFE_INTEGER); var rightBoundRef = useRef(Number.MAX_SAFE_INTEGER); var speed = useRef(DEFAULT_SPEED); var frame = useRef(); var initAutoScroll = function initAutoScroll() { if (target === null || target === void 0 ? void 0 : target.current) { var _target$current$getBo = target.current.getBoundingClientRect(), left = _target$current$getBo.left, width = _target$current$getBo.width; leftBoundRef.current = left; rightBoundRef.current = left + width; } }; var dealDragAutoScroll = function dealDragAutoScroll(e, deltaScroll) { // 超出 if (e.clientX >= rightBoundRef.current || e.clientX <= leftBoundRef.current) { cancelAnimationFrame(frame.current); var over = Math.abs(e.clientX >= rightBoundRef.current ? e.clientX - rightBoundRef.current : e.clientX - leftBoundRef.current); speed.current = Math.min(Number((over / CRITICAL_SIZE).toFixed(0)) * DEFAULT_SPEED, MAX_SPEED); var dir = e.clientX >= rightBoundRef.current ? 1 : -1; var delta = dir * speed.current; var loop = function loop() { deltaScroll && deltaScroll(delta); frame.current = requestAnimationFrame(loop); }; frame.current = requestAnimationFrame(loop); return false; } else { cancelAnimationFrame(frame.current); } return true; }; var dealResizeAutoScroll = function dealResizeAutoScroll(e, dir, deltaScroll) { if (e.clientX >= rightBoundRef.current || e.clientX < leftBoundRef.current) { cancelAnimationFrame(frame.current); var over = Math.abs(e.clientX >= rightBoundRef.current ? e.clientX - rightBoundRef.current : e.clientX - leftBoundRef.current); speed.current = Math.min(Number((over / CRITICAL_SIZE).toFixed(0)) * DEFAULT_SPEED, MAX_SPEED); var direction = e.clientX >= rightBoundRef.current ? 1 : -1; var delta = direction * speed.current; var loop = function loop() { deltaScroll && deltaScroll(delta); frame.current = requestAnimationFrame(loop); }; frame.current = requestAnimationFrame(loop); return false; } else { cancelAnimationFrame(frame.current); } return true; }; var stopAutoScroll = function stopAutoScroll() { leftBoundRef.current = Number.MIN_SAFE_INTEGER; rightBoundRef.current = Number.MAX_SAFE_INTEGER; speed.current = DEFAULT_SPEED; cancelAnimationFrame(frame.current); }; return { initAutoScroll: initAutoScroll, dealDragAutoScroll: dealDragAutoScroll, dealResizeAutoScroll: dealResizeAutoScroll, stopAutoScroll: stopAutoScroll }; } var InteractComp = function InteractComp(_ref) { var children = _ref.children, interactRef = _ref.interactRef, draggable = _ref.draggable, resizable = _ref.resizable, draggableOptions = _ref.draggableOptions, resizableOptions = _ref.resizableOptions; var nodeRef = useRef(); var interactable = useRef(); var draggableOptionsRef = useRef(); var resizableOptionsRef = useRef(); useEffect(function () { draggableOptionsRef.current = _objectSpread2({}, draggableOptions); resizableOptionsRef.current = _objectSpread2({}, resizableOptions); }, [draggableOptions, resizableOptions]); useEffect(function () { interactable.current && interactable.current.unset(); interactable.current = interact(nodeRef.current); interactRef.current = interactable.current; setInteractions(); }, [draggable, resizable]); var setInteractions = function setInteractions() { if (draggable) interactable.current.draggable(_objectSpread2(_objectSpread2({}, draggableOptionsRef.current), {}, { onstart: function onstart(e) { return draggableOptionsRef.current.onstart && draggableOptionsRef.current.onstart(e); }, onmove: function onmove(e) { return draggableOptionsRef.current.onmove && draggableOptionsRef.current.onmove(e); }, onend: function onend(e) { return draggableOptionsRef.current.onend && draggableOptionsRef.current.onend(e); } })); if (resizable) interactable.current.resizable(_objectSpread2(_objectSpread2({}, resizableOptionsRef.current), {}, { onstart: function onstart(e) { return resizableOptionsRef.current.onstart && resizableOptionsRef.current.onstart(e); }, onmove: function onmove(e) { return resizableOptionsRef.current.onmove && resizableOptionsRef.current.onmove(e); }, onend: function onend(e) { return resizableOptionsRef.current.onend && resizableOptionsRef.current.onend(e); } })); }; return /*#__PURE__*/cloneElement(children, { ref: nodeRef, draggable: false }); }; var RowDnd = /*#__PURE__*/React.forwardRef(function (_ref, ref) { var children = _ref.children, edges = _ref.edges, left = _ref.left, width = _ref.width, _ref$start = _ref.start, start = _ref$start === void 0 ? DEFAULT_START_LEFT : _ref$start, _ref$grid = _ref.grid, grid = _ref$grid === void 0 ? DEFAULT_MOVE_GRID : _ref$grid, _ref$bounds = _ref.bounds, bounds = _ref$bounds === void 0 ? { left: Number.MIN_SAFE_INTEGER, right: Number.MAX_SAFE_INTEGER } : _ref$bounds, _ref$enableResizing = _ref.enableResizing, enableResizing = _ref$enableResizing === void 0 ? true : _ref$enableResizing, _ref$enableDragging = _ref.enableDragging, enableDragging = _ref$enableDragging === void 0 ? true : _ref$enableDragging, _ref$adsorptionDistan = _ref.adsorptionDistance, adsorptionDistance = _ref$adsorptionDistan === void 0 ? DEFAULT_ADSORPTION_DISTANCE : _ref$adsorptionDistan, _ref$adsorptionPositi = _ref.adsorptionPositions, adsorptionPositions = _ref$adsorptionPositi === void 0 ? [] : _ref$adsorptionPositi, onResizeStart = _ref.onResizeStart, onResize = _ref.onResize, onResizeEnd = _ref.onResizeEnd, onDragStart = _ref.onDragStart, onDragEnd = _ref.onDragEnd, onDrag = _ref.onDrag, parentRef = _ref.parentRef, deltaScrollLeft = _ref.deltaScrollLeft; var interactable = useRef(); var deltaX = useRef(0); var isAdsorption = useRef(false); var _useAutoScroll = useAutoScroll(parentRef), initAutoScroll = _useAutoScroll.initAutoScroll, dealDragAutoScroll = _useAutoScroll.dealDragAutoScroll, dealResizeAutoScroll = _useAutoScroll.dealResizeAutoScroll, stopAutoScroll = _useAutoScroll.stopAutoScroll; useEffect(function () { return function () { interactable.current && interactable.current.unset(); }; }, []); //#region [rgba(100,120,156,0.08)] 赋值相关api useImperativeHandle(ref, function () { return { updateLeft: function updateLeft(left) { return handleUpdateLeft(left || 0, false); }, updateWidth: function updateWidth(width) { return handleUpdateWidth(width, false); }, getLeft: handleGetLeft, getWidth: handleGetWidth }; }); useEffect(function () { var target = interactable.current.target; handleUpdateWidth(typeof width === 'undefined' ? target.offsetWidth : width, false); }, [width]); useEffect(function () { handleUpdateLeft(left || 0, false); }, [left]); var handleUpdateLeft = function handleUpdateLeft(left) { var reset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; if (!interactable.current || !interactable.current.target) return; reset && (deltaX.current = 0); var target = interactable.current.target; target.style.left = "".concat(left, "px"); Object.assign(target.dataset, { left: left }); }; var handleUpdateWidth = function handleUpdateWidth(width) { var reset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; if (!interactable.current || !interactable.current.target) return; reset && (deltaX.current = 0); var target = interactable.current.target; target.style.width = "".concat(width, "px"); Object.assign(target.dataset, { width: width }); }; var handleGetLeft = function handleGetLeft() { var _target$dataset; var target = interactable.current.target; return parseFloat((target === null || target === void 0 ? void 0 : (_target$dataset = target.dataset) === null || _target$dataset === void 0 ? void 0 : _target$dataset.left) || '0'); }; var handleGetWidth = function handleGetWidth() { var _target$dataset2; var target = interactable.current.target; return parseFloat((target === null || target === void 0 ? void 0 : (_target$dataset2 = target.dataset) === null || _target$dataset2 === void 0 ? void 0 : _target$dataset2.width) || '0'); }; //#endregion //#region [rgba(188,188,120,0.05)] 回调api var handleMoveStart = function handleMoveStart(e) { deltaX.current = 0; isAdsorption.current = false; initAutoScroll(); onDragStart && onDragStart(); }; var move = function move(param) { var preLeft = param.preLeft, preWidth = param.preWidth, scrollDelta = param.scrollDelta; var distance = isAdsorption.current ? adsorptionDistance : grid; if (Math.abs(deltaX.current) >= distance) { var count = parseInt(deltaX.current / distance + ''); var curLeft = preLeft + count * distance; // 控制吸附 var adsorption = curLeft; var minDis = Number.MAX_SAFE_INTEGER; adsorptionPositions.forEach(function (item) { var dis = Math.abs(item - curLeft); if (dis < adsorptionDistance && dis < minDis) adsorption = item; var dis2 = Math.abs(item - (curLeft + preWidth)); if (dis2 < adsorptionDistance && dis2 < minDis) adsorption = item - preWidth; }); if (adsorption !== curLeft) { // 采用吸附数据 isAdsorption.current = true; curLeft = adsorption; } else { // 控制网格 if ((curLeft - start) % grid !== 0) { curLeft = start + grid * Math.round((curLeft - start) / grid); } isAdsorption.current = false; } deltaX.current = deltaX.current % distance; // 控制bounds if (curLeft < bounds.left) curLeft = bounds.left;else if (curLeft + preWidth > bounds.right) curLeft = bounds.right - preWidth; if (onDrag) { var ret = onDrag({ lastLeft: preLeft, left: curLeft, lastWidth: preWidth, width: preWidth }, scrollDelta); if (ret === false) return; } handleUpdateLeft(curLeft, false); } }; var handleMove = function handleMove(e) { var target = e.target; if (deltaScrollLeft && (parentRef === null || parentRef === void 0 ? void 0 : parentRef.current)) { var result = dealDragAutoScroll(e, function (delta) { deltaScrollLeft(delta); var _target$dataset3 = target.dataset, left = _target$dataset3.left, width = _target$dataset3.width; var preLeft = parseFloat(left); var preWidth = parseFloat(width); deltaX.current += delta; move({ preLeft: preLeft, preWidth: preWidth, scrollDelta: delta }); }); if (!result) return; } var _target$dataset4 = target.dataset, left = _target$dataset4.left, width = _target$dataset4.width; var preLeft = parseFloat(left); var preWidth = parseFloat(width); deltaX.current += e.dx; move({ preLeft: preLeft, preWidth: preWidth }); }; var handleMoveStop = function handleMoveStop(e) { deltaX.current = 0; isAdsorption.current = false; stopAutoScroll(); var target = e.target; var _target$dataset5 = target.dataset, left = _target$dataset5.left, width = _target$dataset5.width; onDragEnd && onDragEnd({ left: parseFloat(left), width: parseFloat(width) }); }; var handleResizeStart = function handleResizeStart(e) { var _e$edges; deltaX.current = 0; isAdsorption.current = false; initAutoScroll(); var dir = ((_e$edges = e.edges) === null || _e$edges === void 0 ? void 0 : _e$edges.right) ? 'right' : 'left'; onResizeStart && onResizeStart(dir); }; var resize = function resize(param) { var dir = param.dir, preWidth = param.preWidth, preLeft = param.preLeft; var distance = isAdsorption.current ? adsorptionDistance : grid; if (dir === 'left') { // 拖动左侧 if (Math.abs(deltaX.current) >= distance) { var count = parseInt(deltaX.current / distance + ''); var curLeft = preLeft + count * distance; // 控制吸附 var adsorption = curLeft; var minDis = Number.MAX_SAFE_INTEGER; adsorptionPositions.forEach(function (item) { var dis = Math.abs(item - curLeft); if (dis < adsorptionDistance && dis < minDis) adsorption = item; }); if (adsorption !== curLeft) { // 采用吸附数据 isAdsorption.current = true; curLeft = adsorption; } else { // 控制grid网格 if ((curLeft - start) % grid !== 0) { curLeft = start + grid * Math.round((curLeft - start) / grid); } isAdsorption.current = false; } deltaX.current = deltaX.current % distance; // 控制bounds var tempRight = preLeft + preWidth; if (curLeft < bounds.left) curLeft = bounds.left; var curWidth = tempRight - curLeft; if (onResize) { var ret = onResize('left', { lastLeft: preLeft, lastWidth: preWidth, left: curLeft, width: curWidth }); if (ret === false) return; } handleUpdateLeft(curLeft, false); handleUpdateWidth(curWidth, false); } } else if (dir === 'right') { // 拖动右侧 if (Math.abs(deltaX.current) >= distance) { var _count = parseInt(deltaX.current / grid + ''); var _curWidth = preWidth + _count * grid; // 控制吸附 var _adsorption = preLeft + _curWidth; var _minDis = Number.MAX_SAFE_INTEGER; adsorptionPositions.forEach(function (item) { var dis = Math.abs(item - (preLeft + _curWidth)); if (dis < adsorptionDistance && dis < _minDis) _adsorption = item; }); if (_adsorption !== preLeft + _curWidth) { // 采用吸附数据 isAdsorption.current = true; _curWidth = _adsorption - preLeft; } else { // 控制grid网格 var _tempRight = preLeft + _curWidth; if ((_tempRight - start) % grid !== 0) { _tempRight = start + grid * Math.round((_tempRight - start) / grid); _curWidth = _tempRight - preLeft; } isAdsorption.current = false; } deltaX.current = deltaX.current % distance; // 控制bounds if (preLeft + _curWidth > bounds.right) _curWidth = bounds.right - preLeft; if (onResize) { var _ret = onResize('right', { lastLeft: preLeft, lastWidth: preWidth, left: preLeft, width: _curWidth }); if (_ret === false) return; } handleUpdateWidth(_curWidth, false); } } }; var handleResize = function handleResize(e) { var _e$edges2; var target = e.target; var dir = ((_e$edges2 = e.edges) === null || _e$edges2 === void 0 ? void 0 : _e$edges2.left) ? 'left' : 'right'; if (deltaScrollLeft && (parentRef === null || parentRef === void 0 ? void 0 : parentRef.current)) { var result = dealResizeAutoScr