UNPKG

es6-tween

Version:

ES6 implementation of amazing tween.js

1,770 lines (1,503 loc) 80.1 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (global = global || self, factory(global.TWEEN = {})); }(this, (function (exports) { 'use strict'; /* global global, self */ var root = typeof self !== 'undefined' ? self : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : this || (typeof exports !== 'undefined' ? exports : {}); var requestAnimationFrame = root.requestAnimationFrame || function (fn) { return root.setTimeout(fn, 50 / 3); }; var cancelAnimationFrame = root.cancelAnimationFrame || function (id) { return root.clearTimeout(id); }; /* global process */ /** * Get browser/Node.js current time-stamp * @return Normalised current time-stamp in milliseconds * @memberof TWEEN * @example * TWEEN.now */ var now = function () { if (typeof process !== 'undefined' && process.hrtime !== undefined && (!process.versions || process.versions.electron === undefined)) { return function () { var time = process.hrtime(); // Convert [seconds, nanoseconds] to milliseconds. return time[0] * 1000 + time[1] / 1000000; }; // In a browser, use window.performance.now if it is available. } else if (root.performance !== undefined && root.performance.now !== undefined) { // This must be bound, because directly assigning this function // leads to an invocation exception in Chrome. return root.performance.now.bind(root.performance); // Use Date.now if it is available. } else { var offset = root.performance && root.performance.timing && root.performance.timing.navigationStart ? root.performance.timing.navigationStart : Date.now(); return function () { return Date.now() - offset; }; } }(); /** * Lightweight, effecient and modular ES6 version of tween.js * @copyright 2019 @dalisoft and es6-tween contributors * @license MIT * @namespace TWEEN * @example * // ES6 * const {add, remove, isRunning, autoPlay} = TWEEN */ var _tweens = []; var isStarted = false; var _autoPlay = false; var _onRequestTick = []; var _ticker = requestAnimationFrame; var emptyFrame = 0; var powerModeThrottle = 120; var _tick; var handleLag = true; var onRequestTick = function onRequestTick(fn) { _onRequestTick.push(fn); }; var _requestTick = function _requestTick() { for (var i = 0; i < _onRequestTick.length; i++) { _onRequestTick[i](); } }; /** * Adds tween to list * @param {Tween} tween Tween instance * @memberof TWEEN * @example * let tween = new Tween({x:0}) * tween.to({x:200}, 1000) * TWEEN.add(tween) */ var add = function add(tween) { var i = _tweens.indexOf(tween); if (i > -1) { _tweens.splice(i, 1); } _tweens.push(tween); emptyFrame = 0; if (_autoPlay && !isStarted) { _tick = _ticker(update); isStarted = true; } }; /** * Adds ticker like event * @param {Function} fn callback * @memberof TWEEN * @example * TWEEN.onTick(time => console.log(time)) */ var onTick = function onTick(fn) { return _tweens.push({ update: fn }); }; /** * Sets after how much frames empty updating should stop * @param {number} frameCount=120 count of frames that should stop after all tweens removed * @memberof TWEEN * @example * TWEEN.FrameThrottle(60) */ var FrameThrottle = function FrameThrottle() { var frameCount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 120; powerModeThrottle = frameCount * 1.05; }; /** * Handle lag, useful if you have rendering Canvas or DOM objects or using es6-tween plugins * @param {number} state=true handle lag state * @memberof TWEEN * @example * TWEEN.ToggleLagSmoothing(false) */ var ToggleLagSmoothing = function ToggleLagSmoothing() { var _state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; handleLag = _state; }; /** * @returns {Array<Tween>} List of tweens in Array * @memberof TWEEN * TWEEN.getAll() // list of tweens */ var getAll = function getAll() { return _tweens; }; /** * Runs update loop automaticlly * @param {Boolean} state State of auto-run of update loop * @example TWEEN.autoPlay(true) * @memberof TWEEN */ var autoPlay = function autoPlay(state) { _autoPlay = state; }; /** * Removes all tweens from list * @example TWEEN.removeAll() // removes all tweens, stored in global tweens list * @memberof TWEEN */ var removeAll = function removeAll() { _tweens.length = 0; cancelAnimationFrame(_tick); isStarted = false; }; /** * @param {Tween} tween Tween Instance to be matched * @return {Tween} Matched tween * @memberof TWEEN * @example * TWEEN.get(tween) */ var get = function get(tween) { for (var i = 0; i < _tweens.length; i++) { if (tween === _tweens[i]) { return _tweens[i]; } } return null; }; /** * @param {Tween} tween Tween Instance to be matched * @return {Boolean} Status of Exists tween or not * @memberof TWEEN * @example * TWEEN.has(tween) */ var has = function has(tween) { return get(tween) !== null; }; /** * Removes tween from list * @param {Tween} tween Tween instance * @memberof TWEEN * @example * TWEEN.remove(tween) */ var remove = function remove(tween) { var i = _tweens.indexOf(tween); if (i !== -1) { _tweens.splice(i, 1); } if (_tweens.length === 0) { cancelAnimationFrame(_tick); isStarted = false; } }; /** * Updates global tweens by given time * @param {number=} time Timestamp * @param {Boolean=} preserve Prevents tween to be removed after finish * @memberof TWEEN * @example * TWEEN.update(500) */ var update = function update() { var time = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : now(); var preserve = arguments.length > 1 ? arguments[1] : undefined; if (emptyFrame >= powerModeThrottle && handleLag) { isStarted = false; emptyFrame = 0; cancelAnimationFrame(_tick); return false; } if (_autoPlay && isStarted) { _tick = _ticker(update); } else { _requestTick(); } if (!_tweens.length) { emptyFrame++; } var i = 0; var length = _tweens.length; while (i < length) { _tweens[i++].update(time, preserve); if (length > _tweens.length) { // The tween has been removed, keep same index i--; } length = _tweens.length; } return true; }; /** * The state of ticker running * @return {Boolean} Status of running updates on all tweens * @memberof TWEEN * @example TWEEN.isRunning() */ var isRunning = function isRunning() { return isStarted; }; /** * Returns state of lag smoothing handling * @return {Boolean} Status of lag smoothing state * @memberof TWEEN * @example TWEEN.isRunning() */ var isLagSmoothing = function isLagSmoothing() { return handleLag; }; /** * The plugins store object * @namespace TWEEN.Plugins * @memberof TWEEN * @example * let num = Plugins.num = function (node, start, end) { * return t => start + (end - start) * t * } * * @static */ var Plugins = {}; /** * List of full easings * @namespace TWEEN.Easing * @example * import {Tween, Easing} from 'es6-tween' * * // then set via new Tween({x:0}).to({x:100}, 1000).easing(Easing.Quadratic.InOut).start() */ var Easing = { Linear: { None: function None(k) { return k; } }, Quadratic: { In: function In(k) { return Math.pow(k, 2); }, Out: function Out(k) { return k * (2 - k); }, InOut: function InOut(k) { if ((k *= 2) < 1) { return 0.5 * Math.pow(k, 2); } return -0.5 * (--k * (k - 2) - 1); } }, Cubic: { In: function In(k) { return Math.pow(k, 3); }, Out: function Out(k) { return --k * k * k + 1; }, InOut: function InOut(k) { if ((k *= 2) < 1) { return 0.5 * Math.pow(k, 3); } return 0.5 * ((k -= 2) * k * k + 2); } }, Quartic: { In: function In(k) { return Math.pow(k, 4); }, Out: function Out(k) { return 1 - --k * k * k * k; }, InOut: function InOut(k) { if ((k *= 2) < 1) { return 0.5 * Math.pow(k, 4); } return -0.5 * ((k -= 2) * k * k * k - 2); } }, Quintic: { In: function In(k) { return Math.pow(k, 5); }, Out: function Out(k) { return --k * k * k * k * k + 1; }, InOut: function InOut(k) { if ((k *= 2) < 1) { return 0.5 * Math.pow(k, 5); } return 0.5 * ((k -= 2) * k * k * k * k + 2); } }, Sinusoidal: { In: function In(k) { return 1 - Math.cos(k * Math.PI / 2); }, Out: function Out(k) { return Math.sin(k * Math.PI / 2); }, InOut: function InOut(k) { return 0.5 * (1 - Math.cos(Math.PI * k)); } }, Exponential: { In: function In(k) { return k === 0 ? 0 : Math.pow(1024, k - 1); }, Out: function Out(k) { return k === 1 ? 1 : 1 - Math.pow(2, -10 * k); }, InOut: function InOut(k) { if (k === 0) { return 0; } if (k === 1) { return 1; } if ((k *= 2) < 1) { return 0.5 * Math.pow(1024, k - 1); } return 0.5 * (-Math.pow(2, -10 * (k - 1)) + 2); } }, Circular: { In: function In(k) { return 1 - Math.sqrt(1 - k * k); }, Out: function Out(k) { return Math.sqrt(1 - --k * k); }, InOut: function InOut(k) { if ((k *= 2) < 1) { return -0.5 * (Math.sqrt(1 - k * k) - 1); } return 0.5 * (Math.sqrt(1 - (k -= 2) * k) + 1); } }, Elastic: { In: function In(k) { if (k === 0) { return 0; } if (k === 1) { return 1; } return -Math.pow(2, 10 * (k - 1)) * Math.sin((k - 1.1) * 5 * Math.PI); }, Out: function Out(k) { if (k === 0) { return 0; } if (k === 1) { return 1; } return Math.pow(2, -10 * k) * Math.sin((k - 0.1) * 5 * Math.PI) + 1; }, InOut: function InOut(k) { if (k === 0) { return 0; } if (k === 1) { return 1; } k *= 2; if (k < 1) { return -0.5 * Math.pow(2, 10 * (k - 1)) * Math.sin((k - 1.1) * 5 * Math.PI); } return 0.5 * Math.pow(2, -10 * (k - 1)) * Math.sin((k - 1.1) * 5 * Math.PI) + 1; } }, Back: { In: function In(k) { var s = 1.70158; return k * k * ((s + 1) * k - s); }, Out: function Out(k) { var s = 1.70158; return --k * k * ((s + 1) * k + s) + 1; }, InOut: function InOut(k) { var s = 1.70158 * 1.525; if ((k *= 2) < 1) { return 0.5 * (k * k * ((s + 1) * k - s)); } return 0.5 * ((k -= 2) * k * ((s + 1) * k + s) + 2); } }, Bounce: { In: function In(k) { return 1 - Easing.Bounce.Out(1 - k); }, Out: function Out(k) { var x = 2.75; var y = 7.5625; if (k < 1 / x) { return y * k * k; } else if (k < 2 / x) { return y * (k -= 1.5 / x) * k + 0.75; } else if (k < 2.5 / x) { return y * (k -= 2.25 / x) * k + 0.9375; } else { return y * (k -= 2.625 / x) * k + 0.984375; } }, InOut: function InOut(k) { if (k < 0.5) { return Easing.Bounce.In(k * 2) * 0.5; } return Easing.Bounce.Out(k * 2 - 1) * 0.5 + 0.5; } }, Stepped: { steps: function steps(_steps) { return function (k) { return (k * _steps | 0) / _steps; }; } } }; function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function (obj) { return typeof obj; }; } else { _typeof = function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } 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); 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 ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (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 = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } 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 } }); if (superClass) _setPrototypeOf(subClass, superClass); } function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } 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; } return _assertThisInitialized(self); } function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } function _iterableToArrayLimit(arr, i) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_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 _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } // Frame lag-fix constants var FRAME_MS = 50 / 3; var TOO_LONG_FRAME_MS = 250; var CHAINED_TWEENS = '_chainedTweens'; // Event System var EVENT_CALLBACK = 'Callback'; var EVENT_UPDATE = 'update'; var EVENT_COMPLETE = 'complete'; var EVENT_START = 'start'; var EVENT_REPEAT = 'repeat'; var EVENT_REVERSE = 'reverse'; var EVENT_PAUSE = 'pause'; var EVENT_PLAY = 'play'; var EVENT_RESTART = 'restart'; var EVENT_STOP = 'stop'; var EVENT_SEEK = 'seek'; // For String tweening stuffs var STRING_PROP = 'STRING_PROP'; // Also RegExp's for string tweening var NUM_REGEX = /\s+|([A-Za-z?().,{}:""[\]#%]+)|([-+]=+)?([-+]+)?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]=?\d+)?/g; // Copies everything, duplicates, no shallow-copy function deepCopy(source) { if (source && source.nodeType || source === undefined || _typeof(source) !== 'object') { return source; } else if (Array.isArray(source)) { return [].concat(source); } else if (_typeof(source) === 'object') { var target = {}; for (var prop in source) { target[prop] = deepCopy(source[prop]); } return target; } return source; } var isNaNForST = function isNaNForST(v) { return isNaN(+v) || (v[0] === '+' || v[0] === '-') && v[1] === '=' || v === '' || v === ' '; }; var hexColor = /^#([0-9a-f]{6}|[0-9a-f]{3})$/gi; var hex2rgb = function hex2rgb(all, hex) { var r; var g; var b; if (hex.length === 3) { r = hex[0]; g = hex[1]; b = hex[2]; hex = r + r + g + g + b + b; } var color = parseInt(hex, 16); r = color >> 16 & 255; g = color >> 8 & 255; b = color & 255; return 'rgb(' + r + ', ' + g + ', ' + b + ')'; }; function decomposeString(fromValue) { if (fromValue && fromValue.splice && fromValue.isString) { return fromValue; } if (typeof fromValue !== 'string') { return fromValue; } if (fromValue.charAt(1) === '=') { return fromValue; } var value = fromValue.replace(hexColor, hex2rgb).match(NUM_REGEX).map(function (v) { return isNaNForST(v) ? v : +v; }); value.isString = true; return value; } // Decompose value, now for only `string` that required function decompose(prop, obj, from, to) { var fromValue = from[prop]; var toValue = to[prop]; if (fromValue === toValue) { return true; } else if (Array.isArray(fromValue) && Array.isArray(toValue) && fromValue.length === toValue.length) { for (var i = 0, len = toValue.length; i < len; i++) { var a = fromValue[i]; var b = toValue[i]; if (a === b || typeof a === 'number' && typeof b === 'number') { continue; } else { decompose(i, obj[prop], fromValue, toValue); } } } if (typeof fromValue === 'number' && typeof toValue === 'number') ; else if (fromValue && fromValue.splice && fromValue.isString && toValue && toValue.splice && toValue.isString) ; else if (typeof fromValue === 'string' && Array.isArray(toValue)) { var fromValue1 = decomposeString(fromValue); var toValues = toValue.map(decomposeString); from[prop] = fromValue1; to[prop] = toValues; return true; } else if (typeof fromValue === 'string' || typeof toValue === 'string') { var _fromValue = Array.isArray(fromValue) && fromValue[0] === STRING_PROP ? fromValue : decomposeString(fromValue); var toValue1 = Array.isArray(toValue) && toValue[0] === STRING_PROP ? toValue : decomposeString(toValue); if (_fromValue === undefined) { return; } var _i = 1; while (_i < _fromValue.length) { if (_fromValue[_i] === toValue1[_i] && typeof _fromValue[_i - 1] === 'string') { _fromValue.splice(_i - 1, 2, _fromValue[_i - 1] + _fromValue[_i]); toValue1.splice(_i - 1, 2, toValue1[_i - 1] + toValue1[_i]); } else { _i++; } } _i = 0; if (_fromValue[0] === STRING_PROP) { _fromValue.shift(); } if (toValue1[0] === STRING_PROP) { toValue1.shift(); } from[prop] = _fromValue; to[prop] = toValue1; return true; } else if (_typeof(fromValue) === 'object' && _typeof(toValue) === 'object') { if (Array.isArray(fromValue) && !fromValue.isString) { return fromValue.map(function (v, i) { return decompose(i, obj[prop], fromValue, toValue); }); } else { for (var prop2 in toValue) { decompose(prop2, obj[prop], fromValue, toValue); } } return true; } return false; } // Recompose value var RGB = 'rgb('; var RGBA = 'rgba('; var isRGBColor = function isRGBColor(v, i) { var r = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : RGB; return typeof v[i] === 'number' && (v[i - 1] === r || v[i - 3] === r || v[i - 5] === r); }; function recompose(prop, obj, from, to, t, originalT, stringBuffer) { var fromValue = stringBuffer ? from : from[prop]; var toValue = stringBuffer ? to : to[prop]; if (toValue === undefined) { return fromValue; } if (fromValue === undefined || typeof fromValue === 'string' || fromValue === toValue) { return toValue; } else if (_typeof(fromValue) === 'object' && _typeof(toValue) === 'object') { if (!fromValue || !toValue) { return obj[prop]; } if (_typeof(fromValue) === 'object' && !!fromValue && fromValue.isString && toValue && toValue.splice && toValue.isString) { var STRING_BUFFER = ''; for (var i = 0, len = fromValue.length; i < len; i++) { if (fromValue[i] !== toValue[i] || typeof fromValue[i] !== 'number' || typeof toValue[i] === 'number') { var isRelative = typeof fromValue[i] === 'number' && typeof toValue[i] === 'string' && toValue[i][1] === '='; var currentValue = typeof fromValue[i] !== 'number' ? fromValue[i] : isRelative ? fromValue[i] + parseFloat(toValue[i][0] + toValue[i].substr(2)) * t : fromValue[i] + (toValue[i] - fromValue[i]) * t; if (isRGBColor(fromValue, i) || isRGBColor(fromValue, i, RGBA)) { currentValue |= 0; } STRING_BUFFER += currentValue; if (isRelative && originalT === 1) { fromValue[i] = fromValue[i] + parseFloat(toValue[i][0] + toValue[i].substr(2)); } } else { STRING_BUFFER += fromValue[i]; } } if (!stringBuffer) { obj[prop] = STRING_BUFFER; } return STRING_BUFFER; } else if (Array.isArray(fromValue) && fromValue[0] !== STRING_PROP) { for (var _i2 = 0, _len = fromValue.length; _i2 < _len; _i2++) { if (fromValue[_i2] === toValue[_i2] || typeof obj[prop] === 'string') { continue; } recompose(_i2, obj[prop], fromValue, toValue, t, originalT); } } else if (_typeof(fromValue) === 'object' && !!fromValue && !fromValue.isString) { for (var _i3 in fromValue) { if (fromValue[_i3] === toValue[_i3]) { continue; } recompose(_i3, obj[prop], fromValue, toValue, t, originalT); } } } else if (typeof fromValue === 'number') { var _isRelative = typeof toValue === 'string'; obj[prop] = _isRelative ? fromValue + parseFloat(toValue[0] + toValue.substr(2)) * t : fromValue + (toValue - fromValue) * t; if (_isRelative && originalT === 1) { from[prop] = obj[prop]; } } else if (typeof toValue === 'function') { obj[prop] = toValue(t); } return obj[prop]; } // Dot notation => Object structure converter // example // {'scale.x.y.z':'VALUE'} => {scale:{x:{y:{z:'VALUE'}}}} // Only works for 3-level parsing, after 3-level, parsing dot-notation not works as it's not affects var propRegExp = /([.[])/g; var replaceBrace = /\]/g; var propExtract = function propExtract(obj, property) { var value = obj[property]; var props = property.replace(replaceBrace, '').split(propRegExp); var propsLastIndex = props.length - 1; var lastArr = Array.isArray(obj); var lastObj = _typeof(obj) === 'object' && !lastArr; if (lastObj) { obj[property] = null; delete obj[property]; } else if (lastArr) { obj.splice(property, 1); } return props.reduce(function (nested, prop, index) { if (lastArr) { if (prop !== '.' && prop !== '[') { prop *= 1; } } var nextProp = props[index + 1]; var nextIsArray = nextProp === '['; if (prop === '.' || prop === '[') { if (prop === '.') { lastObj = true; lastArr = false; } else if (prop === '[') { lastObj = false; lastArr = true; } return nested; } else if (nested[prop] === undefined) { if (lastArr || lastObj) { nested[prop] = index === propsLastIndex ? value : lastArr || nextIsArray ? [] : lastObj ? {} : null; lastObj = lastArr = false; return nested[prop]; } } else if (nested[prop] !== undefined) { if (index === propsLastIndex) { nested[prop] = value; } return nested[prop]; } return nested; }, obj); }; var SET_NESTED = function SET_NESTED(nested) { if (_typeof(nested) === 'object' && !!nested) { for (var prop in nested) { if (prop.indexOf('.') !== -1 || prop.indexOf('[') !== -1) { propExtract(nested, prop); } else if (_typeof(nested[prop]) === 'object' && !!nested[prop]) { var nested2 = nested[prop]; for (var prop2 in nested2) { if (prop2.indexOf('.') !== -1 || prop2.indexOf('[') !== -1) { propExtract(nested2, prop2); } else if (_typeof(nested2[prop2]) === 'object' && !!nested2[prop2]) { var nested3 = nested2[prop2]; for (var prop3 in nested3) { if (prop3.indexOf('.') !== -1 || prop3.indexOf('[') !== -1) { propExtract(nested3, prop3); } } } } } } } return nested; }; var constants = /*#__PURE__*/Object.freeze({ __proto__: null, FRAME_MS: FRAME_MS, TOO_LONG_FRAME_MS: TOO_LONG_FRAME_MS, CHAINED_TWEENS: CHAINED_TWEENS, EVENT_CALLBACK: EVENT_CALLBACK, EVENT_UPDATE: EVENT_UPDATE, EVENT_COMPLETE: EVENT_COMPLETE, EVENT_START: EVENT_START, EVENT_REPEAT: EVENT_REPEAT, EVENT_REVERSE: EVENT_REVERSE, EVENT_PAUSE: EVENT_PAUSE, EVENT_PLAY: EVENT_PLAY, EVENT_RESTART: EVENT_RESTART, EVENT_STOP: EVENT_STOP, EVENT_SEEK: EVENT_SEEK, STRING_PROP: STRING_PROP, NUM_REGEX: NUM_REGEX, deepCopy: deepCopy, decomposeString: decomposeString, decompose: decompose, RGB: RGB, RGBA: RGBA, isRGBColor: isRGBColor, recompose: recompose, SET_NESTED: SET_NESTED }); /** * List of full Interpolation * @namespace TWEEN.Interpolation * @example * import {Interpolation, Tween} from 'es6-tween' * * let bezier = Interpolation.Bezier * new Tween({x:0}).to({x:[0, 4, 8, 12, 15, 20, 30, 40, 20, 40, 10, 50]}, 1000).interpolation(bezier).start() * @memberof TWEEN */ var Interpolation = { Linear: function Linear(v, k, value) { var m = v.length - 1; var f = m * k; var i = Math.floor(f); var fn = Interpolation.Utils.Linear; if (k < 0) { return fn(v[0], v[1], f, value); } if (k > 1) { return fn(v[m], v[m - 1], m - f, value); } return fn(v[i], v[i + 1 > m ? m : i + 1], f - i, value); }, Bezier: function Bezier(v, k, value) { var b = Interpolation.Utils.Reset(value); var n = v.length - 1; var pw = Math.pow; var fn = Interpolation.Utils.Bernstein; var isBArray = Array.isArray(b); for (var i = 0; i <= n; i++) { if (typeof b === 'number') { b += pw(1 - k, n - i) * pw(k, i) * v[i] * fn(n, i); } else if (isBArray) { for (var p = 0, len = b.length; p < len; p++) { if (typeof b[p] === 'number') { b[p] += pw(1 - k, n - i) * pw(k, i) * v[i][p] * fn(n, i); } else { b[p] = v[i][p]; } } } else if (_typeof(b) === 'object') { for (var _p in b) { if (typeof b[_p] === 'number') { b[_p] += pw(1 - k, n - i) * pw(k, i) * v[i][_p] * fn(n, i); } else { b[_p] = v[i][_p]; } } } else if (typeof b === 'string') { var STRING_BUFFER = ''; var idx = Math.round(n * k); var vCurr = v[idx]; for (var ks = 1, _len = vCurr.length; ks < _len; ks++) { STRING_BUFFER += vCurr[ks]; } return STRING_BUFFER; } } return b; }, CatmullRom: function CatmullRom(v, k, value) { var m = v.length - 1; var f = m * k; var i = Math.floor(f); var fn = Interpolation.Utils.CatmullRom; if (v[0] === v[m]) { if (k < 0) { i = Math.floor(f = m * (1 + k)); } return fn(v[(i - 1 + m) % m], v[i], v[(i + 1) % m], v[(i + 2) % m], f - i, value); } else { if (k < 0) { return fn(v[1], v[1], v[0], v[0], -k, value); } if (k > 1) { return fn(v[m - 1], v[m - 1], v[m], v[m], (k | 0) - k, value); } return fn(v[i ? i - 1 : 0], v[i], v[m < i + 1 ? m : i + 1], v[m < i + 2 ? m : i + 2], f - i, value); } }, Utils: { Linear: function Linear(p0, p1, t, v) { if (p0 === p1 || typeof p0 === 'string') { // Quick return for performance reason if (p1.length && p1.splice && p1.isString) { p1 = ''; for (var i = 0, len = p0.length; i < len; i++) { p1 += p0[i]; } } return p1; } else if (typeof p0 === 'number') { return typeof p0 === 'function' ? p0(t) : p0 + (p1 - p0) * t; } else if (_typeof(p0) === 'object') { if (p0.length !== undefined) { var isForceStringProp = typeof p0[0] === 'string' || p0.isString; if (isForceStringProp || p0[0] === STRING_PROP) { var STRING_BUFFER = ''; for (var _i = isForceStringProp ? 0 : 1, _len2 = p0.length; _i < _len2; _i++) { var currentValue = t === 0 ? p0[_i] : t === 1 ? p1[_i] : typeof p0[_i] === 'number' ? p0[_i] + (p1[_i] - p0[_i]) * t : p1[_i]; if (t > 0 && t < 1 && isRGBColor(p0, _i) || isRGBColor(p0, _i, RGBA)) { currentValue |= 0; } STRING_BUFFER += currentValue; } return STRING_BUFFER; } else if (v && v.length && v.splice) { for (var p = 0, _len3 = v.length; p < _len3; p++) { v[p] = Interpolation.Utils.Linear(p0[p], p1[p], t, v[p]); } } } else { for (var _p2 in v) { v[_p2] = Interpolation.Utils.Linear(p0[_p2], p1[_p2], t, v[_p2]); } } return v; } }, Reset: function Reset(value) { if (Array.isArray(value)) { for (var i = 0, len = value.length; i < len; i++) { value[i] = Interpolation.Utils.Reset(value[i]); } return value; } else if (_typeof(value) === 'object') { for (var _i2 in value) { value[_i2] = Interpolation.Utils.Reset(value[_i2]); } return value; } else if (typeof value === 'number') { return 0; } return value; }, Bernstein: function Bernstein(n, i) { var fc = Interpolation.Utils.Factorial; return fc(n) / fc(i) / fc(n - i); }, Factorial: function () { var a = [1]; return function (n) { var s = 1; if (a[n]) { return a[n]; } for (var i = n; i > 1; i--) { s *= i; } a[n] = s; return s; }; }(), CatmullRom: function CatmullRom(p0, p1, p2, p3, t, v) { if (typeof p0 === 'string') { return p1; } else if (typeof p0 === 'number') { var v0 = (p2 - p0) * 0.5; var v1 = (p3 - p1) * 0.5; var t2 = t * t; var t3 = t * t2; return (2 * p1 - 2 * p2 + v0 + v1) * t3 + (-3 * p1 + 3 * p2 - 2 * v0 - v1) * t2 + v0 * t + p1; } else if (_typeof(p0) === 'object') { if (p0.length !== undefined) { if (p0[0] === STRING_PROP) { var STRING_BUFFER = ''; for (var i = 1, len = p0.length; i < len; i++) { var currentValue = typeof p0[i] === 'number' ? Interpolation.Utils.CatmullRom(p0[i], p1[i], p2[i], p3[i], t) : p3[i]; if (isRGBColor(p0, i) || isRGBColor(p0, i, RGBA)) { currentValue |= 0; } STRING_BUFFER += currentValue; } return STRING_BUFFER; } for (var p = 0, _len4 = v.length; p < _len4; p++) { v[p] = Interpolation.Utils.CatmullRom(p0[p], p1[p], p2[p], p3[p], t, v[p]); } } else { for (var _p3 in v) { v[_p3] = Interpolation.Utils.CatmullRom(p0[_p3], p1[_p3], p2[_p3], p3[_p3], t, v[_p3]); } } return v; } } } }; var Store = {}; function NodeCache (node, object, tween) { if (!node || !node.nodeType) { return object; } var ID = node.queueID || 'q_' + Date.now(); if (!node.queueID) { node.queueID = ID; } var storeID = Store[ID]; if (storeID) { if (storeID.object === object && node === storeID.tween.node && tween._startTime === storeID.tween._startTime) { remove(storeID.tween); } else if (_typeof(object) === 'object' && !!object && !!storeID.object) { for (var prop in object) { if (prop in storeID.object) { if (tween._startTime === storeID.tween._startTime) { delete storeID.object[prop]; } else { storeID.propNormaliseRequired = true; } } } Object.assign(storeID.object, object); } return storeID.object; } if (_typeof(object) === 'object' && !!object) { Store[ID] = { tween: tween, object: object, propNormaliseRequired: false }; return Store[ID].object; } return object; } function Selector (selector, collection, allowRaw) { if (collection) { return !selector ? null : typeof window !== 'undefined' && selector === window || typeof document !== 'undefined' && selector === document ? [selector] : typeof selector === 'string' ? !!document.querySelectorAll && document.querySelectorAll(selector) : Array.isArray(selector) ? selector : selector.nodeType ? [selector] : allowRaw ? selector : []; } return !selector ? null : typeof window !== 'undefined' && selector === window || typeof document !== 'undefined' && selector === document ? selector : typeof selector === 'string' ? !!document.querySelector && document.querySelector(selector) : Array.isArray(selector) ? selector[0] : selector.nodeType ? selector : allowRaw ? selector : null; } var _id = 0; // Unique ID var defaultEasing = Easing.Linear.None; /** * Tween main constructor * @constructor * @class * @namespace TWEEN.Tween * @param {Object|Element} node Node Element or Tween initial object * @param {Object=} object If Node Element is using, second argument is used for Tween initial object * @example let tween = new Tween(myNode, {width:'100px'}).to({width:'300px'}, 2000).start() */ var Tween = /*#__PURE__*/function () { _createClass(Tween, null, [{ key: "fromTo", /** * Easier way to call the Tween * @param {Element} node DOM Element * @param {object} object - Initial value * @param {object} to - Target value * @param {object} params - Options of tweens * @example Tween.fromTo(node, {x:0}, {x:200}, {duration:1000}) * @memberof TWEEN.Tween * @static */ value: function fromTo(node, object, to) { var params = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; params.quickRender = params.quickRender ? params.quickRender : !to; var tween = new Tween(node, object).to(to, params); if (params.quickRender) { tween.render().update(tween._startTime); tween._rendered = false; tween._onStartCallbackFired = false; } return tween; } /** * Easier way calling constructor only applies the `to` value, useful for CSS Animation * @param {Element} node DOM Element * @param {object} to - Target value * @param {object} params - Options of tweens * @example Tween.to(node, {x:200}, {duration:1000}) * @memberof TWEEN.Tween * @static */ }, { key: "to", value: function to(node, _to, params) { return Tween.fromTo(node, null, _to, params); } /** * Easier way calling constructor only applies the `from` value, useful for CSS Animation * @param {Element} node DOM Element * @param {object} from - Initial value * @param {object} params - Options of tweens * @example Tween.from(node, {x:200}, {duration:1000}) * @memberof TWEEN.Tween * @static */ }, { key: "from", value: function from(node, _from, params) { return Tween.fromTo(node, _from, null, params); } }]); function Tween(node, object) { _classCallCheck(this, Tween); this.id = _id++; if (!!node && _typeof(node) === 'object' && !object && !node.nodeType) { object = this.object = node; node = null; } else if (!!node && (node.nodeType || node.length || typeof node === 'string')) { node = this.node = Selector(node); object = this.object = NodeCache(node, object, this); } this._valuesEnd = null; this._valuesStart = Array.isArray(object) ? [] : {}; this._duration = 1000; this._easingFunction = defaultEasing; this._easingReverse = defaultEasing; this._interpolationFunction = Interpolation.Linear; this._startTime = 0; this._initTime = 0; this._delayTime = 0; this._repeat = 0; this._r = 0; this._isPlaying = false; this._yoyo = false; this._reversed = false; this._onStartCallbackFired = false; this._pausedTime = null; this._isFinite = true; this._maxListener = 15; this._chainedTweensCount = 0; this._prevTime = null; return this; } /** * Sets max `event` listener's count to Events system * @param {number} count - Event listener's count * @memberof TWEEN.Tween */ _createClass(Tween, [{ key: "setMaxListener", value: function setMaxListener() { var count = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 15; this._maxListener = count; return this; } /** * Adds `event` to Events system * @param {string} event - Event listener name * @param {Function} callback - Event listener callback * @memberof TWEEN.Tween */ }, { key: "on", value: function on(event, callback) { var _maxListener = this._maxListener; var callbackName = event + EVENT_CALLBACK; for (var i = 0; i < _maxListener; i++) { var callbackId = callbackName + i; if (!this[callbackId]) { this[callbackId] = callback; break; } } return this; } /** * Adds `event` to Events system. * Removes itself after fired once * @param {string} event - Event listener name * @param {Function} callback - Event listener callback * @memberof TWEEN.Tween */ }, { key: "once", value: function once(event, callback) { var _this = this; var _maxListener = this._maxListener; var callbackName = event + EVENT_CALLBACK; var _loop = function _loop(i) { var callbackId = callbackName + i; if (!_this[callbackId]) { _this[callbackId] = function () { for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } callback.apply(_this, args); _this[callbackId] = null; }; return "break"; } }; for (var i = 0; i < _maxListener; i++) { var _ret = _loop(i); if (_ret === "break") break; } return this; } /** * Removes `event` from Events system * @param {string} event - Event listener name * @param {Function} callback - Event listener callback * @memberof TWEEN.Tween */ }, { key: "off", value: function off(event, callback) { var _maxListener = this._maxListener; var callbackName = event + EVENT_CALLBACK; for (var i = 0; i < _maxListener; i++) { var callbackId = callbackName + i; if (this[callbackId] === callback) { this[callbackId] = null; } } return this; } /** * Emits/Fired/Trigger `event` from Events system listeners * @param {string} event - Event listener name * @memberof TWEEN.Tween */ }, { key: "emit", value: function emit(event, arg1, arg2, arg3) { var _maxListener = this._maxListener; var callbackName = event + EVENT_CALLBACK; if (!this[callbackName + 0]) { return this; } for (var i = 0; i < _maxListener; i++) { var callbackId = callbackName + i; if (this[callbackId]) { this[callbackId](arg1, arg2, arg3); } } return this; } /** * @return {boolean} State of playing of tween * @example tween.isPlaying() // returns `true` if tween in progress * @memberof TWEEN.Tween */ }, { key: "isPlaying", value: function isPlaying() { return this._isPlaying; } /** * @return {boolean} State of started of tween * @example tween.isStarted() // returns `true` if tween in started * @memberof TWEEN.Tween */ }, { key: "isStarted", value: function isStarted() { return this._onStartCallbackFired; } /** * Reverses the tween state/direction * @example tween.reverse() * @param {boolean=} state Set state of current reverse * @memberof TWEEN.Tween */ }, { key: "reverse", value: function reverse(state) { var _reversed = this._reversed; this._reversed = state !== undefined ? state : !_reversed; return this; } /** * @return {boolean} State of reversed * @example tween.reversed() // returns `true` if tween in reversed state * @memberof TWEEN.Tween */ }, { key: "reversed", value: function reversed() { return this._reversed; } /** * Pauses tween * @example tween.pause() * @memberof TWEEN.Tween */ }, { key: "pause", value: function pause() { if (!this._isPlaying) { return this; } this._isPlaying = false; remove(this); this._pausedTime = now(); return this.emit(EVENT_PAUSE, this.object); } /** * Play/Resume the tween * @example tween.play() * @memberof TWEEN.Tween */ }, { key: "play", value: function play() { if (this._isPlaying) { return this; } this._isPlaying = true; this._startTime += now() - this._pausedTime; this._initTime = this._startTime; add(this); this._pausedTime = now(); return this.emit(EVENT_PLAY, this.object); } /** * Restarts tween from initial value * @param {boolean=} noDelay If this param is set to `true`, restarts tween without `delay` * @example tween.restart() * @memberof TWEEN.Tween */ }, { key: "restart", value: function restart(noDelay) { this._repeat = this._r; this.reassignValues(); add(this); return this.emit(EVENT_RESTART, this.object); } /** * Seek tween value by `time`. Note: Not works as excepted. PR are welcome * @param {Time} time Tween update time * @param {boolean=} keepPlaying When this param is set to `false`, tween pausing after seek * @example tween.seek(500) * @memberof TWEEN.Tween * @deprecated Not works as excepted, so we deprecated this method */ }, { key: "seek", value: function seek(time, keepPlaying) { var _duration = this._duration, _initTime = this._initTime, _startTime = this._startTime, _reversed = this._reversed; var updateTime = _initTime + time; this._isPlaying = true; if (updateTime < _startTime && _startTime >= _initTime) { this._startTime -= _duration; this._reversed = !_reversed; } this.update(time, false); this.emit(EVENT_SEEK, time, this.object); return keepPlaying ? this : this.pause(); } /** * Sets tween duration * @param {number} amount Duration is milliseconds * @example tween.duration(2000) * @memberof TWEEN.Tween * @deprecated Not works as excepted and useless, so we deprecated this method */ }, { key: "duration", value: function duration(amount) { this._duration = typeof amount === 'function' ? amount(this._duration) : amount; return this; } /** * Sets target value and duration * @param {object} properties Target value (to value) * @param {number|Object=} [duration=1000] Duration of tween * @example let tween = new Tween({x:0}).to({x:100}, 2000) * @memberof TWEEN.Tween */ }, { key: "to", value: function to(properties) { var duration = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1000; this._valuesEnd = properties; if (typeof duration === 'number' || typeof duration === 'function') { this._duration = typeof duration === 'function' ? duration(this._duration) : duration; } else if (_typeof(duration) === 'object') { for (var prop in duration) { if (typeof this[prop] === 'function') { var _ref = Array.isArray(duration[prop]) ? duration[prop] : [duration[prop]], _ref2 = _slicedToArray(_ref, 4), _ref2$ = _ref2[0], arg1 = _ref2$ === void 0 ? null : _ref2$, _ref2$2 = _ref2[1], arg2 = _ref2$2 === void 0 ? null : _ref2$2, _ref2$3 = _ref2[2], arg3 = _ref2$3 === void 0 ? null : _ref2$3, _ref2$4 = _ref2[3], arg4 = _ref2$4 === void 0 ? null : _ref2$4; this[prop](arg1, arg2, arg3, arg4); } } } return this; } /** * Renders and computes value at first render * @private * @memberof TWEEN.Tween */ }, { key: "render", value: function render() { if (this._rendered) { return this; } var _valuesStart = this._valuesStart, _valuesEnd = this._valuesEnd, object = this.object, node = this.node, InitialValues = this.InitialValues; SET_NESTED(object); SET_NESTED(_valuesEnd); if (node && node.queue