"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.transition = transition; exports.injectNewCurve = injectNewCurve; exports["default"] = void 0; var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof")); var _curves = _interopRequireDefault(require("./config/curves")); var defaultTransitionBC = 'linear'; /** * @description Get the N-frame animation state by the start and end state * of the animation and the easing curve * @param {String|Array} tBC Easing curve name or data * @param {Number|Array|Object} startState Animation start state * @param {Number|Array|Object} endState Animation end state * @param {Number} frameNum Number of Animation frames * @param {Boolean} deep Whether to use recursive mode * @return {Array|Boolean} State of each frame of the animation (Invalid input will return false) */ function transition(tBC) { var startState = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; var endState = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; var frameNum = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 30; var deep = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false; if (!checkParams.apply(void 0, arguments)) return false; try { // Get the transition bezier curve var bezierCurve = getBezierCurve(tBC); // Get the progress of each frame state var frameStateProgress = getFrameStateProgress(bezierCurve, frameNum); // If the recursion mode is not enabled or the state type is Number, the shallow state calculation is performed directly. if (!deep || typeof endState === 'number') return getTransitionState(startState, endState, frameStateProgress); return recursionTransitionState(startState, endState, frameStateProgress); } catch (_unused) { console.warn('Transition parameter may be abnormal!'); return [endState]; } } /** * @description Check if the parameters are legal * @param {String} tBC Name of transition bezier curve * @param {Any} startState Transition start state * @param {Any} endState Transition end state * @param {Number} frameNum Number of transition frames * @return {Boolean} Is the parameter legal */ function checkParams(tBC) { var startState = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; var endState = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; var frameNum = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 30; if (!tBC || startState === false || endState === false || !frameNum) { console.error('transition: Missing Parameters!'); return false; } if ((0, _typeof2["default"])(startState) !== (0, _typeof2["default"])(endState)) { console.error('transition: Inconsistent Status Types!'); return false; } var stateType = (0, _typeof2["default"])(endState); if (stateType === 'string' || stateType === 'boolean' || !tBC.length) { console.error('transition: Unsupported Data Type of State!'); return false; } if (!_curves["default"].has(tBC) && !(tBC instanceof Array)) { console.warn('transition: Transition curve not found, default curve will be used!'); } return true; } /** * @description Get the transition bezier curve * @param {String} tBC Name of transition bezier curve * @return {Array} Bezier curve data */ function getBezierCurve(tBC) { var bezierCurve = ''; if (_curves["default"].has(tBC)) { bezierCurve = _curves["default"].get(tBC); } else if (tBC instanceof Array) { bezierCurve = tBC; } else { bezierCurve = _curves["default"].get(defaultTransitionBC); } return bezierCurve; } /** * @description Get the progress of each frame state * @param {Array} bezierCurve Transition bezier curve * @param {Number} frameNum Number of transition frames * @return {Array} Progress of each frame state */ function getFrameStateProgress(bezierCurve, frameNum) { var tMinus = 1 / (frameNum - 1); var tState = new Array(frameNum).fill(0).map(function (t, i) { return i * tMinus; }); var frameState = tState.map(function (t) { return getFrameStateFromT(bezierCurve, t); }); return frameState; } /** * @description Get the progress of the corresponding frame according to t * @param {Array} bezierCurve Transition bezier curve * @param {Number} t Current frame t * @return {Number} Progress of current frame */ function getFrameStateFromT(bezierCurve, t) { var tBezierCurvePoint = getBezierCurvePointFromT(bezierCurve, t); var bezierCurvePointT = getBezierCurvePointTFromReT(tBezierCurvePoint, t); return getBezierCurveTState(tBezierCurvePoint, bezierCurvePointT); } /** * @description Get the corresponding sub-curve according to t * @param {Array} bezierCurve Transition bezier curve * @param {Number} t Current frame t * @return {Array} Sub-curve of t */ function getBezierCurvePointFromT(bezierCurve, t) { var lastIndex = bezierCurve.length - 1; var begin = '', end = ''; bezierCurve.findIndex(function (item, i) { if (i === lastIndex) return; begin = item; end = bezierCurve[i + 1]; var currentMainPointX = begin[0][0]; var nextMainPointX = end[0][0]; return t >= currentMainPointX && t < nextMainPointX; }); var p0 = begin[0]; var p1 = begin[2] || begin[0]; var p2 = end[1] || end[0]; var p3 = end[0]; return [p0, p1, p2, p3]; } /** * @description Get local t based on t and sub-curve * @param {Array} bezierCurve Sub-curve * @param {Number} t Current frame t * @return {Number} local t of sub-curve */ function getBezierCurvePointTFromReT(bezierCurve, t) { var reBeginX = bezierCurve[0][0]; var reEndX = bezierCurve[3][0]; var xMinus = reEndX - reBeginX; var tMinus = t - reBeginX; return tMinus / xMinus; } /** * @description Get the curve progress of t * @param {Array} bezierCurve Sub-curve * @param {Number} t Current frame t * @return {Number} Progress of current frame */ function getBezierCurveTState(_ref, t) { var _ref2 = (0, _slicedToArray2["default"])(_ref, 4), _ref2$ = (0, _slicedToArray2["default"])(_ref2[0], 2), p0 = _ref2$[1], _ref2$2 = (0, _slicedToArray2["default"])(_ref2[1], 2), p1 = _ref2$2[1], _ref2$3 = (0, _slicedToArray2["default"])(_ref2[2], 2), p2 = _ref2$3[1], _ref2$4 = (0, _slicedToArray2["default"])(_ref2[3], 2), p3 = _ref2$4[1]; var pow = Math.pow; var tMinus = 1 - t; var result1 = p0 * pow(tMinus, 3); var result2 = 3 * p1 * t * pow(tMinus, 2); var result3 = 3 * p2 * pow(t, 2) * tMinus; var result4 = p3 * pow(t, 3); return 1 - (result1 + result2 + result3 + result4); } /** * @description Get transition state according to frame progress * @param {Any} startState Transition start state * @param {Any} endState Transition end state * @param {Array} frameState Frame state progress * @return {Array} Transition frame state */ function getTransitionState(begin, end, frameState) { var stateType = 'object'; if (typeof begin === 'number') stateType = 'number'; if (begin instanceof Array) stateType = 'array'; if (stateType === 'number') return getNumberTransitionState(begin, end, frameState); if (stateType === 'array') return getArrayTransitionState(begin, end, frameState); if (stateType === 'object') return getObjectTransitionState(begin, end, frameState); return frameState.map(function (t) { return end; }); } /** * @description Get the transition data of the number type * @param {Number} startState Transition start state * @param {Number} endState Transition end state * @param {Array} frameState Frame state progress * @return {Array} Transition frame state */ function getNumberTransitionState(begin, end, frameState) { var minus = end - begin; return frameState.map(function (s) { return begin + minus * s; }); } /** * @description Get the transition data of the array type * @param {Array} startState Transition start state * @param {Array} endState Transition end state * @param {Array} frameState Frame state progress * @return {Array} Transition frame state */ function getArrayTransitionState(begin, end, frameState) { var minus = end.map(function (v, i) { if (typeof v !== 'number') return false; return v - begin[i]; }); return frameState.map(function (s) { return minus.map(function (v, i) { if (v === false) return end[i]; return begin[i] + v * s; }); }); } /** * @description Get the transition data of the object type * @param {Object} startState Transition start state * @param {Object} endState Transition end state * @param {Array} frameState Frame state progress * @return {Array} Transition frame state */ function getObjectTransitionState(begin, end, frameState) { var keys = Object.keys(end); var beginValue = keys.map(function (k) { return begin[k]; }); var endValue = keys.map(function (k) { return end[k]; }); var arrayState = getArrayTransitionState(beginValue, endValue, frameState); return arrayState.map(function (item) { var frameData = {}; item.forEach(function (v, i) { return frameData[keys[i]] = v; }); return frameData; }); } /** * @description Get the transition state data by recursion * @param {Array|Object} startState Transition start state * @param {Array|Object} endState Transition end state * @param {Array} frameState Frame state progress * @return {Array} Transition frame state */ function recursionTransitionState(begin, end, frameState) { var state = getTransitionState(begin, end, frameState); var _loop = function _loop(key) { var bTemp = begin[key]; var eTemp = end[key]; if ((0, _typeof2["default"])(eTemp) !== 'object') return "continue"; var data = recursionTransitionState(bTemp, eTemp, frameState); state.forEach(function (fs, i) { return fs[key] = data[i]; }); }; for (var key in end) { var _ret = _loop(key); if (_ret === "continue") continue; } return state; } /** * @description Inject new curve into curves as config * @param {Any} key The key of curve * @param {Array} curve Bezier curve data * @return {Undefined} No return */ function injectNewCurve(key, curve) { if (!key || !curve) { console.error('InjectNewCurve Missing Parameters!'); return; } _curves["default"].set(key, curve); } var _default = transition; exports["default"] = _default;