UNPKG

spiritjs

Version:

The animation toolkit for the web

325 lines (262 loc) 8.17 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _createClass = 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _events = require('events'); var _utils = require('../utils'); 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 _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** * Param * Containing property and value that can be changed over time * * @fires Param#change * @fires Param#change:prop * @fires Param#change:value * @fires List#change * @fires List#change:prop * @fires List#change:value */ var Param = function (_EventEmitter) { _inherits(Param, _EventEmitter); /** * Create Param. * @param {string} prop * @param {*} value */ function Param(prop, value) { _classCallCheck(this, Param); var _this = _possibleConstructorReturn(this, (Param.__proto__ || Object.getPrototypeOf(Param)).call(this)); _this._prop = null; _this._value = null; _this._list = null; _this.mappings = []; _this.setMaxListeners(Infinity); if (typeof prop === 'string' && value !== undefined) { Object.assign(_this, { _prop: prop, _value: value }); } return _this; } /** * Get current property * * @returns {string} */ _createClass(Param, [{ key: 'toObject', /** * Export param to a plain object * * @returns {object} */ value: function toObject() { return _defineProperty({}, this.prop, this.value); } /** * Check if this param is a CSS Transform * * @returns {boolean} */ }, { key: 'isCSSTransform', value: function isCSSTransform() { return ['x', 'y', 'z', 'rotateX', 'rotateY', 'rotateZ', 'skewX', 'skewY', 'scale', 'scaleX', 'scaleY'].includes(this.prop); } /** * Check if current param has an evaluable value * * @returns {boolean} */ }, { key: 'isEval', value: function isEval() { return (/\{(.*?)}/.test(this._value) ); } }, { key: 'prop', get: function get() { return this._prop; } /** * Set property * * @param {string} val * @fires Param#change * @fires Param#change:prop * @fires List#change * #fires List#change:prop */ , set: function set(val) { if (typeof val !== 'string') { throw new Error('Property needs to be a string'); } if (val === this._prop) { return; } /** * Event object. * * @type {object} * @property {object} prevModel - param before change * @property {object} model - param after change * @property {object} changed - {type, from, to} */ var evt = { prevModel: Param.fromObject(this.toObject()), model: Param.fromObject(_defineProperty({}, val, this.value)), changed: { type: 'prop', from: this._prop, to: val } }; // update property this._prop = val; /** * Param event. * * @event Param#change */ var evtChange = ['change', evt]; /** * Param event. * * @event Param#change:prop */ var evtChangeProp = ['change:prop', evt, val]; this.emit.apply(this, evtChange); this.emit.apply(this, evtChangeProp); if (this._list) { var _list, _list2; (_list = this._list).emit.apply(_list, evtChange); (_list2 = this._list).emit.apply(_list2, evtChangeProp); } } /** * Get current value. * * @returns {*} */ }, { key: 'value', get: function get() { var _this2 = this; if (this.isEval()) { // create available mappings for current value var mappings = this.mappings.reduce(function (result, mapping) { if (mapping.regex.global) { mapping.regex.lastIndex = 0; } if (mapping.regex.test(_this2._value)) { result[mapping.regex] = mapping; } return result; }, {}); // apply mappings var val = this._value; for (var mapping in mappings) { val = val.replace(mappings[mapping].regex, 'mappings[' + mapping + '].map'); } return eval(val); // eslint-disable-line no-eval } return this._value; } /** * Set current value * * @param {*} val * @fires Param#change * @fires Param#change:value * @fires List#change * @fires List#change:value */ , set: function set(val) { if (val === this._value) { return; } /** * Event object. * * @type {object} * @property {object} prevModel - param before change * @property {object} model - param after change * @property {object} changed - {type, from, to} */ var evt = { prevModel: Param.fromObject(this.toObject()), model: Param.fromObject(_defineProperty({}, this.prop, val)), changed: { type: 'value', from: this._value, to: val } }; // set value this._value = val; /** * Param event. * * @event Param#change */ var evtChange = ['change', evt]; /** * Param event. * * @event Param#change:value */ var evtChangeValue = ['change:value', evt, val]; this.emit.apply(this, evtChange); this.emit.apply(this, evtChangeValue); if (this._list) { var _list3, _list4; (_list3 = this._list).emit.apply(_list3, evtChange); (_list4 = this._list).emit.apply(_list4, evtChangeValue); } } /** * Get the list where this param is attached to * * @returns {List} */ }, { key: 'list', get: function get() { return this._list; } }]); return Param; }(_events.EventEmitter); /** * Parse Param from object * * @param {object} obj "{prop: value}" * @example {x: 120} * @returns {Param} */ Param.fromObject = function (obj) { if (!_utils.is.isObject(obj)) { throw new Error('Object is invalid.'); } var keys = Object.keys(obj); if (keys.length === 0 || keys.length > 1) { throw new Error('Object is invalid'); } var prop = keys[0]; var value = obj[prop]; if (value === null || value === undefined) { throw new Error('Object is invalid'); } return new Param(prop, value); }; Param.Events = ['change', 'change:prop', 'change:value']; exports.default = Param; module.exports = exports['default'];