UNPKG

wilderness-core

Version:
592 lines (489 loc) 16.5 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.tween = exports.splitLines = exports.pointStructure = exports.joinLines = exports.frameShapeFromPlainShapeObject = exports.curveStructure = exports.commonPointStructure = exports.commonCurveStructure = exports.applyPointStructure = exports.applyCurveStructure = exports.addToPointStructure = undefined; 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; }; 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; }; /* globals __DEV__ */ var _points = require('points'); var _clone = require('./clone'); var _clone2 = _interopRequireDefault(_clone); var _middleware = require('./middleware'); var _svgPoints = require('svg-points'); var _timeline = require('./timeline'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } /** * Shape data as specified by the * {@link https://github.com/colinmeinke/points Points spec}. * * @typedef {Object[]} Points */ /** * The data required to render a shape. * * @typedef {Object} FrameShape * * @property {Points} points * @property {Object} attributes * @property {FrameShape[]} childFrameShapes */ /** * A FrameShape array. * * @typedef {FrameShape[]} Frame */ /** * A number between 0 and 1 (inclusive). * * @typedef {number} Position */ /** * The structure of FrameShape Points. * An array represents a shape. A number represents a line. * An array that has nested arrays represents a group of shapes. * * @typedef {(number|number[])[]} PointStructure */ /** * The curve structure of FrameShape Points. * A boolean represents a point, and designates if the point is a curve. * * @typedef {(boolean|boolean[])[]} CurveStructure */ /** * Converts FrameShape Points to curves based on a CurveStructure. * * @param {FrameShape} frameShape * @param {CurveStructure} structure * * @returns {FrameShape} * * @example * applyCurveStructure(frameShape, stucture) */ var applyCurveStructure = function applyCurveStructure(frameShape, structure) { var points = frameShape.points; var childFrameShapes = frameShape.childFrameShapes; if (childFrameShapes) { var nextChildFrameShapes = []; for (var i = 0, l = childFrameShapes.length; i < l; i++) { nextChildFrameShapes.push(applyCurveStructure(childFrameShapes[i], structure[i])); } frameShape.childFrameShapes = nextChildFrameShapes; } else { var curves = false; for (var _i2 = 0, _l2 = structure.length; _i2 < _l2; _i2++) { if (structure[_i2]) { curves = true; break; } } if (curves) { var nextPoints = []; var cubifiedPoints = (0, _points.cubify)(points); for (var _i3 = 0, _l3 = cubifiedPoints.length; _i3 < _l3; _i3++) { var point = cubifiedPoints[_i3]; if (structure[_i3] && !point.curve) { nextPoints.push(_extends({}, point, { curve: { type: 'cubic', x1: points[_i3 - 1].x, y1: points[_i3 - 1].y, x2: points[_i3].x, y2: points[_i3].y } })); } else { nextPoints.push(point); } } frameShape.points = nextPoints; } } return frameShape; }; /** * Restructures a FrameShape's Points based on a PointStructure. * * @param {FrameShape} frameShape * @param {PointStructure} structure * * @returns {FrameShape} * * @example * applyPointStructure(frameShape, stucture) */ var applyPointStructure = function applyPointStructure(frameShape, structure) { if (Array.isArray(structure[0])) { if (!frameShape.childFrameShapes) { frameShape.childFrameShapes = [(0, _clone2.default)(frameShape)]; delete frameShape.points; } if (frameShape.childFrameShapes.length !== structure.length) { for (var i = 0, l = structure.length; i < l; i++) { if (i >= frameShape.childFrameShapes.length) { var previous = frameShape.childFrameShapes[i - 1].points; frameShape.childFrameShapes.push({ attributes: (0, _clone2.default)(frameShape.attributes), points: [_extends({}, (0, _clone2.default)(previous[previous.length - 1]), { moveTo: true }), (0, _clone2.default)(previous[previous.length - 1])] }); } } } var nextChildFrameShapes = []; for (var _i4 = 0, _l4 = frameShape.childFrameShapes.length; _i4 < _l4; _i4++) { nextChildFrameShapes.push(applyPointStructure(frameShape.childFrameShapes[_i4], structure[_i4])); } frameShape.childFrameShapes = nextChildFrameShapes; } else { var lines = splitLines(frameShape.points); for (var _i5 = 0, _l5 = structure.length; _i5 < _l5; _i5++) { var desiredPoints = structure[_i5]; if (!lines[_i5]) { var previousLine = lines[_i5 - 1]; lines[_i5] = [_extends({}, (0, _clone2.default)(previousLine[previousLine.length - 1]), { moveTo: true }), (0, _clone2.default)(previousLine[previousLine.length - 1])]; } if (desiredPoints > lines[_i5].length) { lines[_i5] = (0, _points.add)(lines[_i5], desiredPoints); } } frameShape.points = joinLines(lines); } return frameShape; }; /** * Add a value to a PointStucture at a defined position. * * @param {PointStructure} structure * @param {(number|number[])} value - Value to add to PointStructure. * @param {number} i - Position to add value at. * * @example * addToPointStructure([], 9, 0) */ var addToPointStructure = function addToPointStructure(structure, value, i) { if (Array.isArray(value)) { if (!Array.isArray(structure[i])) { structure[i] = [structure[i]]; } for (var _i = 0, l = value.length; _i < l; _i++) { structure[i] = addToPointStructure(structure[i], value[_i], _i); } } else { if (Array.isArray(structure[i])) { addToPointStructure(structure[i], value, 0); } else { structure[i] = Math.max(structure[i] || 0, value); } } return structure; }; /** * Creates a common CurveStructure from an array of CurveStructures. * * @param {CurveStructure[]} structures * * @returns {CurveStructure} * * @example * commonCurveStructure(structures) */ var commonCurveStructure = function commonCurveStructure(structures) { var structure = structures[0]; for (var i = 1, l = structures.length; i < l; i++) { var s = structures[i]; var c = []; for (var _i = 0, _l = structure.length; _i < _l; _i++) { var x = structure[_i]; if (Array.isArray(x)) { c.push(commonCurveStructure([x, s[_i]])); } else { c.push(x || s[_i]); } } structure = c; } return structure; }; /** * Creates a common PointStructure from an array of PointStructures. * * @param {PointStructure[]} structures * * @returns {PointStructure} * * @example * commonPointStructure(structures) */ var commonPointStructure = function commonPointStructure(structures) { var structure = []; for (var i = 0, l = structures.length; i < l; i++) { var s = structures[i]; for (var _i = 0, _l = s.length; _i < _l; _i++) { structure = addToPointStructure(structure, s[_i], _i); } } return structure; }; /** * The current Frame of a Timeline. * * @param {Timeline} timeline * @param {number} [at] * * @returns {Frame} * * @example * frame(timeline) */ var frame = function frame(timeline, at) { if (process.env.NODE_ENV !== 'production' && ((typeof timeline === 'undefined' ? 'undefined' : _typeof(timeline)) !== 'object' || !timeline.timelineShapes || !timeline.playbackOptions)) { throw new TypeError('The frame function\'s first argument must be a Timeline'); } if (process.env.NODE_ENV !== 'production' && typeof at !== 'undefined' && typeof at !== 'number') { throw new TypeError('The frame function\'s second argument must be of type number'); } (0, _timeline.updateState)(timeline, typeof at !== 'undefined' ? at : Date.now()); var frameShapes = []; var timelineShapes = timeline.timelineShapes; for (var i = 0, l = timelineShapes.length; i < l; i++) { var timelineShape = timelineShapes[i]; var shape = timelineShape.shape; var keyframes = shape.keyframes; var timelinePosition = timelineShape.timelinePosition; var start = timelinePosition.start; var finish = timelinePosition.finish; var position = timeline.state.position; if (position <= start) { frameShapes.push((0, _middleware.output)(keyframes[0].frameShape, timeline.middleware)); } else if (position >= finish) { frameShapes.push((0, _middleware.output)(keyframes[keyframes.length - 1].frameShape, timeline.middleware)); } else { var shapePosition = (position - start) / (finish - start); frameShapes.push(frameShapeFromShape(shape, shapePosition, timeline.middleware)); } } return frameShapes; }; /** * Creates a FrameShape from a PlainShapeObject. * * @param {PlainShapeObject} plainShapeObject * * @returns {FrameShape} * * @example * frameShapeFromPlainShapeObject(circle) */ var frameShapeFromPlainShapeObject = function frameShapeFromPlainShapeObject(_ref) { var childPlainShapeObjects = _ref.shapes, plainShapeObject = _objectWithoutProperties(_ref, ['shapes']); var type = plainShapeObject.type, height = plainShapeObject.height, width = plainShapeObject.width, x = plainShapeObject.x, y = plainShapeObject.y, cx = plainShapeObject.cx, cy = plainShapeObject.cy, r = plainShapeObject.r, rx = plainShapeObject.rx, ry = plainShapeObject.ry, x1 = plainShapeObject.x1, x2 = plainShapeObject.x2, y1 = plainShapeObject.y1, y2 = plainShapeObject.y2, d = plainShapeObject.d, points = plainShapeObject.points, shapes = plainShapeObject.shapes, attributes = _objectWithoutProperties(plainShapeObject, ['type', 'height', 'width', 'x', 'y', 'cx', 'cy', 'r', 'rx', 'ry', 'x1', 'x2', 'y1', 'y2', 'd', 'points', 'shapes']); if (plainShapeObject.type === 'g' && childPlainShapeObjects) { var childFrameShapes = []; for (var i = 0, l = childPlainShapeObjects.length; i < l; i++) { childFrameShapes.push(frameShapeFromPlainShapeObject(childPlainShapeObjects[i])); } return { attributes: attributes, childFrameShapes: childFrameShapes }; } return { attributes: attributes, points: (0, _svgPoints.toPoints)(plainShapeObject) }; }; /** * Creates a FrameShape from a Shape given the Position. * * @param {Shape} shape * @param {Position} position * @param {Middleware[]} middleware * * @returns {FrameShape} * * @example * frameShapeFromShape(shape, 0.75, []) */ var frameShapeFromShape = function frameShapeFromShape(shape, position, middleware) { var keyframes = shape.keyframes; var fromIndex = 0; for (var i = 0, l = keyframes.length; i < l; i++) { if (position > keyframes[i].position) { fromIndex = i; } } var toIndex = fromIndex + 1; var from = keyframes[fromIndex]; var to = keyframes[toIndex]; var keyframePosition = (position - from.position) / (to.position - from.position); var forces = to.tween.forces; var frameShape = tween(from.frameShape, to.frameShape, to.tween.easing, keyframePosition); for (var _i6 = 0, _l6 = forces.length; _i6 < _l6; _i6++) { frameShape = forces[_i6](frameShape, keyframePosition); } return (0, _middleware.output)(frameShape, middleware); }; /** * Joins an array of Points into Points. * * @param {Points[]} lines * * @returns {Points} * * @example * joinLines([ shape1, shape2 ]) */ var joinLines = function joinLines(lines) { var _ref2; return (_ref2 = []).concat.apply(_ref2, _toConsumableArray(lines)); }; /** * Creates a CurveStructure from a FrameShape. * * @param {FrameShape} frameShape * * @returns {CurveStructure} * * @example * curveStructure(frameShape) */ var curveStructure = function curveStructure(_ref3) { var points = _ref3.points, childFrameShapes = _ref3.childFrameShapes; var s = []; if (childFrameShapes) { for (var i = 0, l = childFrameShapes.length; i < l; i++) { s.push(curveStructure(childFrameShapes[i])); } } else { for (var _i7 = 0, _l7 = points.length; _i7 < _l7; _i7++) { s.push(typeof points[_i7].curve !== 'undefined'); } } return s; }; /** * Creates a PointStructure from a FrameShape. * * @param {FrameShape} frameShape * * @returns {PointStructure} * * @example * pointStructure(frameShape) */ var pointStructure = function pointStructure(_ref4) { var points = _ref4.points, childFrameShapes = _ref4.childFrameShapes; if (childFrameShapes) { var s = []; for (var i = 0, l = childFrameShapes.length; i < l; i++) { s.push(pointStructure(childFrameShapes[i])); } return s; } var structure = []; for (var _i8 = 0, _l8 = points.length; _i8 < _l8; _i8++) { if (points[_i8].moveTo) { structure.push(1); } else { structure[structure.length - 1]++; } } return structure; }; /** * Splits Points at moveTo commands. * * @param {Points} points * * @return {Points[]} * * @example * splitLines(points) */ var splitLines = function splitLines(points) { var lines = []; for (var i = 0, l = points.length; i < l; i++) { var point = points[i]; if (point.moveTo) { lines.push([point]); } else { lines[lines.length - 1].push(point); } } return lines; }; /** * Tween between any two values. * * @param {*} from * @param {*} to - An identicle structure to the from param * @param {function} easing - The easing function to apply * @param {Position} position * * @returns {*} * * @example * tween(0, 100, easeOut, 0.75) */ var tween = function tween(from, to, easing, position) { if (typeof from === 'number') { if (process.env.NODE_ENV !== 'production' && typeof to !== 'number') { throw new TypeError('The tween function\'s from and to arguments must be of an identicle structure'); } if (from === to) { return from; } return easing(position, from, to, 1); } else if (Array.isArray(from)) { if (process.env.NODE_ENV !== 'production' && !Array.isArray(to)) { throw new TypeError('The tween function\'s from and to arguments must be of an identicle structure'); } var arr = []; for (var i = 0, l = from.length; i < l; i++) { arr.push(tween(from[i], to[i], easing, position)); } return arr; } else if (from !== null && (typeof from === 'undefined' ? 'undefined' : _typeof(from)) === 'object') { if (process.env.NODE_ENV !== 'production' && to !== null && (typeof to === 'undefined' ? 'undefined' : _typeof(to)) !== 'object') { throw new TypeError('The tween function\'s from and to arguments must be of an identicle structure'); } var obj = {}; for (var k in from) { obj[k] = tween(from[k], to[k], easing, position); } return obj; } return from; }; exports.addToPointStructure = addToPointStructure; exports.applyCurveStructure = applyCurveStructure; exports.applyPointStructure = applyPointStructure; exports.commonCurveStructure = commonCurveStructure; exports.commonPointStructure = commonPointStructure; exports.curveStructure = curveStructure; exports.frameShapeFromPlainShapeObject = frameShapeFromPlainShapeObject; exports.joinLines = joinLines; exports.pointStructure = pointStructure; exports.splitLines = splitLines; exports.tween = tween; exports.default = frame;