wilderness-core
Version:
The SVG animation engine behind Wilderness
437 lines (367 loc) • 12 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.valid = undefined;
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; /* globals __DEV__ */
var _frame = require('./frame');
var _frame2 = _interopRequireDefault(_frame);
var _svgPoints = require('svg-points');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _toArray(arr) { return Array.isArray(arr) ? arr : Array.from(arr); }
/**
* An SVG shape as defined by https://github.com/colinmeinke/svg-points.
*
* @typedef {Object} PlainShapeObjectCoreProps
*/
/**
* Additional options specifically for a motion path.
*
* @typedef {Object} PlainShapeObjectMotionPathProps
*
* @property {number} accuracy - .
* @property {boolean|number} rotate - .
*/
/**
* The tween options to use when transitioning from a previous shape.
*
* @typedef {Object} PlainShapeObjectTweenProps
*
* @property {number} delay - Milliseconds before the tween starts.
* @property {number} duration - Milliseconds until tween finishes.
* @property {string|function} easing - The name of an easing function, or an easing function.
*/
/**
* A static shape.
*
* @typedef {Object} PlainShapeObject
*
* @extends PlainShapeObjectCoreProps
* @extends PlainShapeObjectMotionPathProps
* @extends PlainShapeObjectTweenProps
* @property {string|number} name
*/
/**
* Validates PlainShapeObjectCoreProps.
*
* @param {PlainShapeObject[]} plainShapeObjects
*
* @throws {TypeError} Throws if not valid
*
* @returns {true}
*
* @example
* if (corePropsValid([ circle ])) {
* console.log('circle has valid Plain Shape Object Core Props')
* }
*/
var corePropsValid = function corePropsValid(plainShapeObjects) {
var errors = [];
for (var i = 0, l = plainShapeObjects.length; i < l; i++) {
var result = (0, _svgPoints.valid)(plainShapeObjects[i]);
if (!result.valid) {
var errs = result.errors;
for (var _i = 0, _l = errs.length; _i < _l; _i++) {
errors.push(errs[_i]);
}
}
}
if (errors.length) {
throw new TypeError(errorMsg(errors));
}
return true;
};
/**
* Joins an array of error messages into one error message.
*
* @param {string[]} errors
*
* @returns {string}
*
* @example
* errorMsg([
* 'cx prop is required on a ellipse',
* 'cy prop must be of type number'
* ])
*/
var errorMsg = function errorMsg(errors) {
return 'Plain Shape Object props not valid: ' + errors.join('. ');
};
/**
* Validates forces prop.
*
* @param {PlainShapeObject[]} plainShapeObjects
*
* @throws {TypeError} Throws if not valid
*
* @returns {true}
*
* @example
* if (forcesPropValid([ circle ])) {
* console.log('circle has valid forces prop')
* }
*/
var forcesPropValid = function forcesPropValid(plainShapeObjects) {
var errors = [];
for (var i = 0, l = plainShapeObjects.length; i < l; i++) {
var forces = plainShapeObjects[i].forces;
if (typeof forces !== 'undefined') {
if (Array.isArray(forces)) {
for (var _i = 0, _l = forces.length; _i < _l; _i++) {
if (typeof forces[_i] !== 'function') {
errors.push('each force item should be of type function');
}
}
} else {
errors.push('the forces prop must be of type array');
}
}
}
if (errors.length) {
throw new TypeError(errorMsg(errors));
}
return true;
};
/**
* Validates PlainShapeObjectMotionPathProps.
*
* @param {PlainShapeObject[]} plainShapeObjects
*
* @throws {TypeError} Throws if not valid
*
* @returns {true}
*
* @example
* if (motionPathPropsValid([ circle ])) {
* console.log('circle has valid motion path props')
* }
*/
var motionPathPropsValid = function motionPathPropsValid(plainShapeObjects) {
var errors = [];
for (var i = 0, l = plainShapeObjects.length; i < l; i++) {
var _plainShapeObject = plainShapeObjects[i];
var accuracy = _plainShapeObject.accuracy;
var rotate = _plainShapeObject.rotate;
if (typeof accuracy !== 'undefined' && !(typeof accuracy === 'number' && accuracy > 0)) {
errors.push('the accuracy prop must be a number greater than 0');
}
if (typeof rotate !== 'undefined' && !(typeof rotate === 'boolean' || typeof rotate === 'number')) {
errors.push('the rotate prop must be a of type boolean or number');
}
}
if (errors.length) {
throw new TypeError(errorMsg(errors));
}
return true;
};
/**
* Validates name prop.
*
* @param {PlainShapeObject[]} plainShapeObjects
*
* @throws {TypeError} Throws if not valid
*
* @returns {true}
*
* @example
* if (namePropValid([ circle ])) {
* console.log('circle has a valid name prop')
* }
*/
var namePropValid = function namePropValid(plainShapeObjects) {
var errors = [];
for (var i = 0, l = plainShapeObjects.length; i < l; i++) {
var name = plainShapeObjects[i].name;
if (typeof name !== 'undefined' && !(typeof name === 'string' || typeof name === 'number')) {
errors.push('the name prop must be of type string or number');
}
}
if (errors.length) {
throw new TypeError(errorMsg(errors));
}
return true;
};
/**
* Creates a PlainShapeObject from a Shape.
*
* @param {Shape} shape
* @param {number} [at]
*
* @returns {PlainShapeObject}
*
* @example
* plainShapeObject(circle)
*/
var plainShapeObject = function plainShapeObject(shape, at) {
if (process.env.NODE_ENV !== 'production' && ((typeof shape === 'undefined' ? 'undefined' : _typeof(shape)) !== 'object' || !shape.keyframes)) {
throw new Error('The plainShapeObject function\'s first argument must be a Shape');
}
if (process.env.NODE_ENV !== 'production' && typeof at !== 'undefined' && typeof at !== 'number') {
throw new TypeError('The plainShapeObject function\'s second argument must be of type number');
}
var frameShape = typeof shape.timeline === 'undefined' ? shape.keyframes[0].frameShape : (0, _frame2.default)(shape.timeline, at)[shape.timelineIndex];
return plainShapeObjectFromFrameShape(frameShape);
};
/**
* Creates a PlainShapeObject from a FrameShape.
*
* @param {FrameShape} frameShape
*
* @returns {PlainShapeObject}
*
* @example
* plainShapeObjectFromFrameShape(frameShape)
*/
var plainShapeObjectFromFrameShape = function plainShapeObjectFromFrameShape(_ref) {
var attributes = _ref.attributes,
points = _ref.points,
childFrameShapes = _ref.childFrameShapes;
if (childFrameShapes) {
var shapes = [];
for (var i = 0, l = childFrameShapes.length; i < l; i++) {
shapes.push(plainShapeObjectFromFrameShape(childFrameShapes[i]));
}
return _extends({}, attributes, {
type: 'g',
shapes: shapes
});
}
return _extends({}, attributes, {
type: 'path',
d: (0, _svgPoints.toPath)(points)
});
};
/**
* Validates transforms prop.
*
* @param {PlainShapeObject[]} plainShapeObjects
*
* @throws {TypeError} Throws if not valid
*
* @returns {true}
*
* @example
* if (transformsPropValid([ circle ])) {
* console.log('circle has valid transforms prop')
* }
*/
var transformsPropValid = function transformsPropValid(plainShapeObjects) {
var errors = [];
for (var i = 0, l = plainShapeObjects.length; i < l; i++) {
var transforms = plainShapeObjects[i].transforms;
if (typeof transforms !== 'undefined') {
if (Array.isArray(transforms)) {
for (var _i = 0, _l = transforms.length; _i < _l; _i++) {
var _transforms$i = _toArray(transforms[i]),
key = _transforms$i[0],
args = _transforms$i.slice(1);
switch (key) {
case 'moveIndex':
case 'rotate':
if (args.length === 1) {
if (typeof args[0] !== 'number') {
errors.push('moveIndex transform argument should be of type number');
}
} else {
errors.push('moveIndex transform takes 1 argument');
}
break;
case 'offset':
if (args.length === 2) {
if (typeof args[0] !== 'number' || typeof args[1] !== 'number') {
errors.push('both offset transform arguments should be of type number');
}
} else {
errors.push('offset transform takes 2 arguments (x and y)');
}
break;
case 'reverse':
if (args.length > 0) {
errors.push('reverse transform takes no arguments');
}
break;
case 'scale':
if (args.length > 0 && args.length < 3) {
if (typeof args[0] !== 'number') {
errors.push('scale transform scaleFactor argument should be of type number');
}
if (typeof args[1] !== 'undefined' && typeof args[1] !== 'string') {
errors.push('scale transform anchor argument should be of type string');
}
} else {
errors.push('scale transform takes 1 or 2 arguments');
}
break;
default:
errors.push(key + ' is not a valid transform');
}
}
} else {
errors.push('the transforms prop must be of type array');
}
}
}
if (errors.length) {
throw new TypeError(errorMsg(errors));
}
return true;
};
/**
* Validates PlainShapeObjectTweenProps.
*
* @param {PlainShapeObject[]} plainShapeObjects
*
* @throws {TypeError} Throws if not valid
*
* @returns {true}
*
* @example
* if (tweenPropsValid([ circle, square ])) {
* console.log('circle and square have valid tween props')
* }
*/
var tweenPropsValid = function tweenPropsValid(plainShapeObjects) {
var errors = [];
for (var i = 0, l = plainShapeObjects.length; i < l; i++) {
var _plainShapeObjects$i = plainShapeObjects[i],
delay = _plainShapeObjects$i.delay,
duration = _plainShapeObjects$i.duration,
easing = _plainShapeObjects$i.easing;
if (typeof delay !== 'undefined' && !(typeof delay === 'number' && delay > 0)) {
errors.push('the delay prop must be a number greater than 0');
}
if (typeof duration !== 'undefined' && !(typeof duration === 'number' && duration >= 0)) {
errors.push('the duration prop must be a number greater than or equal to 0');
}
if (typeof easing !== 'undefined' && !(typeof easing === 'function' || typeof easing === 'string')) {
errors.push('the easing prop must be a of type function or string');
}
}
if (errors.length) {
throw new TypeError(errorMsg(errors));
}
return true;
};
/**
* Validates one or more PlainShapeObject.
*
* @param {...PlainShapeObject} plainShapeObjects
*
* @throws {TypeError} Throws if not valid
*
* @returns {true}
*
* @example
* if (valid(circle)) {
* console.log('circle is a valid Plain Shape Object')
* }
*/
var valid = function valid() {
for (var _len = arguments.length, plainShapeObjects = Array(_len), _key = 0; _key < _len; _key++) {
plainShapeObjects[_key] = arguments[_key];
}
return namePropValid(plainShapeObjects) && corePropsValid(plainShapeObjects) && forcesPropValid(plainShapeObjects) && transformsPropValid(plainShapeObjects) && tweenPropsValid(plainShapeObjects) && motionPathPropsValid(plainShapeObjects);
};
exports.valid = valid;
exports.default = plainShapeObject;