From ffa87efcb8af16fd981d546859693ad4647bd59f Mon Sep 17 00:00:00 2001 From: Anish_Ramesan Date: Thu, 12 May 2016 14:56:59 +0530 Subject: [PATCH 01/32] rAF with observers - animation module with observers - easing as separate module and references updated - kind with animate API for simple application of animations. - scene module to create animation instances. - transform to handle math operations. - tween to create animation frames based on time. Enyo-DCO-1.1-Signed-off-by: Anish Ramesan --- src/Animator.js | 3 +- src/animation.js | 94 +++--- src/easing.js | 408 ++++++++++++++++++++++++++ src/kind.js | 35 ++- src/scene.js | 329 +++++++++++++++++++++ src/transform.js | 731 +++++++++++++++++++++++++++++++++++++++++++++++ src/tween.js | 702 +++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 2245 insertions(+), 57 deletions(-) create mode 100644 src/easing.js create mode 100644 src/scene.js create mode 100644 src/transform.js create mode 100644 src/tween.js diff --git a/src/Animator.js b/src/Animator.js index 631db7cba..8431a48ec 100644 --- a/src/Animator.js +++ b/src/Animator.js @@ -8,6 +8,7 @@ require('enyo'); var kind = require('./kind'), utils = require('./utils'), + easing = require('./easing'), animation = require('./animation'); var @@ -145,7 +146,7 @@ module.exports = kind( * @default module:enyo/easing~easing.cubicOut * @public */ - easingFunction: animation.easing.cubicOut + easingFunction: easing.cubicOut }, /* diff --git a/src/animation.js b/src/animation.js index 2176e080e..68453dcbb 100644 --- a/src/animation.js +++ b/src/animation.js @@ -15,7 +15,9 @@ var ms = Math.round(1000/60), cRAF = 'cancelRequestAnimationFrame', cAF = 'cancelAnimationFrame', i, pl, p, wcRAF, wrAF, wcAF, - _requestFrame, _cancelFrame, cancelFrame; + _requestFrame, _cancelFrame, cancelFrame, + core = { ts: 0, obs: []}; + /* * Fallback on setTimeout @@ -98,63 +100,35 @@ exports.cancelRequestAnimationFrame = function(id) { exports.cancelAnimationFrame = function(id) { return _cancelFrame(id); }; - /** -* A set of interpolation functions for animations, similar in function to CSS3 -* transitions. +* Subcribes for animation frame ticks. * -* These are intended for use with {@link module:enyo/animation#easedLerp}. Each easing function -* accepts one (1) [Number]{@glossary Number} parameter and returns one (1) -* [Number]{@glossary Number} value. +* @param {Object} ctx - The context on which callback is registered. +* @param {Function} callback - A [callback]{@glossary callback} to be executed on tick. +* @public +*/ +exports.subscribe = function(ctx,callback) { + core.obs.push(utils.bindSafely(ctx, callback)); + return core.obs.length -1; +}; +/** +* Unsubcribes for animation frame ticks. * +* @param {Object} node - The context on which callback is registered. +* @param {Function} callback - A [callback]{@glossary callback} to be executed on tick. * @public */ -exports.easing = /** @lends module:enyo/animation~easing.prototype */ { - /** - * cubicIn - * - * @public - */ - cubicIn: function(n) { - return Math.pow(n, 3); - }, - /** - * cubicOut - * - * @public - */ - cubicOut: function(n) { - return Math.pow(n - 1, 3) + 1; - }, - /** - * expoOut - * - * @public - */ - expoOut: function(n) { - return (n == 1) ? 1 : (-1 * Math.pow(2, -10 * n) + 1); - }, - /** - * quadInOut - * - * @public - */ - quadInOut: function(n) { - n = n * 2; - if (n < 1) { - return Math.pow(n, 2) / 2; - } - return -1 * ((--n) * (n - 2) - 1) / 2; - }, - /** - * linear - * - * @public - */ - linear: function(n) { - return n; - } +exports.unsubscribe = function(id) { + core.obs.splice(id, 1); +}; + +var startrAF = function(){ + _requestFrame(function (time) { + startrAF(); + core.ts = time; + }.bind(this)); }; +startrAF(); /** * Gives an interpolation of an animated transition's distance from 0 to 1. @@ -206,3 +180,19 @@ exports.easedComplexLerp = function(t0, duration, easing, reverse, time, startVa return easing(lerp, time, startValue, valueChange, duration); } }; + + +//TODO: A temporary implementation for rAF with observers. +Object.defineProperty(core, 'ts', { + + get: function() { + return this.value; + }, + + set: function(newValue) { + for (var i = 0, ob; (ob = this.obs[i]); i++) { + ob(this.value, newValue); + } + this.value = newValue; + } +}); \ No newline at end of file diff --git a/src/easing.js b/src/easing.js new file mode 100644 index 000000000..e6dd104cb --- /dev/null +++ b/src/easing.js @@ -0,0 +1,408 @@ +/** +* Contains set of interpolation functions for animations, similar in function to CSS3 transitions. +* @module enyo/easing +*/ + +var easing = module.exports = { + /** + * linear + * + * @public + */ + linear: function(n) { + return n; + }, + /** + * cubicIn + * + * @public + */ + cubicIn: function(n) { + return Math.pow(n, 3); + }, + /** + * cubicOut + * + * @public + */ + cubicOut: function(n) { + return Math.pow(n - 1, 3) + 1; + }, + /** + * expoOut + * + * @public + */ + expoOut: function(n) { + return (n == 1) ? 1 : (-1 * Math.pow(2, -10 * n) + 1); + }, + /** + * quadInOut + * + * @public + */ + quadInOut: function(n) { + n = n * 2; + if (n < 1) { + return Math.pow(n, 2) / 2; + } + return -1 * ((--n) * (n - 2) - 1) / 2; + }, + + /** + * EaseInQuad + * @public + * @param {number} t - current time + * @return {number} - calculated time + */ + easeInQuad: function(t) { + return t * t; + }, + + /** + * EaseOutQuad + * @public + * @param {number} t - current time + * @return {number} calculated time + */ + easeOutQuad: function(t) { + return -1 * t * (t - 2); + }, + + /** + * EaseInOutQuad + * @public + * @param {number} t - current time + * @return {number} calculated time + */ + easeInOutQuad: function(t) { + if ((t *= 2) < 1) return 0.5 * t * t; + return -0.5 * ((--t) * (t - 2) - 1); + }, + + /** + * EaseInCubic + * @public + * @param {number} t - current time + * @return {number} calculated time + */ + easeInCubic: function(t) { + return t * t * t; + }, + + /** + * EaseOutCubic + * @public + * @param {number} t - current time + * @return {number} calculated time + */ + easeOutCubic: function(t) { + return --t * t * t + 1; + }, + + /** + * EaseInOutCubic + * @public + * @param {number} t - current time + * @return {number} calculated time + */ + easeInOutCubic: function(t) { + if ((t *= 2) < 1) return 0.5 * t * t * t; + return 0.5 * ((t -= 2) * t * t + 2); + }, + + /** + * EaseInQuart + * @public + * @param {number} t - current time + * @return {number} calculated time + */ + easeInQuart: function(t) { + return t * t * t * t; + }, + + /** + * EaseOutQuart + * @public + * @param {number} t - current time + * @return {number} calculated time + */ + easeOutQuart: function(t) { + return -1 * (--t * t * t * t - 1); + }, + + /** + * EaseInOutQuart + * @public + * @param {number} t - current time + * @return {number} calculated time + */ + easeInOutQuart: function(t) { + if ((t *= 2) < 1) return 0.5 * t * t * t * t; + return -0.5 * ((t -= 2) * t * t * t - 2); + }, + + /** + * EaseInQuint + * @public + * @param {number} t - current time + * @return {number} calculated time + */ + easeInQuint: function(t) { + return t * t * t * t * t; + }, + /** + * EaseOutQuint + * @public + * @param {number} t - current time + * @return {number} calculated time + */ + easeOutQuint: function(t) { + return --t * t * t * t * t + 1; + }, + + /** + * EaseInOutQuint + * @public + * @param {number} t - current time + * @return {number} calculated time + */ + easeInOutQuint: function(t, d) { + if ((t *= 2) < 1) return 0.5 * t * t * t * t * t; + return 0.5 * ((t -= 2) * t * t * t * t + 2); + }, + + /** + * EaseInSine + * @public + * @param {number} t - current time + * @return {number} calculated time + */ + easeInSine: function(t) { + return -1 * Math.cos(t * (Math.PI / 2)) + 1; + }, + + /** + * EaseOutSine + * @public + * @param {number} t - current time + * @return {number} calculated time + */ + easeOutSine: function(t) { + return Math.sin(t * (Math.PI / 2)); + }, + + /** + * EaseInOutSine + * @public + * @param {number} t - current time + * @return {number} calculated time + */ + easeInOutSine: function(t) { + return -0.5 * (Math.cos(Math.PI * t) - 1); + }, + + /** + * EaseInExpo + * @public + * @param {number} t - current time + * @return {number} calculated time + */ + easeInExpo: function(t) { + return (t === 0) ? 0 : Math.pow(2, 10 * (t - 1)); + }, + + /** + * EaseOutExpo + * @public + * @param {number} t - current time + * @return {number} calculated time + */ + easeOutExpo: function(t) { + return (t === 1) ? 1 : -Math.pow(2, -10 * t) + 1; + }, + + /** + * EaseInOutExpo + * @public + * @param {number} t - current time + * @return {number} calculated time + */ + easeInOutExpo: function(t) { + if (t === 0) return 0; + if (t === 1) return 1; + if ((t *= 2) < 1) return 0.5 * Math.pow(2, 10 * (t - 1)); + return 0.5 * (-Math.pow(2, -10 * --t) + 2); + }, + + /** + * EaseInCirc + * @public + * @param {number} t - current time + * @return {number} calculated time + */ + easeInCirc: function(t) { + return -1 * (Math.sqrt(1 - t * t) - 1); + }, + + /** + * EaseOutCirc + * @public + * @param {number} t - current time + * @return {number} calculated time + */ + easeOutCirc: function(t) { + return Math.sqrt(1 - --t * t); + }, + + /** + * EaseInOutCirc + * @public + * @param {number} t - current time + * @return {number} calculated time + */ + easeInOutCirc: function(t) { + if ((t *= 2) < 1) return -0.5 * (Math.sqrt(1 - t * t) - 1); + return 0.5 * (Math.sqrt(1 - (t -= 2) * t) + 1); + }, + + /** + * EaseInElastic + * @public + * @param {number} t - current time + * @param {number} d - duration + * @return {number} calculated time + */ + easeInElastic: function(t, d) { + var a = 1, + p = 0, + s = 1.70158; + if (t === 0) return 0; + if (t === 1) return 1; + if (!p) p = d * 0.3; + if (a < 1) { + a = 1; + s = p / 4; + } else s = p / (2 * Math.PI) * Math.asin(1 / a); + return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)); + }, + + /** + * EaseInBounce + * @public + * @param {number} t - current time + * @return {number} calculated time + */ + easeInBounce: function(t) { + return 1 - easing.easeOutBounce(1 - t); + }, + + /** + * EaseOutBounce + * @public + * @param {number} t - current time + * @return {number} calculated time + */ + easeOutBounce: function(t) { + if (t < 0.363636) { + return 7.5625 * t * t; + } else if (t < 0.727272) { + return 7.5625 * (t -= 0.545454) * t + 0.75; + } else if (t < (2.5 / 2.75)) { + return 7.5625 * (t -= 0.818182) * t + 0.9375; + } else { + return 7.5625 * (t -= 0.954545) * t + 0.984375; + } + }, + + /** + * EaseInOutBounce + * @public + * @param {number} t - current time + * @return {number} calculated time + */ + easeInOutBounce: function(t) { + if (t < 0.5) return easing.easeInBounce(t * 2) * 0.5; + return easing.easeOutBounce(t * 2 - 1) * 0.5 + 0.5; + }, + + /** + * EaseOutElastic + * @public + * @param {number} t - current time + * @param {number} d - duration + * @return {number} calculated time + */ + easeOutElastic: function(t, d) { + var a = 1, + p = 0, + s = 1.70158; + if (t === 0) return 0; + if (t === 1) return 1; + if (!p) p = d * 0.3; + if (a < 1) { + a = 1; + s = p / 4; + } else s = p / (2 * Math.PI) * Math.asin(1 / a); + return a * Math.pow(2, -10 * t) * Math.sin((t * d - s) * (2 * Math.PI) / p) + 1; + }, + + /** + * EaseInOutElastic + * @public + * @param {number} t - current time + * @param {number} d - duration + * @return {number} calculated time + */ + easeInOutElastic: function(t, d) { + var a = 1, + p = 0, + s = 1.70158; + if (t === 0) return 0; + if ((t *= 2) === 2) return 1; + if (!p) p = d * (0.3 * 1.5); + if (a < 1) { + a = 1; + s = p / 4; + } else s = p / (2 * Math.PI) * Math.asin(1 / a); + if (t < 1) return -0.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)); + return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p) * 0.5 + 1; + }, + + /** + * EaseInBack + * @public + * @param {number} t - current time + * @param {number} d - duration + * @return {number} calculated time + */ + easeInBack: function(t, d, s) { + if (!s) s = 1.70158; + return t * t * ((s + 1) * t - s); + }, + + /** + * EaseOutBack + * @public + * @param {number} t - current time + * @param {number} d - duration + * @return {number} calculated time + */ + easeOutBack: function(t, d, s) { + if (!s) s = 1.70158; + return --t * t * ((s + 1) * t + s) + 1; + }, + + /** + * EaseInOutBack + * @public + * @param {number} t - current time + * @param {number} d - duration + * @return {number} calculated time + */ + easeInOutBack: function(t, d, s) { + if (!s) s = 1.70158; + if ((t *= 2) < 1) return 0.5 * (t * t * (((s *= (1.525)) + 1) * t - s)); + return 0.5 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2); + } +}; \ No newline at end of file diff --git a/src/kind.js b/src/kind.js index 7a479c75c..bc8f25e1e 100644 --- a/src/kind.js +++ b/src/kind.js @@ -1,8 +1,9 @@ require('enyo'); var - logger = require('./logger'), - utils = require('./utils'); + logger = require('./logger'), + scene = require('./scene'), + utils = require('./utils'); var defaultCtor = null; @@ -420,13 +421,20 @@ kind.statics = { * @private */ exports.concatHandler = function (ctor, props, instance) { - var proto = ctor.prototype || ctor - , base = proto.ctor; + var proto = ctor.prototype || ctor, + base = proto.ctor, sctor; while (base) { if (base.concat) base.concat(ctor, props, instance); base = base.prototype.base; } + + // install common statics + if (props.scene) { + sctor = new scene(proto, props.scene); + proto.scene = sctor; + delete props.scene; + } }; var kindCtors = @@ -504,3 +512,22 @@ exports.createFromKind = function (nom, param) { return new Ctor(param); } }; +/** + * Interface which accepts the animation details and returns a scene object + * @param {Array} proto Actors + * @param {Object} properties Animation Properties + * @param {number} duration Animation duration + * @param {String} completed Callback function on completion + * @return {Object} A scene object + */ +exports.animate = function(proto, properties, opts) { + var i, ctor, s, + ctors = utils.isArray(proto) ? proto : [proto]; + + for (i = 0; (ctor = ctors[i]); i++) { + s = new scene(ctor, properties); + if (opts && opts.delay) opts.delay += opts.delay; + utils.mixin(s, opts); + } + return s; +}; \ No newline at end of file diff --git a/src/scene.js b/src/scene.js new file mode 100644 index 000000000..fe5bebd27 --- /dev/null +++ b/src/scene.js @@ -0,0 +1,329 @@ +var + tween = require('./tween'), + utils = require('./utils'), + animation = require('./animation'); + +var _ts, _framerate = 16.6; + +var AnimationSupport = { + /** + * @public + */ + span: 0, + /** + * @private + */ + timeline: 0, + /** + * @public + */ + repeat: false, + /** + * @public + */ + handleLayers: false, + /** + * @public + */ + animating: false, + /** + * @public + */ + direction: 0, + /** + * @public + */ + speed: 0, + /** + * @public + */ + seekInterval: 0, + + /** + * Starts the animation of the actor given in argument. + * If actor is not provided, animation of all the components linked to the {@link module:enyo/AnimationSupport/Scene} will be started. + * @param [Component]{@link module:enyo/Component~Component} actor The component to be animated + * @public + */ + play: function () { + this.direction = this.speed = 1; + if (isNaN(this.timeline) || !this.timeline) { + this.timeline = 0; + } + this.animating = true; + return this; + }, + + /** + * Resumes the paused animation of the actor given in argument. + * If actor is not provided, animation of all the components linked to the {@link module:enyo/AnimationSupport/Scene} will be resumed. + * @param [Component]{@link module:enyo/Component~Component} actor The component to be animated + * @public + */ + resume: function() { + this.direction = 1; + return this; + }, + + /** + * Pauses the animation of the actor given in argument. + * If actor is not provided, animation of all the components linked to the {@link module:enyo/AnimationSupport/Scene} will be paused. + * @param [Component]{@link module:enyo/Component~Component} actor The component to be animated + * @public + */ + pause: function () { + this.direction = 0; + return this; + }, + + /** + * Reverses the animation of the actor given in argument. + * If actor is not provided, animation of all the components linked to the {@link module:enyo/AnimationSupport/Scene} will be reversed. + * @param [Component]{@link module:enyo/Component~Component} actor The component to be animated + * @public + */ + reverse: function () { + this.direction = -1; + }, + + /** + * Changes the speed of the animation.
+ * Speed of the animation changed based on the factor.
+ * To slow down the speed use values between 0 and 1. For Example 0.5 to reduce the speed by 50%.
+ * To increase the speed use values above 1. For Example 2 to increase the speed by 200%.
+ * Animation will be paused if factor is 0. To pause the animation use {@link enyo/AnimationSupport/Editor.pause pause} API.
+ * Speed will not be affected incase of negative multiplication factor. + * @param {Number} factor Multiplication factor which changes the speed + * @param [Component {@link module:enyo/Component~Component}] actor The component whose animating speed should be changed + * @public + */ + // speed: function(mul, actor) { + // if (mul < 0) return; + // this.cache(actor); + // actor = actor || this; + // actor.speed *= mul; + // }, + + /** + * Stops the animation of the actor given in argument. + * If actor is not provided, animation of all the components linked to the {@link module:enyo/AnimationSupport/Scene} will be stopped. + * @param [Component]{@link module:enyo/Component~Component} actor The component to be animated + * @public + */ + stop: function () { + this.speed = 0; + this.timeline = 0; + }, + + /** + * Seeks the animation of the actor to the position provided in seek + * The value of seek should be between 0 to duration of the animation. + * @param {Number} seek Value in seek where the animation has to be seeked + * @param [Component]{@link module:enyo/Component~Component} actor The component to be animated + * @public + */ + seek: function(seek) { + this.timeline = seek; + }, + + /** + * Seeks actor with animation to the position provided in seek + * The value of seek should be between 0 to duration of the animation. + * @param {Number} seek Value in seek where the animation has to be seeked + * @param [Component]{@link module:enyo/Component~Component} actor The component to be animated + * @public + */ + seekAnimate: function(seek) { + if (seek >= 0 ) { + if (!this.animating) + this.play(); + this.speed = 1; + }else{ + this.speed = -1; + } + this.seekInterval = this.timeline + seek; + if (this.seekInterval < 0) { + this.speed = 0; + this.seekInterval = 0; + } + }, + + //TODO: Move these events to Event Delegator + /** + * Event to identify when the scene has done animating. + * @memberOf module:enyo/AnimationSupport/Actor + * @public + */ + completed: function() {}, + + /** + * Event to identify when the scene has done a step(rAF updatation of time) in the animation. + * @memberOf module:enyo/AnimationSupport/Actor + * @public + */ + step: function() {} +}; + +/** +* {@link module:enyo/Scene~Scene} is a work-in-progress module +* +* @class Scene +* @extends module:enyo/Scene~Scene +* @wip +* @private +*/ +var scene = module.exports = function (actor, props) { + this.id = utils.uid("@"); + this.poses = []; + this.rolePlays = []; + this.actor = actor; + + this.rAFId = animation.subscribe(this, loop); + utils.mixin(this, AnimationSupport); + + if (props) { + var anims = utils.isArray(props) ? props : [props]; + for (var i = 0, anim; (anim = anims[i]); i++) { + this.addAnimation(anim, anim.duration || 0); + } + } +}; + +scene.prototype.getAnimation = function (index) { + return index < 0 || this.poses[index]; +}; + +scene.prototype.addAnimation = function (newProp, span) { + var l = this.poses.length, old; + + if (l > 0) { + old = this.poses[l-1]; + span += old.span; + } + this.poses.push({animate: newProp, span: span}); + this.span = span; +}; + +scene.prototype.action = function(ts, pose) { + var past, index, tm, + dur = this.span; + + if (this.actor && this.actor.generated) { + tm = rolePlay(ts, this); + if (isNaN(tm) || tm < 0) return pose; + else if (tm <= dur) { + index = animateAtTime(this.poses, tm); + pose = this.poses[index]; + past = index ? this.poses[index - 1].span : 0; + update(pose, this.actor, tm - past, pose.span - past); + this.step && this.step(this.actor); + } else { + this.timeline = this.repeat ? 0 : this.span; + if(!this.repeat) this.cut(); + } + } + return pose; +}; + +scene.prototype.cut = function () { + if (this.handleLayers) { + this.speed = 0; + if (this.active) { + this.active = false; + tween.halt(this.actor); + } + } + this.animating = false; + this.completed && this.completed(this.actor); +}; + +scene.prototype.addScene = function (scene) { + this.span = scene.span + this.span; + this.rolePlays.push({ + scene: scene, + span: this.span, + dur: scene.span + }); +}; + + +function loop (was, is) { + if (this.animating) { + _ts = is - (was || 0); + _ts = (_ts > _framerate) ? _framerate : _ts; + this.action(_ts); + } else if(this.actor.destroyed) { + animation.unsubscribe(this.rAFId); + } +} + +function update (pose, actor, since, dur) { + var t; + if (!pose._startAnim) tween.init(actor, pose); + + if (since < 0) since = 0; + if (since <= dur && dur !== 0) { + t = since / dur; + tween.step(actor, pose, t, dur); + } else { + tween.step(actor, pose, 1, dur); + } +} + +/** + * rolePlay updated the timeline of the actor which is currently animating. + * @param {Number} t Elapsed time since the animation of this pose has started (ratio in factor of 1) + * @param {@link module:enyo/Component~Component} actor The component which is animating + * @return {Number} Returns the updated timeline of the actor + * @private + */ +function rolePlay (t, actor) { + actor = actor || this; + t = t * actor.speed * actor.direction; + + if(actor.delay > 0) { + actor.delay -= t; + } else { + actor.timeline += t; + } + + if(actor.seekInterval !== 0) { + if((actor.seekInterval-actor.timeline)*actor.speed < 0) { + actor.seekInterval = 0; + actor.speed = 0; + } + } + + if (actor.timeline === undefined || actor.timeline < 0) + actor.timeline = 0; + return actor.timeline; +} + +/** + * Returns animation pose index for a particular + * instance of time from the list of + * animations added to the scene. + * @param {number} span - Time span from the animation timeline + * @return {number} - index of the animation + * @private + */ +function animateAtTime (anims, span) { + var startIndex = 0, + stopIndex = anims.length - 1, + middle = Math.floor((stopIndex + startIndex) / 2); + + if (span === 0) { + return startIndex; + } + + while (anims[middle].span != span && startIndex < stopIndex) { + if (span < anims[middle].span) { + stopIndex = middle; + } else if (span > anims[middle].span) { + startIndex = middle + 1; + } + + middle = Math.floor((stopIndex + startIndex) / 2); + } + return (anims[middle].span != span) ? startIndex : middle; +} \ No newline at end of file diff --git a/src/transform.js b/src/transform.js new file mode 100644 index 000000000..7f2f995dc --- /dev/null +++ b/src/transform.js @@ -0,0 +1,731 @@ +require('enyo'); + +/** + * To create a Typed_array + * @param {Number} size The size of the buffer required + * @return {Number[]} Typed_array + */ +function typedArray (size) { + return new Float32Array(new ArrayBuffer(size)); +} + +/** + * To input the specified indices with value 1 + * @param {Number[]} matrix typedArray sent + * @param {Number[]} numberMat indices where value has to be 1 + */ +function inputValues (matrix, numberMat) { + for (var i = 0; i < numberMat.length; i++) { + matrix[numberMat[i]] = 1; + } +} + + +/** + * To translate in any dimension based on co-ordinates. + * @public + * @param {Number} x Translate value in X axis + * @param {Number} y Translate value in Y axis + * @param {Number} z Translate value in Z axis + * @return {Number[]} Matrix3d + */ +exports.translate = function(x, y, z) { + var translateMat, modifiedMat; + translateMat = typedArray(64); + modifiedMat = inputValues(translateMat, new Uint8Array([0, 5, 10, 15])); + translateMat[12] = x; + translateMat[13] = y ? y : 0; + translateMat[14] = z ? z : 0; + return translateMat; +}; + +/** + * To translate in x dimension + * @public + * @param {Number} x Translate value in X axis + * @return {Number[]} Matrix3d + */ +exports.translateX = function(x) { + var translateX, modifiedMat; + translateX = typedArray(64); + modifiedMat = inputValues(translateX, new Uint8Array([0, 5, 10, 15])); + translateX[12] = x ? x : 0; + return translateX; +}; + +/** + * To translate in y dimension + * @public + * @param {Number} y Translate value in Y axis + * @return {Number[]} Matrix3d + */ +exports.translateY = function(y) { + var translateY, modifiedMat; + translateY = typedArray(64); + modifiedMat = inputValues(translateY, new Uint8Array([0, 5, 10, 15])); + translateY[13] = y ? y : 0; + return translateY; +}; + +/** + * To translate in z dimension + * @public + * @param {Number} z Translate value in Z axis + * @return {Number[]} Matrix3d + */ +exports.translateZ = function(z) { + var translateZ, modifiedMat; + translateZ = typedArray(64); + modifiedMat = inputValues(translateZ, new Uint8Array([0, 5, 10, 15])); + translateZ[14] = z ? z : 0; + return translateZ; +}; + +/** + * To scale in any dimension + * @public + * @param {Number} x Scale value in X axis + * @param {Number} y Scale value in Y axis + * @param {Number} z Scale value in Z axis + * @return {Number[]} Matrix3d + */ +exports.scale = function(x, y, z) { + var scaleMat = typedArray(64); + scaleMat[0] = x; + scaleMat[5] = y ? y : 1; + scaleMat[10] = z ? z : 1; + scaleMat[15] = 1; + return scaleMat; +}; + +/** + * To skew in any dimension (skew can only happen in 2d) + * @public + * @param {Number} a Skew value in X axis + * @param {Number} b Skew value in Y axis + * @return {Number[]} Matrix3d + */ +exports.skew =function(a, b) { + var skewMat, modifiedMat; + a = a ? Math.tan(a * Math.PI / 180) : 0; + b = b ? Math.tan(b * Math.PI / 180) : 0; + + skewMat = typedArray(64); + modifiedMat = inputValues(skewMat, new Uint8Array([0, 5, 10, 15])); + skewMat[1] = b; + skewMat[4] = a; + return skewMat; +}; + +/** + * To rotate in x-axis + * @public + * @param {Number} a Rotate value in X axis + * @return {Number[]} Matrix3d + */ +exports.rotateX = function(a) { + var cosa, sina, rotateXMat, modifiedMat; + a = a ? a * Math.PI / 180 : 0; + cosa = Math.cos(a); + sina = Math.sin(a); + + rotateXMat = typedArray(64); + modifiedMat = inputValues(rotateXMat, new Uint8Array([0, 15])); + rotateXMat[5] = cosa; + rotateXMat[6] = -sina; + rotateXMat[9] = sina; + rotateXMat[10] = cosa; + return rotateXMat; +}; + +/** + * To rotate in y-axis + * @public + * @param {Number} b Rotate value in Y axis + * @return {Number[]} Matrix3d + */ +exports.rotateY = function(b) { + var cosb, sinb, rotateYMat, modifiedMat; + b = b ? b * Math.PI / 180 : 0; + cosb = Math.cos(b); + sinb = Math.sin(b); + + rotateYMat = typedArray(64); + modifiedMat = inputValues(rotateYMat, new Uint8Array([5, 15])); + rotateYMat[0] = cosb; + rotateYMat[2] = sinb; + rotateYMat[8] = -sinb; + rotateYMat[10] = cosb; + return rotateYMat; +}; + +/** + * To rotate in z-axis + * @public + * @param {Number} g Rotate value in Z axis + * @return {Number[]} Matrix3d + */ +exports.rotateZ = function(g) { + var cosg, sing, rotateZMat; + g = g ? g * Math.PI / 180 : 0; + cosg = Math.cos(g); + sing = Math.sin(g); + + rotateZMat = typedArray(64); + rotateZMat[0] = cosg; + rotateZMat[1] = -sing; + rotateZMat[4] = sing; + rotateZMat[5] = cosg; + rotateZMat[15] = 1; + return rotateZMat; +}; + +/** + * To rotate in any dimension + * @public + * @param {Number} a Rotate value in X axis + * @param {Number} b Rotate value in Y axis + * @param {Number} g Rotate value in Z axis + * @return {Number[]} Matrix3d + */ +exports.rotate = function(a, b, g) { + var ca, sa, cb, sb, cg, sg, rotateMat; + a = a ? a * Math.PI / 180 : 0; + b = b ? b * Math.PI / 180 : 0; + g = g ? g * Math.PI / 180 : 0; + ca = Math.cos(a); + sa = Math.sin(a); + cb = Math.cos(b); + sb = Math.sin(b); + cg = Math.cos(g); + sg = Math.sin(g); + + rotateMat = typedArray(64); + rotateMat[0] = cb * cg; + rotateMat[1] = ca * sg + sa * sb * cg; + rotateMat[2] = sa * sg - ca * sb * cg; + rotateMat[4] = -cb * sg; + rotateMat[5] = ca * cg - sa * sb * sg; + rotateMat[6] = sa * cg + ca * sb * sg; + rotateMat[8] = sb; + rotateMat[9] = -sa * cb; + rotateMat[10] = ca * cb; + rotateMat[15] = 1; + return rotateMat; +}; + +exports.Matrix = { + + /** + * To create Identity Matrix3d as array. + * @public + * @return {Number[]} Identity Matrix3d + */ + identity: function() { + var identityMatrix, modifiedMat; + identityMatrix = typedArray(64); + modifiedMat = inputValues(identityMatrix, new Uint8Array([0, 5, 10, 15])); + return identityMatrix; + }, + + /** + * To create Identity Matrix2d as array. + * @public + * @return {Number[]} Identity Matrix2d as array + */ + identity2D: function() { + var identity2D, modifiedMat; + identity2D = typedArray(36); + modifiedMat = inputValues(identity2D, new Uint8Array([0, 4, 8])); + return identity2D; + }, + + + /** + * To create Identity Matrix (NXN order). + * @public + * @param {Number} N Order of Identity Matrix + * @return {Number[][]} Identity Matrix of order N + */ + identityMatrix: function(N) { + var i, j, row, result = []; + for (i = 0; i < N; i++) { + row = []; + for (j = 0; j < N; j++) { + if (i === j) { + row.push(1); + } else { + row.push(0); + } + } + result.push(row); + } + return result; + }, + /** + * To multiply 2 Martix3d (4x4 order) + * @public + * @param {Number[]} m1 1st Matrix3d + * @param {Number[]} m2 2nd Matrix3d + * @return {Number[]} Resultant Matrix3d + */ + multiply: function(m1, m2) { + if (m1.length !== 16 || m2.length !== 16) return; + var multiplyMat = typedArray(64); + multiplyMat[0] = m1[0] * m2[0] + m1[4] * m2[1] + m1[8] * m2[2]; + multiplyMat[1] = m1[1] * m2[0] + m1[5] * m2[1] + m1[9] * m2[2]; + multiplyMat[2] = m1[2] * m2[0] + m1[6] * m2[1] + m1[10] * m2[2]; + multiplyMat[4] = m1[0] * m2[4] + m1[4] * m2[5] + m1[8] * m2[6]; + multiplyMat[5] = m1[1] * m2[4] + m1[5] * m2[5] + m1[9] * m2[6]; + multiplyMat[6] = m1[2] * m2[4] + m1[6] * m2[5] + m1[10] * m2[6]; + multiplyMat[8] = m1[0] * m2[8] + m1[4] * m2[9] + m1[8] * m2[10]; + multiplyMat[9] = m1[1] * m2[8] + m1[5] * m2[9] + m1[9] * m2[10]; + multiplyMat[10] = m1[2] * m2[8] + m1[6] * m2[9] + m1[10] * m2[10]; + multiplyMat[12] = m1[0] * m2[12] + m1[4] * m2[13] + m1[8] * m2[14] + m1[12]; + multiplyMat[13] = m1[1] * m2[12] + m1[5] * m2[13] + m1[9] * m2[14] + m1[13]; + multiplyMat[14] = m1[2] * m2[12] + m1[6] * m2[13] + m1[10] * m2[14] + m1[14]; + multiplyMat[15] = 1; + return multiplyMat; + }, + + /** + * To multiply 2 Martix3d (n*n order) + * @param {Number[]} m1 1st Matrix3d + * @param {Number[]} m2 2nd Matrix3d + * @return {[type]} Resultant Matrix3d + */ + multiplyN: function(m1, m2) { + var i, j, sum, + m = [], + l1 = m1.length, + l2 = m2.length; + + for (i = 0; i < l1; i++) { + sum = 0; + for (j = 0; j < l2; j++) { + sum += m1[i][j] * m2[j]; + } + m.push(sum); + } + return m; + }, + + /** + * To inverse matrix of order N + * @public + * @param {Number[]} matrix Matrix (NxN order) + * @param {Number} n Order of the matrix + * @return {Number[]} Inverted Matrix + */ + inverseN: function(matrix, n) { + var i, j, k, r, t, + result = this.identityMatrix(n); + + for (i = 0; i < n; i++) { + for (j = 0; j < n; j++) { + if (i != j) { + r = matrix[j][i] / matrix[i][i]; + for (k = 0; k < n; k++) { + matrix[j][k] -= r * matrix[i][k]; + result[j][k] -= r * result[i][k]; + } + } + } + } + + for (i = 0; i < n; i++) { + t = matrix[i][i]; + for (j = 0; j < n; j++) { + matrix[i][j] = matrix[i][j] / t; + result[i][j] = result[i][j] / t; + } + } + + return result; + }, + + /** + * Calculate matrix3d of a frame based on transformation vectors. + * @public + * @param {Number[]} trns Translate vector + * @param {Number[]} rot Rotate quaternion vector + * @param {Number[]} sc Scale vector + * @param {Number[]} sq Skew vector + * @param {Number[]} per Perspective vector + * @return {Number[]} Final Matrix3d for particular frame + */ + recompose: function(trns, rot, sc, sq, per) { + var i, + x = rot[0], + y = rot[1], + z = rot[2], + w = rot[3], + m = this.identity(), + sM = this.identity(), + rM = this.identity(); + + + // apply perspective + if (per) { + m[3] = per[0]; + m[7] = per[1]; + m[11] = per[2]; + m[15] = per[3]; + } + + m[12] = trns[0]; + m[13] = trns[1]; + m[14] = trns[2]; + + // apply rotate + rM[0] = 1 - 2 * (y * y + z * z); + rM[1] = 2 * (x * y - z * w); + rM[2] = 2 * (x * z + y * w); + rM[4] = 2 * (x * y + z * w); + rM[5] = 1 - 2 * (x * x + z * z); + rM[6] = 2 * (y * z - x * w); + rM[8] = 2 * (x * z - y * w); + rM[9] = 2 * (y * z + x * w); + rM[10] = 1 - 2 * (x * x + y * y); + + m = this.multiply(m, rM); + + // apply skew + if (sq[2]) { + sM[9] = sq[2]; + m = this.multiply(m, sM); + } + + if (sq[1]) { + sM[9] = 0; + sM[8] = sq[1]; + m = this.multiply(m, sM); + } + + if (sq[0]) { + sM[8] = 0; + sM[4] = sq[0]; + m = this.multiply(m, sM); + } + + // apply scale + for (i = 0; i < 12; i += 4) { + m[0 + i] *= sc[0]; + m[1 + i] *= sc[1]; + m[2 + i] *= sc[2]; + } + return m; + }, + + /** + * Decompose transformation vectors into various properties out of matrix3d. + * @public + * @param {Number[]} matrix Matrix3d + * @param {Object} ret To store various transformation properties like translate, rotate, scale, skew and perspective. + * @return {Boolean} true, if matrix exists else false. + */ + decompose: function(matrix, ret) { + if (matrix[15] === 0) return false; + var i, + tV = [], + rV = [], + pV = [], + skV = [], + scV = [], + row = [], + pdum3 = []; + + for (i = 0; i < 16; i++) + matrix[i] /= matrix[15]; + + //TODO: decompose perspective + pV = [0, 0, 0, 0]; + + for (i = 0; i < 3; i++) + tV[i] = matrix[12 + i]; + + for (i = 0; i < 12; i += 4) { + row.push([ + matrix[0 + i], + matrix[1 + i], + matrix[2 + i] + ]); + } + + scV[0] = vector.len(row[0]); + row[0] = quaternion.normalize(row[0]); + skV[0] = vector.dot(row[0], row[1]); + row[1] = vector.combine(row[1], row[0], 1.0, -skV[0]); + + scV[1] = vector.len(row[1]); + row[1] = quaternion.normalize(row[1]); + skV[0] /= scV[1]; + + // Compute XZ and YZ shears, orthogonalized 3rd row + skV[1] = vector.dot(row[0], row[2]); + row[2] = vector.combine(row[2], row[0], 1.0, -skV[1]); + skV[2] = vector.dot(row[1], row[2]); + row[2] = vector.combine(row[2], row[1], 1.0, -skV[2]); + + // Next, get Z scale and normalize 3rd row. + scV[2] = vector.len(row[2]); + row[2] = quaternion.normalize(row[2]); + skV[1] /= scV[2]; + skV[2] /= scV[2]; + + pdum3 = vector.cross(row[1], row[2]); + if (vector.dot(row[0], pdum3) < 0) { + for (i = 0; i < 3; i++) { + scV[i] *= -1; + row[i][0] *= -1; + row[i][1] *= -1; + row[i][2] *= -1; + } + } + + rV[0] = 0.5 * Math.sqrt(Math.max(1 + row[0][0] - row[1][1] - row[2][2], 0)); + rV[1] = 0.5 * Math.sqrt(Math.max(1 - row[0][0] + row[1][1] - row[2][2], 0)); + rV[2] = 0.5 * Math.sqrt(Math.max(1 - row[0][0] - row[1][1] + row[2][2], 0)); + rV[3] = 0.5 * Math.sqrt(Math.max(1 + row[0][0] + row[1][1] + row[2][2], 0)); + + if (row[2][1] > row[1][2]) rV[0] = -rV[0]; + if (row[0][2] > row[2][0]) rV[1] = -rV[1]; + if (row[1][0] > row[0][1]) rV[2] = -rV[2]; + + ret.translate = tV; + ret.rotate = rV; + ret.scale = scV; + ret.skew = skV; + ret.perspective = pV; + return true; + }, + + /** + * Decompose transformation matrix2d from matrix3d. + * @public + * @param {Number[]} matrix Matrix3d + * @param {Object} ret To store various transformation properties like translate, angle and matrix. + * @return {Boolean} ret To store various transformation properties like translate, angle and matrix. + */ + decompose2D: function(m, ret) { + var scale = [], + matrix = [], + row0x = m[0], + row0y = m[1], + row1x = m[4], + row1y = m[5], + det, angle, sn, cs, + m11, m12, m21, m22; + + ret = ret || {}; + scale = [ + Math.sqrt(row0x * row0x + row0y * row0y), + Math.sqrt(row1x * row1x + row1y * row1y) + ]; + + // If determinant is negative, one axis was flipped. + det = row0x * row1y - row0y * row1x; + if (det < 0) + // Flip axis with minimum unit vector dot product. + if (row0x < row1y) + scale[0] = -scale[0]; + else + scale[1] = -scale[1]; + + // Renormalize matrix to remove scale. + if (scale[0]) { + row0x *= 1 / scale[0]; + row0y *= 1 / scale[0]; + } + + if (scale[1]) { + row1x *= 1 / scale[1]; + row1y *= 1 / scale[1]; + } + ret.scale = scale; + + + // Compute rotation and renormalize matrix. + angle = Math.atan2(row0y, row0x); + + if (angle) { + sn = -row0y; + cs = row0x; + m11 = row0x; + m12 = row0y; + m21 = row1x; + m22 = row1y; + row0x = cs * m11 + sn * m21; + row0y = cs * m12 + sn * m22; + row1x = -sn * m11 + cs * m21; + row1y = -sn * m12 + cs * m22; + } + + // Rotate(-angle) = [cos(angle), sin(angle), -sin(angle), cos(angle)] + // = [row0x, -row0y, row0y, row0x] + // Thanks to the normalization above. + matrix[0] = row0x; + matrix[1] = row0y; + matrix[2] = row1x; + matrix[3] = row1y; + matrix[4] = m[12]; + matrix[5] = m[13]; + ret.matrix2D = matrix; + + // Convert into degrees because our rotation functions expect it. + ret.angle = angle * 180 / Math.PI; + + return ret; + }, + + /** + * Convert Matrix3d array to Matrix3d String + * @public + * @param {Number[]} m Matrix3d Array + * @return {String} Matrix3d String + */ + toString: function(m) { + var i, ms = m.length > 10 ? 'matrix3d(' : 'matrix('; + for (i = 0; i < m.length - 1; i++) { + ms += (m[i] < 0.000001 && m[i] > -0.000001) ? '0,' : m[i] + ','; + } + ms += m[m.length - 1] + ')'; + return ms; + } +}; + +var vector = exports.Vector = { + /** + * Length of a vector + * @param {Number[]} v - vector + * @return {Number} resultant length + * @public + */ + len: function(v) { + return Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); + }, + + /** + * Divides vector with a scalar value. + * @param {Number[]} v - vector + * @param {Number} s - scalar value to divide + * @return {Number[]} resultant vector + * @public + */ + divide: function(v, s) { + var divideVector = new Float32Array([v[0] / s, v[1] / s, v[2] / s]); + return divideVector; + }, + + /** + * Dot product of 3D vectors + * @param {Number[]} v1 - vector + * @param {Number[]} v2 - vector + * @return {Number} resultant dot product + * @public + */ + dot: function(v1, v2) { + return (v1[0] * v2[0]) + (v1[1] * v2[1]) + (v1[2] * v2[2]) + (v1[3] !== undefined && v2[3] !== undefined ? (v1[3] * v2[3]) : 0); + }, + + /** + * Cross product of two vectors + * @param {Number[]} v1 - vector + * @param {Number[]} v2 - vector + * @return {Number[]} resultant cross product + * @public + */ + cross: function(v1, v2) { + var crossProdMat = new Float32Array([v1[1] * v2[2] - v1[2] * v2[1], v1[2] * v2[0] - v1[0] * v2[2], v1[0] * v2[1] - v1[1] * v2[0]]); + return crossProdMat; + }, + + /** + * Combine scalar values with two vectors. + * Required during parsing scaler values matrix. + * @param {Number[]} a - first vector + * @param {Number[]} b - second vector + * @param {Number[]} ascl - first vector scalar + * @param {Number[]} bscl - second vector scalar + * @return {Number[]} resultant vector + * @public + */ + combine: function(a, b, ascl, bscl) { + var combineMat = new Float32Array([(ascl * a[0]) + (bscl * b[0]), (ascl * a[1]) + (bscl * b[1]), (ascl * a[2]) + (bscl * b[2])]); + return combineMat; + + } +}; + +var quaternion = exports.Quaternion = { + /** + * Gives the direction of motion from one vector to other. + * Returns true if moving towards positive direction. + * @param {Number[]} q1 - quant + * @param {Number[]} q2 - quant + * @return {boolean} true if positive, false otherwise. + * @public + */ + direction: function(q1, q2) { + return (q1[0] - q2[0]) < 0 || (q1[1] - q2[1]) < 0 || (q1[2] - q2[2]) < 0; + }, + + /** + * Dot product of 3D quanterion + * @param {Number[]} q1 - quanterion + * @param {Number[]} q2 - quanterion + * @return {Number} resultant dot product + * @public + */ + quantDot: function(q1, q2) { + return (q1[0] * q2[0]) + (q1[1] * q2[1]) + (q1[2] * q2[2]) + (q1[3] * q2[3]); + }, + + multiplication: function(q1, q2) { + return [q2[0] * q1[0] - q2[1] * q1[1] - q2[2] * q1[2] - q2[3] * q1[3], + q2[0] * q1[1] + q2[1] * q1[0] - q2[2] * q1[3] + q2[3] * q1[2], + q2[0] * q1[2] + q2[1] * q1[3] + q2[2] * q1[0] - q2[3] * q1[1], + q2[0] * q1[3] - q2[1] * q1[2] + q2[2] * q1[1] + q2[3] * q1[0]]; + }, + + /** + * Normalizing a vector is obtaining another unit vector in the same direction. + * To normalize a vector, divide the vector by its magnitude. + * @param {Number[]} q1 - quanterion + * @return {Number[]} resultant quanterion + * @public + */ + normalize: function(q) { + return vector.divide(q, vector.len(q)); + }, + + /** + * Converts a rotation vector to a quaternion vector. + * @param {Number[]} v - vector + * @return {Number[]} resultant quaternion + * @public + */ + toQuant: function(v) { + if (!v) v = []; + var p = parseFloat(v[1] || 0) * Math.PI / 360, + y = parseFloat(v[2] || 0) * Math.PI / 360, + r = parseFloat(v[0] || 0) * Math.PI / 360, + c1 = Math.cos(p), + c2 = Math.cos(y), + c3 = Math.cos(r), + s1 = Math.sin(p), + s2 = Math.sin(y), + s3 = Math.sin(r), + q; + + q = new Float32Array([ + Math.round((s1 * s2 * c3 + c1 * c2 * s3) * 100000) / 100000, + Math.round((s1 * c2 * c3 + c1 * s2 * s3) * 100000) / 100000, + Math.round((c1 * s2 * c3 - s1 * c2 * s3) * 100000) / 100000, + Math.round((c1 * c2 * c3 - s1 * s2 * s3) * 100000) / 100000 + ]); + + return q; + } + //TODO: Acheive the same fucntionality for other 11 choices XYX, XZX, XZY, YXY, YXZ, YZX, YZY, ZXY, ZXZ, ZYX, ZYZ +}; \ No newline at end of file diff --git a/src/tween.js b/src/tween.js new file mode 100644 index 000000000..c52129aef --- /dev/null +++ b/src/tween.js @@ -0,0 +1,702 @@ +require('enyo'); + +var + dom = require('./dom'), + utils = require('./utils'), + transform = require('./transform'); + + +var fn, state, ease, points, path, oldState, newState, node, matrix, cState = [], + domCSS = {}; +/** + * Tween is a module responsible for creating intermediate frames for an animation. + * The responsibilities of this module is to; + * - Interpolating current state of character. + * - Update DOM based on current state, using matrix for tranform and styles for others. + * + * @module enyo/tween + */ +module.exports = { + + /** + * @private + */ + init: function(actor, pose, initial) { + if (!(actor && pose && pose.animate)) return; + node = actor.hasNode(); + utils.mixin(pose, getAnimatedProperty(node, pose.animate, initial || actor.currentState)); + actor.currentState = pose.currentState; + return pose; + }, + + /** + * Step represents state of the actor at any point of time in the animation. + * @param {Object} actor - Element to be animated + * @param {Object} pose - Current behavior in the animation (at a given time) + * @param {Number} t - Fraction which represents the animation (between 0 to 1) + * @param {Number} d - Duration of the current pose + * @memberOf module:enyo/tween + * @private + */ + step: function(actor, pose, t, d) { + if (!(actor && pose && pose.animate)) return; + t = t < 0 ? 0 : t; + t = t > 1 ? 1 : t; + + var k; + domCSS = {}; + node = actor.hasNode(); + state = actor.currentState = actor.currentState || pose.currentState || {}; + points = pose.controlPoints = pose.controlPoints || {}; + ease = pose.animate && pose.animate.ease ? pose.animate.ease : this.ease; + path = pose.animate && pose.animate.path; + + if (pose.props) { + for (k in pose.props) { + if (!pose._endAnim[k] || k === 'duration' || k === 'ease') { + continue; + } + + cState = utils.clone(state[k] || []); + newState = pose._endAnim[k].slice(); + oldState = pose._startAnim[k].slice(); + + if (ease && (typeof ease !== 'function')) { + if (k == 'rotate') { + points[k] = points[k] || + this.bezierSPoints(ease, oldState, newState, pose.props[k], points[k]); + fn = this.bezierSpline; + } else { + points[k] = points[k] || + this.bezierPoints(ease, oldState, newState, points[k]); + fn = this.bezier; + } + cState = fn.call(this, t, points[k], cState); + } else { + fn = (k === 'rotate') ? this.slerp : this.lerp; + cState = fn.call(this, oldState, newState, ease(t, d), cState); + } + + if (!isTransform(k)) { + domCSS = toPropertyValue(k, cState, domCSS); + } + state[k] = cState; + } + } else { + utils.mixin(state, oldState); + } + + //TODO: Support for properties other than translate + if (path) { + this.traversePath(t, path, state.translate); + } + + matrix = transform.Matrix.recompose( + state.translate, + state.rotate, + state.scale, + state.skew, + state.perspective + ); + state.matrix = matrix; + actor.currentState = pose.currentState = state; + domCSS = toTransformValue(matrix, domCSS); + + actor.addStyles(domCSS); + }, + + halt: function(actor, pose) { + var matrix = actor.currentState && actor.currentState.matrix; + + pose = transform.Matrix.decompose2D(matrix); + domCSS = toTransformValue(pose.matrix2D); + actor.addStyles(domCSS); + }, + + /** + * Overridden function for applying the default ease. + * @param {Number} t - Fraction which represents the animation (between 0 to 1) + * @return {Number} t + * @memberOf module:enyo/AnimationSupport/Tween + * @private + * @override + */ + ease: function(t) { + return t; + }, + + /** + * Draws linear interpolation between two values. + * @param {Number[]} vA - origin vector + * @param {Number[]} vB - Destination vector + * @param {Number} t - Fraction which represents the animation (between 0 to 1) + * @param {Number[]} vR - Resultant vector + * @return {Number[]} vR + * @memberOf module:enyo/AnimationSupport/Tween + * @private + */ + lerp: function(vA, vB, t, vR) { + if (!vA) return; + if (!vR) vR = []; + var i, l = vA.length; + + for (i = 0; i < l; i++) { + vR[i] = (1 - t) * vA[i] + t * vB[i]; + } + return vR; + }, + + /** + * Draws sperical linear interpolation between two values. + * @param {Number[]} qA Quaternion origin + * @param {Number[]} qB - Quaternion destination + * @param {Number} t - Fraction which represents the animation (between 0 to 1) + * @param {Number[]} qR - Resultant quaternion + * @return {Number[]} qR + * @memberOf module:enyo/AnimationSupport/Tween + * @private + */ + slerp: function(qA, qB, t, qR) { + if (!qA) return; + if (!qR) qR = []; + var a, + b, + theta, + dot = transform.Quaternion.quantDot(qA, qB), + l = qA.length; + + dot = Math.min(Math.max(dot, -1.0), 1.0); + if (dot == 1.0) { + qR = utils.cloneArray(qA); + return qR; + } + theta = Math.acos(dot); + for (var i = 0; i < l; i++) { + a = (Math.sin((1 - t) * theta) / Math.sin(theta)) * qA[i]; + b = (Math.sin(t * theta) / Math.sin(theta)) * qB[i]; + qR[i] = a + b; + } + return qR; + }, + + /** + * Creates bezier curve path for animation. + * @param {Number} t - Fraction which represents the animation (between 0 to 1) + * @param {Number[]} points - knot and control points + * @param {Number[]} vR - Resulting points + * @return {Number[]} vR + * @memberOf module:enyo/AnimationSupport/Tween + */ + bezier: function(t, points, vR) { + if (!points) return; + if (!vR) vR = []; + + var i, j, + c = points.length, + l = points[0].length, + lastIndex = (c - 1), + startPoint = points[0], + endPoint = points[lastIndex], + values = this.getBezierValues(t, lastIndex); + + for (i = 0; i < l; i++) { + vR[i] = 0; + for (j = 0; j < c; j++) { + if ((j > 0) && (j < (c - 1))) { + vR[i] = vR[i] + ((startPoint[i] + (points[j][i] * (endPoint[i] - startPoint[i]))) * values[j]); + } else { + vR[i] = vR[i] + (points[j][i] * values[j]); + } + } + } + return vR; + }, + + /** + * Returns the control points for bezier curve. + * @param {Object} easeObj- The easing object with values. + * @param {Number[]} startPoint - Starting point of the curve + * @param {Number[]} endPoint - End point of the curve + * @param {Number[]} points - control points + * @return {Number[]} points + * @memberOf module:enyo/AnimationSupport/Tween + */ + bezierPoints: function(easeObj, startPoint, endPoint, points) { + if (!easeObj) return; + var order = (easeObj && Object.keys(easeObj).length) ? (Object.keys(easeObj).length + 1) : 0; + var bValues = [], + m1 = [], + m2 = [], + m3 = [], + m4 = [], + l = 0; + points = [startPoint]; + + var t, a; + for (var key in easeObj) { + t = parseFloat(key) / 100; + a = parseFloat(easeObj[key]) / 100; + bValues = this.getBezierValues(t, order); + bValues.shift(); + m1.push(a - bValues.pop()); + m2.push(bValues); + } + + m3 = transform.Matrix.inverseN(m2, bValues.length); + m4 = transform.Matrix.multiplyN(m3, m1); + l = m4.length; + for (var i = 0; i < l; i++) { + var pValues = []; + for (var j = 0; j < endPoint.length; j++) { + pValues.push(m4[i]); + } + points.push(pValues); + } + + points.push(endPoint); + return points; + }, + + /** + * Traverses the path of the animation + * @param {Number} t - Fraction which represents the animation (between 0 to 1) + * @param {Number[]} path - Array of points + * @param {Number[]} vR Resulatant Array + * @return {Number[]} vR + * @memberOf module:enyo/AnimationSupport/Tween + */ + traversePath: function(t, path, vR) { + if (!path) return; + if (!vR) vR = []; + + var i, j, + c = path.length, + l = path[0].length, + lastIndex = (c - 1), + values = this.getBezierValues(t, lastIndex); + + for (i = 0; i < l; i++) { + vR[i] = 0; + for (j = 0; j < c; j++) { + vR[i] = vR[i] + (path[j][i] * values[j]); + } + } + return vR; + }, + + /** + * Returns the control points for bezier spline. + * @param {Object} ease- The easing object with values. + * @param {Number[]} startQuat - Quaternion origin + * @param {Number[]} endQuat - Quaternion destination + * @param {Number[]} endPoint - Final Destination point + * @param {Number[]} splinePoints - spline control points + * @return {Number[]} splinePoints + * @memberOf module:enyo/AnimationSupport/Tween + */ + bezierSPoints: function(ease, startQuat, endQuat, endPoint, splinePoints) { + if (!ease) return; + var time = [0], + quats = [startQuat]; + + var a, n, _a, aI, bN, eP, key, i, j, + eD = formatCSSValues(endPoint); + + splinePoints = splinePoints || {}; + if (Object.keys(ease).length > 0) { + for (key in ease) { + eP = utils.clone(eD); + a = parseFloat(ease[key]) / 100; + for (i in eP) { + eP[i] *= a; + } + quats.push(transform.Quaternion.toQuant(eP)); + time.push(parseFloat(key) / 100); + } + quats.push(endQuat); + time.push(1); + n = quats.length - 1; + aI = this.slerp(startQuat, endQuat, 0); + splinePoints[0] = [quats[0], aI, aI, quats[1]]; + for (i = 0, j = 1; i < n; i++, j++) { + if (i === 0) { + aI = this.slerp(quats[0], this.slerp(quats[2], quats[1], 2.0), 1.0 / 3); + } else { + _a = this.slerp(this.slerp(quats[i - 1], quats[i], 2.0), quats[i + 1], 0.5); + aI = this.slerp(quats[j], _a, 1.0 / 3); + } + if (j === n) { + bN = this.slerp(quats[j], this.slerp(quats[j - 2], quats[j - 1], 2.0), 1.0 / 3); + } else { + _a = this.slerp(this.slerp(quats[j - 1], quats[j], 2.0), quats[j + 1], 0.5); + bN = this.slerp(quats[j], _a, -1.0 / 3); + } + splinePoints[time[j]] = [quats[i], aI, bN, quats[i + 1]]; + } + } + return splinePoints; + }, + + /** + * Creates bezier spline path for animation. + * @param {Number} t - Fraction which represents the animation (between 0 to 1) + * @param {Number[]} points - knot and control points + * @param {Number[]} vR - Resulting points + * @return {Number[]} vR + * @memberOf module:enyo/AnimationSupport/Tween + */ + bezierSpline: function(t, points, vR) { + if (!points) return; + if (!vR) vR = []; + var Q0, Q1, Q2, R0, R1, + p, key, pts; + for (p in points) { + if (p >= t) { + key = p; + break; + } + } + pts = points[key]; + + if (pts.length >= 4) { + Q0 = this.slerp(pts[0], pts[1], t); + Q1 = this.slerp(pts[1], pts[2], t); + Q2 = this.slerp(pts[2], pts[3], t); + R0 = this.slerp(Q0, Q1, t); + R1 = this.slerp(Q1, Q2, t); + vR = this.slerp(R0, R1, t); + } else + vR = this.slerp(pts[0], pts[1], t); + return vR; + }, + + /** + * This function returns the coefficents based on the order and the current position + * @private + * @param {number} n - order + * @param {number} k - current position + * @return {object} - coefficients + */ + getCoeff: function(n, k) { + n = parseInt(n, 10); + k = parseInt(k, 10); + // Credits + // https://math.stackexchange.com/questions/202554/how-do-i-compute-binomial-coefficients-efficiently#answer-927064 + if (isNaN(n) || isNaN(k)) + return void 0; + if ((n < 0) || (k < 0)) + return void 0; + if (k > n) + return void 0; + if (k === 0) + return 1; + if (k === n) + return 1; + if (k > n / 2) + return this.getCoeff(n, n - k); + + return n * this.getCoeff(n - 1, k - 1) / k; + }, + + /** + * Function to get the bezier coeffients based on the time and order + * @public + * @param {number} t - time + * @param {number} n - order + * @return {object} - bezier coefficients + */ + getBezierValues: function(t, n) { + t = parseFloat(t, 10), + n = parseInt(n, 10); + + if (isNaN(t) || isNaN(n)) + return void 0; + if ((t < 0) || (n < 0)) + return void 0; + if (t > 1) + return void 0; + + var c, + values = [], + + x = (1 - t), + y = t; + // + // Binomial theorem to expand (x+y)^n + // + for (var k = 0; k <= n; k++) { + c = this.getCoeff(n, k) * Math.pow(x, (n - k)) * Math.pow(y, k); + values.push(c); + } + + return values; + } +}; + +/** + * Get DOM node animation properties. + * @public + * @param {HTMLElement} node DOM node + * @param {Object} props Properties to fetch from DOM. + * @param {Object} initial Default properties to be applied. + * @return {Object} Object with various animation properties. + */ +function getAnimatedProperty(node, props, initial) { + if (!node) return; + + var eP = {}, + sP = initial ? utils.mixin({}, initial) : {}, + tP = {}, + dP = {}, + m, k, v, t, + s = initial ? undefined : dom.getComputedStyle(node); + + for (k in props) { + v = sP[k]; + if (!isTransform(k)) { + v = v || getStyleValue(s || dom.getComputedStyle(node), k); + sP[k] = formatCSSValues(v, k); + eP[k] = formatCSSValues(props[k], k, sP[k] ? sP[k].length : sP[k]); + } else { + v = formatTransformValues(props[k], k); + if (k.match(/rotate/)) { + v = transform.Quaternion.toQuant(v); + tP.rotate = tP.rotate ? transform.Quaternion.multiplication(tP.rotate, v) : v; + } else { + t = k.replace(/[XYZ]$/, ''); + tP[t] = tP[t] ? tP[t].map(function(num, id) { + return num + v[id]; + }) : v; + } + if (k.match(/[XYZ]$/)) { + t = k.replace(/[XYZ]$/, ''); + props[t] = tP[t].join(); + delete props[k]; + } + } + } + + if (initial) { + dP.translate = initial.translate; + dP.rotate = initial.rotate.length < 4 ? transform.Quaternion.toQuant(initial.rotate) : initial.rotate; + dP.scale = initial.scale; + dP.skew = initial.skew; + dP.perspective = initial.perspective; + } else { + m = getStyleValue(s || dom.getComputedStyle(node), dom.getCssTransformProp()); + m = formatTransformValues(m, 'matrix'); + transform.Matrix.decompose(m, dP); + } + + for (k in dP) { + sP[k] = dP[k]; + eP[k] = tP[k] || dP[k]; + } + return { + _startAnim: sP, + _endAnim: eP, + _transform: dP, + currentState: dP, + matrix: m, + props: props + }; +} + + +/** + * Converts comma separated values to array. + * @public + * @param {String} val Value of required animation in any property. + * @param {Number} length [description] + * @param {[type]} prop [description] + * @return {Number[]} Create array from val. + */ +function formatCSSValues(val, prop, length) { + var res; + if (typeof val === 'function') { + return val; + } + if (SHADOW[prop] || COLOR[prop]) { + if (val === 'none') { + return Array(7).fill(0); + } + if (val.indexOf('rgb') === 0) { + res = stringToMatrix(val.split(')')[0].replace(/^\w*\(/, '').concat(val.split(')')[1].split(' ').join())); + } else { + res = stringToMatrix(val.split('rgb(')[1].replace(')', ',').concat(val.split('rgb(')[0]).replace(/, $/, '')); + } + } + if (prop === 'duration') { + return 0; + } + return length ? res.concat(Array(length - res.length).fill(0)) : res; +} + +function formatTransformValues(val, prop) { + var res; + switch (prop) { + case 'translateX': + case 'rotateX': + case 'skewX': + return [parseFloat(val, 10), 0, 0]; + case 'translateY': + case 'rotateY': + case 'skewY': + return [0, parseFloat(val, 10), 0]; + case 'translateZ': + case 'rotateZ': + return [0, 0, parseFloat(val, 10)]; + case 'scaleX': + return [parseFloat(val, 10), 1, 1]; + case 'scaleY': + return [1, parseFloat(val, 10), 1]; + case 'scaleZ': + return [1, 1, parseFloat(val, 10)]; + case 'matrix': + res = transform.Matrix.identity(); + val = stringToMatrix(val.replace(/^\w*\(/, '').replace(')', '')); + if (val.length <= 6) { + res[0] = val[0]; + res[1] = val[1]; + res[4] = val[2]; + res[5] = val[3]; + res[12] = val[4]; + res[13] = val[5]; + } + if (val.length == 16) { + res = val; + } + return res; + default: + return stringToMatrix(val); + } +} + +/** + * Validates if property is a transform property. + * @public + * @param {String} transform Any transform property, for which we want to identify whether or not the property is transform. + * @return {Number} Value of the required transform property. + */ +function isTransform(transform) { + return TRANSFORM[transform]; +} + +function stringToMatrix(val) { + if (!val || val === "auto" || val === 'none') { + return 0; + } + return val.toString().split(",").map(function(v) { + return parseFloat(v, 10); + }); +} + +function toPropertyValue(prop, val, ret) { + if (!val) return; + ret = ret || {}; + if (COLOR[prop]) { + val = val.map(function(v) { + return parseInt(v, 10); + }); + val = 'rgb(' + val + ')'; + } else if (INT_UNIT[prop]) { + val = parseInt(val[0], 10); + } else if (BORDER[prop]) { + val = val[0] + '%'; + } else if (OPACITY[prop]) { + val = val[0].toFixed(6); + val = (val <= 0) ? '0.000001' : val; + } else if (SHADOW[prop]) { + val = 'rgb(' + val.slice(0, 3).map(function(v) { + return parseInt(v, 10); + }) + ') ' + val.slice(3).map(function(v) { + return v + 'px' + }).join(' '); + } else { + val = val[0] + 'px'; + } + + ret[prop] = val; + return ret; +} + + +/** +* @private +*/ +function toTransformValue (matrix, ret) { + var mat = transform.Matrix.toString(matrix), + key = dom.getStyleTransformProp(); + + ret = ret || {}; + ret[key] = mat; + return ret; +} + + +/** + * Gets a style property applied from the DOM element. + * @public + * @param {HTMLElement} style Computed style of a DOM. + * @param {String} key Property name for which style has to be fetched. + * @return {Number|HTMLElement} + */ +function getStyleValue(style, key) { + return style.getPropertyValue(key) || style[key]; +} + +var + BORDER = { + 'border-radius': 1, + 'border-image-slice': 1, + 'border-top-left-radius': 1, + 'border-top-right-radius': 1, + 'border-bottom-left-radius': 1, + 'border-bottom-right-radius': 1 + }, + COLOR = { + 'color': 1, + 'fill': 1, + 'stop-color': 1, + 'flood-color': 1, + 'border-color': 1, + 'outline-color': 1, + 'lighting-color': 1, + 'border-top-color': 1, + 'background-color': 1, + 'border-left-color': 1, + 'border-right-color': 1, + 'border-bottom-color': 1 + }, + INT_UNIT = { + 'z-index': 1 + }, + SHADOW = { + 'box-shadow': 1, + 'text-shadow': 1 + }, + OPACITY = { + 'opacity': 1, + 'flood-opacity': 1, + 'stop-opacity': 1, + 'fill-opacity': 1, + 'stroke-opacity': 1 + }, + TRANSFORM = { + translate: 1, + translateX: 1, + translateY: 1, + translateZ: 1, + rotate: 1, + rotateX: 1, + rotateY: 1, + rotateZ: 1, + skew: 1, + skewX: 1, + skewY: 1, + scale: 1, + scaleX: 1, + scaleY: 1, + scaleZ: 1, + perspective: 1 + }; \ No newline at end of file From cbe98496a32911835e4bc525ea5ae7aa71fa5277 Mon Sep 17 00:00:00 2001 From: Anish_Ramesan Date: Fri, 13 May 2016 19:51:42 +0530 Subject: [PATCH 02/32] travis fixes Enyo-DCO-1.1-Signed-off-by: Anish Ramesan --- src/easing.js | 744 ++++++++++++++-------------- src/transform.js | 1212 +++++++++++++++++++++++----------------------- src/tween.js | 13 +- 3 files changed, 987 insertions(+), 982 deletions(-) diff --git a/src/easing.js b/src/easing.js index e6dd104cb..0f991ebfb 100644 --- a/src/easing.js +++ b/src/easing.js @@ -4,405 +4,405 @@ */ var easing = module.exports = { - /** - * linear - * - * @public - */ - linear: function(n) { - return n; - }, - /** - * cubicIn - * - * @public - */ - cubicIn: function(n) { - return Math.pow(n, 3); - }, - /** - * cubicOut - * - * @public - */ - cubicOut: function(n) { - return Math.pow(n - 1, 3) + 1; - }, - /** - * expoOut - * - * @public - */ - expoOut: function(n) { - return (n == 1) ? 1 : (-1 * Math.pow(2, -10 * n) + 1); - }, - /** - * quadInOut - * - * @public - */ - quadInOut: function(n) { - n = n * 2; - if (n < 1) { - return Math.pow(n, 2) / 2; - } - return -1 * ((--n) * (n - 2) - 1) / 2; - }, + /** + * linear + * + * @public + */ + linear: function(n) { + return n; + }, + /** + * cubicIn + * + * @public + */ + cubicIn: function(n) { + return Math.pow(n, 3); + }, + /** + * cubicOut + * + * @public + */ + cubicOut: function(n) { + return Math.pow(n - 1, 3) + 1; + }, + /** + * expoOut + * + * @public + */ + expoOut: function(n) { + return (n == 1) ? 1 : (-1 * Math.pow(2, -10 * n) + 1); + }, + /** + * quadInOut + * + * @public + */ + quadInOut: function(n) { + n = n * 2; + if (n < 1) { + return Math.pow(n, 2) / 2; + } + return -1 * ((--n) * (n - 2) - 1) / 2; + }, - /** - * EaseInQuad - * @public - * @param {number} t - current time - * @return {number} - calculated time - */ - easeInQuad: function(t) { - return t * t; - }, + /** + * EaseInQuad + * @public + * @param {number} t - current time + * @return {number} - calculated time + */ + easeInQuad: function(t) { + return t * t; + }, - /** - * EaseOutQuad - * @public - * @param {number} t - current time - * @return {number} calculated time - */ - easeOutQuad: function(t) { - return -1 * t * (t - 2); - }, + /** + * EaseOutQuad + * @public + * @param {number} t - current time + * @return {number} calculated time + */ + easeOutQuad: function(t) { + return -1 * t * (t - 2); + }, - /** - * EaseInOutQuad - * @public - * @param {number} t - current time - * @return {number} calculated time - */ - easeInOutQuad: function(t) { - if ((t *= 2) < 1) return 0.5 * t * t; - return -0.5 * ((--t) * (t - 2) - 1); - }, + /** + * EaseInOutQuad + * @public + * @param {number} t - current time + * @return {number} calculated time + */ + easeInOutQuad: function(t) { + if ((t *= 2) < 1) return 0.5 * t * t; + return -0.5 * ((--t) * (t - 2) - 1); + }, - /** - * EaseInCubic - * @public - * @param {number} t - current time - * @return {number} calculated time - */ - easeInCubic: function(t) { - return t * t * t; - }, + /** + * EaseInCubic + * @public + * @param {number} t - current time + * @return {number} calculated time + */ + easeInCubic: function(t) { + return t * t * t; + }, - /** - * EaseOutCubic - * @public - * @param {number} t - current time - * @return {number} calculated time - */ - easeOutCubic: function(t) { - return --t * t * t + 1; - }, + /** + * EaseOutCubic + * @public + * @param {number} t - current time + * @return {number} calculated time + */ + easeOutCubic: function(t) { + return --t * t * t + 1; + }, - /** - * EaseInOutCubic - * @public - * @param {number} t - current time - * @return {number} calculated time - */ - easeInOutCubic: function(t) { - if ((t *= 2) < 1) return 0.5 * t * t * t; - return 0.5 * ((t -= 2) * t * t + 2); - }, + /** + * EaseInOutCubic + * @public + * @param {number} t - current time + * @return {number} calculated time + */ + easeInOutCubic: function(t) { + if ((t *= 2) < 1) return 0.5 * t * t * t; + return 0.5 * ((t -= 2) * t * t + 2); + }, - /** - * EaseInQuart - * @public - * @param {number} t - current time - * @return {number} calculated time - */ - easeInQuart: function(t) { - return t * t * t * t; - }, + /** + * EaseInQuart + * @public + * @param {number} t - current time + * @return {number} calculated time + */ + easeInQuart: function(t) { + return t * t * t * t; + }, - /** - * EaseOutQuart - * @public - * @param {number} t - current time - * @return {number} calculated time - */ - easeOutQuart: function(t) { - return -1 * (--t * t * t * t - 1); - }, + /** + * EaseOutQuart + * @public + * @param {number} t - current time + * @return {number} calculated time + */ + easeOutQuart: function(t) { + return -1 * (--t * t * t * t - 1); + }, - /** - * EaseInOutQuart - * @public - * @param {number} t - current time - * @return {number} calculated time - */ - easeInOutQuart: function(t) { - if ((t *= 2) < 1) return 0.5 * t * t * t * t; - return -0.5 * ((t -= 2) * t * t * t - 2); - }, + /** + * EaseInOutQuart + * @public + * @param {number} t - current time + * @return {number} calculated time + */ + easeInOutQuart: function(t) { + if ((t *= 2) < 1) return 0.5 * t * t * t * t; + return -0.5 * ((t -= 2) * t * t * t - 2); + }, - /** - * EaseInQuint - * @public - * @param {number} t - current time - * @return {number} calculated time - */ - easeInQuint: function(t) { - return t * t * t * t * t; - }, - /** - * EaseOutQuint - * @public - * @param {number} t - current time - * @return {number} calculated time - */ - easeOutQuint: function(t) { - return --t * t * t * t * t + 1; - }, + /** + * EaseInQuint + * @public + * @param {number} t - current time + * @return {number} calculated time + */ + easeInQuint: function(t) { + return t * t * t * t * t; + }, + /** + * EaseOutQuint + * @public + * @param {number} t - current time + * @return {number} calculated time + */ + easeOutQuint: function(t) { + return --t * t * t * t * t + 1; + }, - /** - * EaseInOutQuint - * @public - * @param {number} t - current time - * @return {number} calculated time - */ - easeInOutQuint: function(t, d) { - if ((t *= 2) < 1) return 0.5 * t * t * t * t * t; - return 0.5 * ((t -= 2) * t * t * t * t + 2); - }, + /** + * EaseInOutQuint + * @public + * @param {number} t - current time + * @return {number} calculated time + */ + easeInOutQuint: function(t, d) { + if ((t *= 2) < 1) return 0.5 * t * t * t * t * t; + return 0.5 * ((t -= 2) * t * t * t * t + 2); + }, - /** - * EaseInSine - * @public - * @param {number} t - current time - * @return {number} calculated time - */ - easeInSine: function(t) { - return -1 * Math.cos(t * (Math.PI / 2)) + 1; - }, + /** + * EaseInSine + * @public + * @param {number} t - current time + * @return {number} calculated time + */ + easeInSine: function(t) { + return -1 * Math.cos(t * (Math.PI / 2)) + 1; + }, - /** - * EaseOutSine - * @public - * @param {number} t - current time - * @return {number} calculated time - */ - easeOutSine: function(t) { - return Math.sin(t * (Math.PI / 2)); - }, + /** + * EaseOutSine + * @public + * @param {number} t - current time + * @return {number} calculated time + */ + easeOutSine: function(t) { + return Math.sin(t * (Math.PI / 2)); + }, - /** - * EaseInOutSine - * @public - * @param {number} t - current time - * @return {number} calculated time - */ - easeInOutSine: function(t) { - return -0.5 * (Math.cos(Math.PI * t) - 1); - }, + /** + * EaseInOutSine + * @public + * @param {number} t - current time + * @return {number} calculated time + */ + easeInOutSine: function(t) { + return -0.5 * (Math.cos(Math.PI * t) - 1); + }, - /** - * EaseInExpo - * @public - * @param {number} t - current time - * @return {number} calculated time - */ - easeInExpo: function(t) { - return (t === 0) ? 0 : Math.pow(2, 10 * (t - 1)); - }, + /** + * EaseInExpo + * @public + * @param {number} t - current time + * @return {number} calculated time + */ + easeInExpo: function(t) { + return (t === 0) ? 0 : Math.pow(2, 10 * (t - 1)); + }, - /** - * EaseOutExpo - * @public - * @param {number} t - current time - * @return {number} calculated time - */ - easeOutExpo: function(t) { - return (t === 1) ? 1 : -Math.pow(2, -10 * t) + 1; - }, + /** + * EaseOutExpo + * @public + * @param {number} t - current time + * @return {number} calculated time + */ + easeOutExpo: function(t) { + return (t === 1) ? 1 : -Math.pow(2, -10 * t) + 1; + }, - /** - * EaseInOutExpo - * @public - * @param {number} t - current time - * @return {number} calculated time - */ - easeInOutExpo: function(t) { - if (t === 0) return 0; - if (t === 1) return 1; - if ((t *= 2) < 1) return 0.5 * Math.pow(2, 10 * (t - 1)); - return 0.5 * (-Math.pow(2, -10 * --t) + 2); - }, + /** + * EaseInOutExpo + * @public + * @param {number} t - current time + * @return {number} calculated time + */ + easeInOutExpo: function(t) { + if (t === 0) return 0; + if (t === 1) return 1; + if ((t *= 2) < 1) return 0.5 * Math.pow(2, 10 * (t - 1)); + return 0.5 * (-Math.pow(2, -10 * --t) + 2); + }, - /** - * EaseInCirc - * @public - * @param {number} t - current time - * @return {number} calculated time - */ - easeInCirc: function(t) { - return -1 * (Math.sqrt(1 - t * t) - 1); - }, + /** + * EaseInCirc + * @public + * @param {number} t - current time + * @return {number} calculated time + */ + easeInCirc: function(t) { + return -1 * (Math.sqrt(1 - t * t) - 1); + }, - /** - * EaseOutCirc - * @public - * @param {number} t - current time - * @return {number} calculated time - */ - easeOutCirc: function(t) { - return Math.sqrt(1 - --t * t); - }, + /** + * EaseOutCirc + * @public + * @param {number} t - current time + * @return {number} calculated time + */ + easeOutCirc: function(t) { + return Math.sqrt(1 - (--t * t)); + }, - /** - * EaseInOutCirc - * @public - * @param {number} t - current time - * @return {number} calculated time - */ - easeInOutCirc: function(t) { - if ((t *= 2) < 1) return -0.5 * (Math.sqrt(1 - t * t) - 1); - return 0.5 * (Math.sqrt(1 - (t -= 2) * t) + 1); - }, + /** + * EaseInOutCirc + * @public + * @param {number} t - current time + * @return {number} calculated time + */ + easeInOutCirc: function(t) { + if ((t *= 2) < 1) return -0.5 * (Math.sqrt(1 - t * t) - 1); + return 0.5 * (Math.sqrt(1 - (t -= 2) * t) + 1); + }, - /** - * EaseInElastic - * @public - * @param {number} t - current time - * @param {number} d - duration - * @return {number} calculated time - */ - easeInElastic: function(t, d) { - var a = 1, - p = 0, - s = 1.70158; - if (t === 0) return 0; - if (t === 1) return 1; - if (!p) p = d * 0.3; - if (a < 1) { - a = 1; - s = p / 4; - } else s = p / (2 * Math.PI) * Math.asin(1 / a); - return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)); - }, + /** + * EaseInElastic + * @public + * @param {number} t - current time + * @param {number} d - duration + * @return {number} calculated time + */ + easeInElastic: function(t, d) { + var a = 1, + p = 0, + s = 1.70158; + if (t === 0) return 0; + if (t === 1) return 1; + if (!p) p = d * 0.3; + if (a < 1) { + a = 1; + s = p / 4; + } else s = p / (2 * Math.PI) * Math.asin(1 / a); + return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)); + }, - /** - * EaseInBounce - * @public - * @param {number} t - current time - * @return {number} calculated time - */ - easeInBounce: function(t) { - return 1 - easing.easeOutBounce(1 - t); - }, + /** + * EaseInBounce + * @public + * @param {number} t - current time + * @return {number} calculated time + */ + easeInBounce: function(t) { + return 1 - easing.easeOutBounce(1 - t); + }, - /** - * EaseOutBounce - * @public - * @param {number} t - current time - * @return {number} calculated time - */ - easeOutBounce: function(t) { - if (t < 0.363636) { - return 7.5625 * t * t; - } else if (t < 0.727272) { - return 7.5625 * (t -= 0.545454) * t + 0.75; - } else if (t < (2.5 / 2.75)) { - return 7.5625 * (t -= 0.818182) * t + 0.9375; - } else { - return 7.5625 * (t -= 0.954545) * t + 0.984375; - } - }, + /** + * EaseOutBounce + * @public + * @param {number} t - current time + * @return {number} calculated time + */ + easeOutBounce: function(t) { + if (t < 0.363636) { + return 7.5625 * t * t; + } else if (t < 0.727272) { + return 7.5625 * (t -= 0.545454) * t + 0.75; + } else if (t < (2.5 / 2.75)) { + return 7.5625 * (t -= 0.818182) * t + 0.9375; + } else { + return 7.5625 * (t -= 0.954545) * t + 0.984375; + } + }, - /** - * EaseInOutBounce - * @public - * @param {number} t - current time - * @return {number} calculated time - */ - easeInOutBounce: function(t) { - if (t < 0.5) return easing.easeInBounce(t * 2) * 0.5; - return easing.easeOutBounce(t * 2 - 1) * 0.5 + 0.5; - }, + /** + * EaseInOutBounce + * @public + * @param {number} t - current time + * @return {number} calculated time + */ + easeInOutBounce: function(t) { + if (t < 0.5) return easing.easeInBounce(t * 2) * 0.5; + return easing.easeOutBounce(t * 2 - 1) * 0.5 + 0.5; + }, - /** - * EaseOutElastic - * @public - * @param {number} t - current time - * @param {number} d - duration - * @return {number} calculated time - */ - easeOutElastic: function(t, d) { - var a = 1, - p = 0, - s = 1.70158; - if (t === 0) return 0; - if (t === 1) return 1; - if (!p) p = d * 0.3; - if (a < 1) { - a = 1; - s = p / 4; - } else s = p / (2 * Math.PI) * Math.asin(1 / a); - return a * Math.pow(2, -10 * t) * Math.sin((t * d - s) * (2 * Math.PI) / p) + 1; - }, + /** + * EaseOutElastic + * @public + * @param {number} t - current time + * @param {number} d - duration + * @return {number} calculated time + */ + easeOutElastic: function(t, d) { + var a = 1, + p = 0, + s = 1.70158; + if (t === 0) return 0; + if (t === 1) return 1; + if (!p) p = d * 0.3; + if (a < 1) { + a = 1; + s = p / 4; + } else s = p / (2 * Math.PI) * Math.asin(1 / a); + return a * Math.pow(2, -10 * t) * Math.sin((t * d - s) * (2 * Math.PI) / p) + 1; + }, - /** - * EaseInOutElastic - * @public - * @param {number} t - current time - * @param {number} d - duration - * @return {number} calculated time - */ - easeInOutElastic: function(t, d) { - var a = 1, - p = 0, - s = 1.70158; - if (t === 0) return 0; - if ((t *= 2) === 2) return 1; - if (!p) p = d * (0.3 * 1.5); - if (a < 1) { - a = 1; - s = p / 4; - } else s = p / (2 * Math.PI) * Math.asin(1 / a); - if (t < 1) return -0.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)); - return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p) * 0.5 + 1; - }, + /** + * EaseInOutElastic + * @public + * @param {number} t - current time + * @param {number} d - duration + * @return {number} calculated time + */ + easeInOutElastic: function(t, d) { + var a = 1, + p = 0, + s = 1.70158; + if (t === 0) return 0; + if ((t *= 2) === 2) return 1; + if (!p) p = d * (0.3 * 1.5); + if (a < 1) { + a = 1; + s = p / 4; + } else s = p / (2 * Math.PI) * Math.asin(1 / a); + if (t < 1) return -0.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)); + return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p) * 0.5 + 1; + }, - /** - * EaseInBack - * @public - * @param {number} t - current time - * @param {number} d - duration - * @return {number} calculated time - */ - easeInBack: function(t, d, s) { - if (!s) s = 1.70158; - return t * t * ((s + 1) * t - s); - }, + /** + * EaseInBack + * @public + * @param {number} t - current time + * @param {number} d - duration + * @return {number} calculated time + */ + easeInBack: function(t, d, s) { + if (!s) s = 1.70158; + return t * t * ((s + 1) * t - s); + }, - /** - * EaseOutBack - * @public - * @param {number} t - current time - * @param {number} d - duration - * @return {number} calculated time - */ - easeOutBack: function(t, d, s) { - if (!s) s = 1.70158; - return --t * t * ((s + 1) * t + s) + 1; - }, + /** + * EaseOutBack + * @public + * @param {number} t - current time + * @param {number} d - duration + * @return {number} calculated time + */ + easeOutBack: function(t, d, s) { + if (!s) s = 1.70158; + return --t * t * ((s + 1) * t + s) + 1; + }, - /** - * EaseInOutBack - * @public - * @param {number} t - current time - * @param {number} d - duration - * @return {number} calculated time - */ - easeInOutBack: function(t, d, s) { - if (!s) s = 1.70158; - if ((t *= 2) < 1) return 0.5 * (t * t * (((s *= (1.525)) + 1) * t - s)); - return 0.5 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2); - } + /** + * EaseInOutBack + * @public + * @param {number} t - current time + * @param {number} d - duration + * @return {number} calculated time + */ + easeInOutBack: function(t, d, s) { + if (!s) s = 1.70158; + if ((t *= 2) < 1) return 0.5 * (t * t * (((s *= (1.525)) + 1) * t - s)); + return 0.5 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2); + } }; \ No newline at end of file diff --git a/src/transform.js b/src/transform.js index 7f2f995dc..6a603e721 100644 --- a/src/transform.js +++ b/src/transform.js @@ -6,7 +6,7 @@ require('enyo'); * @return {Number[]} Typed_array */ function typedArray (size) { - return new Float32Array(new ArrayBuffer(size)); + return new Float32Array(new ArrayBuffer(size)); } /** @@ -15,9 +15,9 @@ function typedArray (size) { * @param {Number[]} numberMat indices where value has to be 1 */ function inputValues (matrix, numberMat) { - for (var i = 0; i < numberMat.length; i++) { - matrix[numberMat[i]] = 1; - } + for (var i = 0; i < numberMat.length; i++) { + matrix[numberMat[i]] = 1; + } } @@ -30,13 +30,13 @@ function inputValues (matrix, numberMat) { * @return {Number[]} Matrix3d */ exports.translate = function(x, y, z) { - var translateMat, modifiedMat; - translateMat = typedArray(64); - modifiedMat = inputValues(translateMat, new Uint8Array([0, 5, 10, 15])); - translateMat[12] = x; - translateMat[13] = y ? y : 0; - translateMat[14] = z ? z : 0; - return translateMat; + var translateMat, modifiedMat; + translateMat = typedArray(64); + modifiedMat = inputValues(translateMat, new Uint8Array([0, 5, 10, 15])); + translateMat[12] = x; + translateMat[13] = y ? y : 0; + translateMat[14] = z ? z : 0; + return translateMat; }; /** @@ -46,11 +46,11 @@ exports.translate = function(x, y, z) { * @return {Number[]} Matrix3d */ exports.translateX = function(x) { - var translateX, modifiedMat; - translateX = typedArray(64); - modifiedMat = inputValues(translateX, new Uint8Array([0, 5, 10, 15])); - translateX[12] = x ? x : 0; - return translateX; + var translateX, modifiedMat; + translateX = typedArray(64); + modifiedMat = inputValues(translateX, new Uint8Array([0, 5, 10, 15])); + translateX[12] = x ? x : 0; + return translateX; }; /** @@ -60,11 +60,11 @@ exports.translateX = function(x) { * @return {Number[]} Matrix3d */ exports.translateY = function(y) { - var translateY, modifiedMat; - translateY = typedArray(64); - modifiedMat = inputValues(translateY, new Uint8Array([0, 5, 10, 15])); - translateY[13] = y ? y : 0; - return translateY; + var translateY, modifiedMat; + translateY = typedArray(64); + modifiedMat = inputValues(translateY, new Uint8Array([0, 5, 10, 15])); + translateY[13] = y ? y : 0; + return translateY; }; /** @@ -74,11 +74,11 @@ exports.translateY = function(y) { * @return {Number[]} Matrix3d */ exports.translateZ = function(z) { - var translateZ, modifiedMat; - translateZ = typedArray(64); - modifiedMat = inputValues(translateZ, new Uint8Array([0, 5, 10, 15])); - translateZ[14] = z ? z : 0; - return translateZ; + var translateZ, modifiedMat; + translateZ = typedArray(64); + modifiedMat = inputValues(translateZ, new Uint8Array([0, 5, 10, 15])); + translateZ[14] = z ? z : 0; + return translateZ; }; /** @@ -90,12 +90,12 @@ exports.translateZ = function(z) { * @return {Number[]} Matrix3d */ exports.scale = function(x, y, z) { - var scaleMat = typedArray(64); - scaleMat[0] = x; - scaleMat[5] = y ? y : 1; - scaleMat[10] = z ? z : 1; - scaleMat[15] = 1; - return scaleMat; + var scaleMat = typedArray(64); + scaleMat[0] = x; + scaleMat[5] = y ? y : 1; + scaleMat[10] = z ? z : 1; + scaleMat[15] = 1; + return scaleMat; }; /** @@ -106,15 +106,15 @@ exports.scale = function(x, y, z) { * @return {Number[]} Matrix3d */ exports.skew =function(a, b) { - var skewMat, modifiedMat; - a = a ? Math.tan(a * Math.PI / 180) : 0; - b = b ? Math.tan(b * Math.PI / 180) : 0; - - skewMat = typedArray(64); - modifiedMat = inputValues(skewMat, new Uint8Array([0, 5, 10, 15])); - skewMat[1] = b; - skewMat[4] = a; - return skewMat; + var skewMat, modifiedMat; + a = a ? Math.tan(a * Math.PI / 180) : 0; + b = b ? Math.tan(b * Math.PI / 180) : 0; + + skewMat = typedArray(64); + modifiedMat = inputValues(skewMat, new Uint8Array([0, 5, 10, 15])); + skewMat[1] = b; + skewMat[4] = a; + return skewMat; }; /** @@ -124,18 +124,18 @@ exports.skew =function(a, b) { * @return {Number[]} Matrix3d */ exports.rotateX = function(a) { - var cosa, sina, rotateXMat, modifiedMat; - a = a ? a * Math.PI / 180 : 0; - cosa = Math.cos(a); - sina = Math.sin(a); - - rotateXMat = typedArray(64); - modifiedMat = inputValues(rotateXMat, new Uint8Array([0, 15])); - rotateXMat[5] = cosa; - rotateXMat[6] = -sina; - rotateXMat[9] = sina; - rotateXMat[10] = cosa; - return rotateXMat; + var cosa, sina, rotateXMat, modifiedMat; + a = a ? a * Math.PI / 180 : 0; + cosa = Math.cos(a); + sina = Math.sin(a); + + rotateXMat = typedArray(64); + modifiedMat = inputValues(rotateXMat, new Uint8Array([0, 15])); + rotateXMat[5] = cosa; + rotateXMat[6] = -sina; + rotateXMat[9] = sina; + rotateXMat[10] = cosa; + return rotateXMat; }; /** @@ -145,18 +145,18 @@ exports.rotateX = function(a) { * @return {Number[]} Matrix3d */ exports.rotateY = function(b) { - var cosb, sinb, rotateYMat, modifiedMat; - b = b ? b * Math.PI / 180 : 0; - cosb = Math.cos(b); - sinb = Math.sin(b); - - rotateYMat = typedArray(64); - modifiedMat = inputValues(rotateYMat, new Uint8Array([5, 15])); - rotateYMat[0] = cosb; - rotateYMat[2] = sinb; - rotateYMat[8] = -sinb; - rotateYMat[10] = cosb; - return rotateYMat; + var cosb, sinb, rotateYMat, modifiedMat; + b = b ? b * Math.PI / 180 : 0; + cosb = Math.cos(b); + sinb = Math.sin(b); + + rotateYMat = typedArray(64); + modifiedMat = inputValues(rotateYMat, new Uint8Array([5, 15])); + rotateYMat[0] = cosb; + rotateYMat[2] = sinb; + rotateYMat[8] = -sinb; + rotateYMat[10] = cosb; + return rotateYMat; }; /** @@ -166,18 +166,18 @@ exports.rotateY = function(b) { * @return {Number[]} Matrix3d */ exports.rotateZ = function(g) { - var cosg, sing, rotateZMat; - g = g ? g * Math.PI / 180 : 0; - cosg = Math.cos(g); - sing = Math.sin(g); - - rotateZMat = typedArray(64); - rotateZMat[0] = cosg; - rotateZMat[1] = -sing; - rotateZMat[4] = sing; - rotateZMat[5] = cosg; - rotateZMat[15] = 1; - return rotateZMat; + var cosg, sing, rotateZMat; + g = g ? g * Math.PI / 180 : 0; + cosg = Math.cos(g); + sing = Math.sin(g); + + rotateZMat = typedArray(64); + rotateZMat[0] = cosg; + rotateZMat[1] = -sing; + rotateZMat[4] = sing; + rotateZMat[5] = cosg; + rotateZMat[15] = 1; + return rotateZMat; }; /** @@ -189,543 +189,543 @@ exports.rotateZ = function(g) { * @return {Number[]} Matrix3d */ exports.rotate = function(a, b, g) { - var ca, sa, cb, sb, cg, sg, rotateMat; - a = a ? a * Math.PI / 180 : 0; - b = b ? b * Math.PI / 180 : 0; - g = g ? g * Math.PI / 180 : 0; - ca = Math.cos(a); - sa = Math.sin(a); - cb = Math.cos(b); - sb = Math.sin(b); - cg = Math.cos(g); - sg = Math.sin(g); - - rotateMat = typedArray(64); - rotateMat[0] = cb * cg; - rotateMat[1] = ca * sg + sa * sb * cg; - rotateMat[2] = sa * sg - ca * sb * cg; - rotateMat[4] = -cb * sg; - rotateMat[5] = ca * cg - sa * sb * sg; - rotateMat[6] = sa * cg + ca * sb * sg; - rotateMat[8] = sb; - rotateMat[9] = -sa * cb; - rotateMat[10] = ca * cb; - rotateMat[15] = 1; - return rotateMat; + var ca, sa, cb, sb, cg, sg, rotateMat; + a = a ? a * Math.PI / 180 : 0; + b = b ? b * Math.PI / 180 : 0; + g = g ? g * Math.PI / 180 : 0; + ca = Math.cos(a); + sa = Math.sin(a); + cb = Math.cos(b); + sb = Math.sin(b); + cg = Math.cos(g); + sg = Math.sin(g); + + rotateMat = typedArray(64); + rotateMat[0] = cb * cg; + rotateMat[1] = ca * sg + sa * sb * cg; + rotateMat[2] = sa * sg - ca * sb * cg; + rotateMat[4] = -cb * sg; + rotateMat[5] = ca * cg - sa * sb * sg; + rotateMat[6] = sa * cg + ca * sb * sg; + rotateMat[8] = sb; + rotateMat[9] = -sa * cb; + rotateMat[10] = ca * cb; + rotateMat[15] = 1; + return rotateMat; }; exports.Matrix = { - /** - * To create Identity Matrix3d as array. - * @public - * @return {Number[]} Identity Matrix3d - */ - identity: function() { - var identityMatrix, modifiedMat; - identityMatrix = typedArray(64); - modifiedMat = inputValues(identityMatrix, new Uint8Array([0, 5, 10, 15])); - return identityMatrix; - }, - - /** - * To create Identity Matrix2d as array. - * @public - * @return {Number[]} Identity Matrix2d as array - */ - identity2D: function() { - var identity2D, modifiedMat; - identity2D = typedArray(36); - modifiedMat = inputValues(identity2D, new Uint8Array([0, 4, 8])); - return identity2D; - }, - - - /** - * To create Identity Matrix (NXN order). - * @public - * @param {Number} N Order of Identity Matrix - * @return {Number[][]} Identity Matrix of order N - */ - identityMatrix: function(N) { - var i, j, row, result = []; - for (i = 0; i < N; i++) { - row = []; - for (j = 0; j < N; j++) { - if (i === j) { - row.push(1); - } else { - row.push(0); - } - } - result.push(row); - } - return result; - }, - /** - * To multiply 2 Martix3d (4x4 order) - * @public - * @param {Number[]} m1 1st Matrix3d - * @param {Number[]} m2 2nd Matrix3d - * @return {Number[]} Resultant Matrix3d - */ - multiply: function(m1, m2) { - if (m1.length !== 16 || m2.length !== 16) return; - var multiplyMat = typedArray(64); - multiplyMat[0] = m1[0] * m2[0] + m1[4] * m2[1] + m1[8] * m2[2]; - multiplyMat[1] = m1[1] * m2[0] + m1[5] * m2[1] + m1[9] * m2[2]; - multiplyMat[2] = m1[2] * m2[0] + m1[6] * m2[1] + m1[10] * m2[2]; - multiplyMat[4] = m1[0] * m2[4] + m1[4] * m2[5] + m1[8] * m2[6]; - multiplyMat[5] = m1[1] * m2[4] + m1[5] * m2[5] + m1[9] * m2[6]; - multiplyMat[6] = m1[2] * m2[4] + m1[6] * m2[5] + m1[10] * m2[6]; - multiplyMat[8] = m1[0] * m2[8] + m1[4] * m2[9] + m1[8] * m2[10]; - multiplyMat[9] = m1[1] * m2[8] + m1[5] * m2[9] + m1[9] * m2[10]; - multiplyMat[10] = m1[2] * m2[8] + m1[6] * m2[9] + m1[10] * m2[10]; - multiplyMat[12] = m1[0] * m2[12] + m1[4] * m2[13] + m1[8] * m2[14] + m1[12]; - multiplyMat[13] = m1[1] * m2[12] + m1[5] * m2[13] + m1[9] * m2[14] + m1[13]; - multiplyMat[14] = m1[2] * m2[12] + m1[6] * m2[13] + m1[10] * m2[14] + m1[14]; - multiplyMat[15] = 1; - return multiplyMat; - }, - - /** - * To multiply 2 Martix3d (n*n order) - * @param {Number[]} m1 1st Matrix3d - * @param {Number[]} m2 2nd Matrix3d - * @return {[type]} Resultant Matrix3d - */ - multiplyN: function(m1, m2) { - var i, j, sum, - m = [], - l1 = m1.length, - l2 = m2.length; - - for (i = 0; i < l1; i++) { - sum = 0; - for (j = 0; j < l2; j++) { - sum += m1[i][j] * m2[j]; - } - m.push(sum); - } - return m; - }, - - /** - * To inverse matrix of order N - * @public - * @param {Number[]} matrix Matrix (NxN order) - * @param {Number} n Order of the matrix - * @return {Number[]} Inverted Matrix - */ - inverseN: function(matrix, n) { - var i, j, k, r, t, - result = this.identityMatrix(n); - - for (i = 0; i < n; i++) { - for (j = 0; j < n; j++) { - if (i != j) { - r = matrix[j][i] / matrix[i][i]; - for (k = 0; k < n; k++) { - matrix[j][k] -= r * matrix[i][k]; - result[j][k] -= r * result[i][k]; - } - } - } - } - - for (i = 0; i < n; i++) { - t = matrix[i][i]; - for (j = 0; j < n; j++) { - matrix[i][j] = matrix[i][j] / t; - result[i][j] = result[i][j] / t; - } - } - - return result; - }, - - /** - * Calculate matrix3d of a frame based on transformation vectors. - * @public - * @param {Number[]} trns Translate vector - * @param {Number[]} rot Rotate quaternion vector - * @param {Number[]} sc Scale vector - * @param {Number[]} sq Skew vector - * @param {Number[]} per Perspective vector - * @return {Number[]} Final Matrix3d for particular frame - */ - recompose: function(trns, rot, sc, sq, per) { - var i, - x = rot[0], - y = rot[1], - z = rot[2], - w = rot[3], - m = this.identity(), - sM = this.identity(), - rM = this.identity(); - - - // apply perspective - if (per) { - m[3] = per[0]; - m[7] = per[1]; - m[11] = per[2]; - m[15] = per[3]; - } - - m[12] = trns[0]; - m[13] = trns[1]; - m[14] = trns[2]; - - // apply rotate - rM[0] = 1 - 2 * (y * y + z * z); - rM[1] = 2 * (x * y - z * w); - rM[2] = 2 * (x * z + y * w); - rM[4] = 2 * (x * y + z * w); - rM[5] = 1 - 2 * (x * x + z * z); - rM[6] = 2 * (y * z - x * w); - rM[8] = 2 * (x * z - y * w); - rM[9] = 2 * (y * z + x * w); - rM[10] = 1 - 2 * (x * x + y * y); - - m = this.multiply(m, rM); - - // apply skew - if (sq[2]) { - sM[9] = sq[2]; - m = this.multiply(m, sM); - } - - if (sq[1]) { - sM[9] = 0; - sM[8] = sq[1]; - m = this.multiply(m, sM); - } - - if (sq[0]) { - sM[8] = 0; - sM[4] = sq[0]; - m = this.multiply(m, sM); - } - - // apply scale - for (i = 0; i < 12; i += 4) { - m[0 + i] *= sc[0]; - m[1 + i] *= sc[1]; - m[2 + i] *= sc[2]; - } - return m; - }, - - /** - * Decompose transformation vectors into various properties out of matrix3d. - * @public - * @param {Number[]} matrix Matrix3d - * @param {Object} ret To store various transformation properties like translate, rotate, scale, skew and perspective. - * @return {Boolean} true, if matrix exists else false. - */ - decompose: function(matrix, ret) { - if (matrix[15] === 0) return false; - var i, - tV = [], - rV = [], - pV = [], - skV = [], - scV = [], - row = [], - pdum3 = []; - - for (i = 0; i < 16; i++) - matrix[i] /= matrix[15]; - - //TODO: decompose perspective - pV = [0, 0, 0, 0]; - - for (i = 0; i < 3; i++) - tV[i] = matrix[12 + i]; - - for (i = 0; i < 12; i += 4) { - row.push([ - matrix[0 + i], - matrix[1 + i], - matrix[2 + i] - ]); - } - - scV[0] = vector.len(row[0]); - row[0] = quaternion.normalize(row[0]); - skV[0] = vector.dot(row[0], row[1]); - row[1] = vector.combine(row[1], row[0], 1.0, -skV[0]); - - scV[1] = vector.len(row[1]); - row[1] = quaternion.normalize(row[1]); - skV[0] /= scV[1]; - - // Compute XZ and YZ shears, orthogonalized 3rd row - skV[1] = vector.dot(row[0], row[2]); - row[2] = vector.combine(row[2], row[0], 1.0, -skV[1]); - skV[2] = vector.dot(row[1], row[2]); - row[2] = vector.combine(row[2], row[1], 1.0, -skV[2]); - - // Next, get Z scale and normalize 3rd row. - scV[2] = vector.len(row[2]); - row[2] = quaternion.normalize(row[2]); - skV[1] /= scV[2]; - skV[2] /= scV[2]; - - pdum3 = vector.cross(row[1], row[2]); - if (vector.dot(row[0], pdum3) < 0) { - for (i = 0; i < 3; i++) { - scV[i] *= -1; - row[i][0] *= -1; - row[i][1] *= -1; - row[i][2] *= -1; - } - } - - rV[0] = 0.5 * Math.sqrt(Math.max(1 + row[0][0] - row[1][1] - row[2][2], 0)); - rV[1] = 0.5 * Math.sqrt(Math.max(1 - row[0][0] + row[1][1] - row[2][2], 0)); - rV[2] = 0.5 * Math.sqrt(Math.max(1 - row[0][0] - row[1][1] + row[2][2], 0)); - rV[3] = 0.5 * Math.sqrt(Math.max(1 + row[0][0] + row[1][1] + row[2][2], 0)); - - if (row[2][1] > row[1][2]) rV[0] = -rV[0]; - if (row[0][2] > row[2][0]) rV[1] = -rV[1]; - if (row[1][0] > row[0][1]) rV[2] = -rV[2]; - - ret.translate = tV; - ret.rotate = rV; - ret.scale = scV; - ret.skew = skV; - ret.perspective = pV; - return true; - }, - - /** - * Decompose transformation matrix2d from matrix3d. - * @public - * @param {Number[]} matrix Matrix3d - * @param {Object} ret To store various transformation properties like translate, angle and matrix. - * @return {Boolean} ret To store various transformation properties like translate, angle and matrix. - */ - decompose2D: function(m, ret) { - var scale = [], - matrix = [], - row0x = m[0], - row0y = m[1], - row1x = m[4], - row1y = m[5], - det, angle, sn, cs, - m11, m12, m21, m22; - - ret = ret || {}; - scale = [ - Math.sqrt(row0x * row0x + row0y * row0y), - Math.sqrt(row1x * row1x + row1y * row1y) - ]; - - // If determinant is negative, one axis was flipped. - det = row0x * row1y - row0y * row1x; - if (det < 0) - // Flip axis with minimum unit vector dot product. - if (row0x < row1y) - scale[0] = -scale[0]; - else - scale[1] = -scale[1]; - - // Renormalize matrix to remove scale. - if (scale[0]) { - row0x *= 1 / scale[0]; - row0y *= 1 / scale[0]; - } - - if (scale[1]) { - row1x *= 1 / scale[1]; - row1y *= 1 / scale[1]; - } - ret.scale = scale; - - - // Compute rotation and renormalize matrix. - angle = Math.atan2(row0y, row0x); - - if (angle) { - sn = -row0y; - cs = row0x; - m11 = row0x; - m12 = row0y; - m21 = row1x; - m22 = row1y; - row0x = cs * m11 + sn * m21; - row0y = cs * m12 + sn * m22; - row1x = -sn * m11 + cs * m21; - row1y = -sn * m12 + cs * m22; - } - - // Rotate(-angle) = [cos(angle), sin(angle), -sin(angle), cos(angle)] - // = [row0x, -row0y, row0y, row0x] - // Thanks to the normalization above. - matrix[0] = row0x; - matrix[1] = row0y; - matrix[2] = row1x; - matrix[3] = row1y; - matrix[4] = m[12]; - matrix[5] = m[13]; - ret.matrix2D = matrix; - - // Convert into degrees because our rotation functions expect it. - ret.angle = angle * 180 / Math.PI; - - return ret; - }, - - /** - * Convert Matrix3d array to Matrix3d String - * @public - * @param {Number[]} m Matrix3d Array - * @return {String} Matrix3d String - */ - toString: function(m) { - var i, ms = m.length > 10 ? 'matrix3d(' : 'matrix('; - for (i = 0; i < m.length - 1; i++) { - ms += (m[i] < 0.000001 && m[i] > -0.000001) ? '0,' : m[i] + ','; - } - ms += m[m.length - 1] + ')'; - return ms; - } + /** + * To create Identity Matrix3d as array. + * @public + * @return {Number[]} Identity Matrix3d + */ + identity: function() { + var identityMatrix, modifiedMat; + identityMatrix = typedArray(64); + modifiedMat = inputValues(identityMatrix, new Uint8Array([0, 5, 10, 15])); + return identityMatrix; + }, + + /** + * To create Identity Matrix2d as array. + * @public + * @return {Number[]} Identity Matrix2d as array + */ + identity2D: function() { + var identity2D, modifiedMat; + identity2D = typedArray(36); + modifiedMat = inputValues(identity2D, new Uint8Array([0, 4, 8])); + return identity2D; + }, + + + /** + * To create Identity Matrix (NXN order). + * @public + * @param {Number} N Order of Identity Matrix + * @return {Number[][]} Identity Matrix of order N + */ + identityMatrix: function(N) { + var i, j, row, result = []; + for (i = 0; i < N; i++) { + row = []; + for (j = 0; j < N; j++) { + if (i === j) { + row.push(1); + } else { + row.push(0); + } + } + result.push(row); + } + return result; + }, + /** + * To multiply 2 Martix3d (4x4 order) + * @public + * @param {Number[]} m1 1st Matrix3d + * @param {Number[]} m2 2nd Matrix3d + * @return {Number[]} Resultant Matrix3d + */ + multiply: function(m1, m2) { + if (m1.length !== 16 || m2.length !== 16) return; + var multiplyMat = typedArray(64); + multiplyMat[0] = m1[0] * m2[0] + m1[4] * m2[1] + m1[8] * m2[2]; + multiplyMat[1] = m1[1] * m2[0] + m1[5] * m2[1] + m1[9] * m2[2]; + multiplyMat[2] = m1[2] * m2[0] + m1[6] * m2[1] + m1[10] * m2[2]; + multiplyMat[4] = m1[0] * m2[4] + m1[4] * m2[5] + m1[8] * m2[6]; + multiplyMat[5] = m1[1] * m2[4] + m1[5] * m2[5] + m1[9] * m2[6]; + multiplyMat[6] = m1[2] * m2[4] + m1[6] * m2[5] + m1[10] * m2[6]; + multiplyMat[8] = m1[0] * m2[8] + m1[4] * m2[9] + m1[8] * m2[10]; + multiplyMat[9] = m1[1] * m2[8] + m1[5] * m2[9] + m1[9] * m2[10]; + multiplyMat[10] = m1[2] * m2[8] + m1[6] * m2[9] + m1[10] * m2[10]; + multiplyMat[12] = m1[0] * m2[12] + m1[4] * m2[13] + m1[8] * m2[14] + m1[12]; + multiplyMat[13] = m1[1] * m2[12] + m1[5] * m2[13] + m1[9] * m2[14] + m1[13]; + multiplyMat[14] = m1[2] * m2[12] + m1[6] * m2[13] + m1[10] * m2[14] + m1[14]; + multiplyMat[15] = 1; + return multiplyMat; + }, + + /** + * To multiply 2 Martix3d (n*n order) + * @param {Number[]} m1 1st Matrix3d + * @param {Number[]} m2 2nd Matrix3d + * @return {[type]} Resultant Matrix3d + */ + multiplyN: function(m1, m2) { + var i, j, sum, + m = [], + l1 = m1.length, + l2 = m2.length; + + for (i = 0; i < l1; i++) { + sum = 0; + for (j = 0; j < l2; j++) { + sum += m1[i][j] * m2[j]; + } + m.push(sum); + } + return m; + }, + + /** + * To inverse matrix of order N + * @public + * @param {Number[]} matrix Matrix (NxN order) + * @param {Number} n Order of the matrix + * @return {Number[]} Inverted Matrix + */ + inverseN: function(matrix, n) { + var i, j, k, r, t, + result = this.identityMatrix(n); + + for (i = 0; i < n; i++) { + for (j = 0; j < n; j++) { + if (i != j) { + r = matrix[j][i] / matrix[i][i]; + for (k = 0; k < n; k++) { + matrix[j][k] -= r * matrix[i][k]; + result[j][k] -= r * result[i][k]; + } + } + } + } + + for (i = 0; i < n; i++) { + t = matrix[i][i]; + for (j = 0; j < n; j++) { + matrix[i][j] = matrix[i][j] / t; + result[i][j] = result[i][j] / t; + } + } + + return result; + }, + + /** + * Calculate matrix3d of a frame based on transformation vectors. + * @public + * @param {Number[]} trns Translate vector + * @param {Number[]} rot Rotate quaternion vector + * @param {Number[]} sc Scale vector + * @param {Number[]} sq Skew vector + * @param {Number[]} per Perspective vector + * @return {Number[]} Final Matrix3d for particular frame + */ + recompose: function(trns, rot, sc, sq, per) { + var i, + x = rot[0], + y = rot[1], + z = rot[2], + w = rot[3], + m = this.identity(), + sM = this.identity(), + rM = this.identity(); + + + // apply perspective + if (per) { + m[3] = per[0]; + m[7] = per[1]; + m[11] = per[2]; + m[15] = per[3]; + } + + m[12] = trns[0]; + m[13] = trns[1]; + m[14] = trns[2]; + + // apply rotate + rM[0] = 1 - 2 * (y * y + z * z); + rM[1] = 2 * (x * y - z * w); + rM[2] = 2 * (x * z + y * w); + rM[4] = 2 * (x * y + z * w); + rM[5] = 1 - 2 * (x * x + z * z); + rM[6] = 2 * (y * z - x * w); + rM[8] = 2 * (x * z - y * w); + rM[9] = 2 * (y * z + x * w); + rM[10] = 1 - 2 * (x * x + y * y); + + m = this.multiply(m, rM); + + // apply skew + if (sq[2]) { + sM[9] = sq[2]; + m = this.multiply(m, sM); + } + + if (sq[1]) { + sM[9] = 0; + sM[8] = sq[1]; + m = this.multiply(m, sM); + } + + if (sq[0]) { + sM[8] = 0; + sM[4] = sq[0]; + m = this.multiply(m, sM); + } + + // apply scale + for (i = 0; i < 12; i += 4) { + m[0 + i] *= sc[0]; + m[1 + i] *= sc[1]; + m[2 + i] *= sc[2]; + } + return m; + }, + + /** + * Decompose transformation vectors into various properties out of matrix3d. + * @public + * @param {Number[]} matrix Matrix3d + * @param {Object} ret To store various transformation properties like translate, rotate, scale, skew and perspective. + * @return {Boolean} true, if matrix exists else false. + */ + decompose: function(matrix, ret) { + if (matrix[15] === 0) return false; + var i, + tV = [], + rV = [], + pV = [], + skV = [], + scV = [], + row = [], + pdum3 = []; + + for (i = 0; i < 16; i++) + matrix[i] /= matrix[15]; + + //TODO: decompose perspective + pV = [0, 0, 0, 0]; + + for (i = 0; i < 3; i++) + tV[i] = matrix[12 + i]; + + for (i = 0; i < 12; i += 4) { + row.push([ + matrix[0 + i], + matrix[1 + i], + matrix[2 + i] + ]); + } + + scV[0] = vector.len(row[0]); + row[0] = quaternion.normalize(row[0]); + skV[0] = vector.dot(row[0], row[1]); + row[1] = vector.combine(row[1], row[0], 1.0, -skV[0]); + + scV[1] = vector.len(row[1]); + row[1] = quaternion.normalize(row[1]); + skV[0] /= scV[1]; + + // Compute XZ and YZ shears, orthogonalized 3rd row + skV[1] = vector.dot(row[0], row[2]); + row[2] = vector.combine(row[2], row[0], 1.0, -skV[1]); + skV[2] = vector.dot(row[1], row[2]); + row[2] = vector.combine(row[2], row[1], 1.0, -skV[2]); + + // Next, get Z scale and normalize 3rd row. + scV[2] = vector.len(row[2]); + row[2] = quaternion.normalize(row[2]); + skV[1] /= scV[2]; + skV[2] /= scV[2]; + + pdum3 = vector.cross(row[1], row[2]); + if (vector.dot(row[0], pdum3) < 0) { + for (i = 0; i < 3; i++) { + scV[i] *= -1; + row[i][0] *= -1; + row[i][1] *= -1; + row[i][2] *= -1; + } + } + + rV[0] = 0.5 * Math.sqrt(Math.max(1 + row[0][0] - row[1][1] - row[2][2], 0)); + rV[1] = 0.5 * Math.sqrt(Math.max(1 - row[0][0] + row[1][1] - row[2][2], 0)); + rV[2] = 0.5 * Math.sqrt(Math.max(1 - row[0][0] - row[1][1] + row[2][2], 0)); + rV[3] = 0.5 * Math.sqrt(Math.max(1 + row[0][0] + row[1][1] + row[2][2], 0)); + + if (row[2][1] > row[1][2]) rV[0] = -rV[0]; + if (row[0][2] > row[2][0]) rV[1] = -rV[1]; + if (row[1][0] > row[0][1]) rV[2] = -rV[2]; + + ret.translate = tV; + ret.rotate = rV; + ret.scale = scV; + ret.skew = skV; + ret.perspective = pV; + return true; + }, + + /** + * Decompose transformation matrix2d from matrix3d. + * @public + * @param {Number[]} matrix Matrix3d + * @param {Object} ret To store various transformation properties like translate, angle and matrix. + * @return {Boolean} ret To store various transformation properties like translate, angle and matrix. + */ + decompose2D: function(m, ret) { + var scale = [], + matrix = [], + row0x = m[0], + row0y = m[1], + row1x = m[4], + row1y = m[5], + det, angle, sn, cs, + m11, m12, m21, m22; + + ret = ret || {}; + scale = [ + Math.sqrt(row0x * row0x + row0y * row0y), + Math.sqrt(row1x * row1x + row1y * row1y) + ]; + + // If determinant is negative, one axis was flipped. + det = row0x * row1y - row0y * row1x; + if (det < 0) + // Flip axis with minimum unit vector dot product. + if (row0x < row1y) + scale[0] = -scale[0]; + else + scale[1] = -scale[1]; + + // Renormalize matrix to remove scale. + if (scale[0]) { + row0x *= 1 / scale[0]; + row0y *= 1 / scale[0]; + } + + if (scale[1]) { + row1x *= 1 / scale[1]; + row1y *= 1 / scale[1]; + } + ret.scale = scale; + + + // Compute rotation and renormalize matrix. + angle = Math.atan2(row0y, row0x); + + if (angle) { + sn = -row0y; + cs = row0x; + m11 = row0x; + m12 = row0y; + m21 = row1x; + m22 = row1y; + row0x = cs * m11 + sn * m21; + row0y = cs * m12 + sn * m22; + row1x = -sn * m11 + cs * m21; + row1y = -sn * m12 + cs * m22; + } + + // Rotate(-angle) = [cos(angle), sin(angle), -sin(angle), cos(angle)] + // = [row0x, -row0y, row0y, row0x] + // Thanks to the normalization above. + matrix[0] = row0x; + matrix[1] = row0y; + matrix[2] = row1x; + matrix[3] = row1y; + matrix[4] = m[12]; + matrix[5] = m[13]; + ret.matrix2D = matrix; + + // Convert into degrees because our rotation functions expect it. + ret.angle = angle * 180 / Math.PI; + + return ret; + }, + + /** + * Convert Matrix3d array to Matrix3d String + * @public + * @param {Number[]} m Matrix3d Array + * @return {String} Matrix3d String + */ + toString: function(m) { + var i, ms = m.length > 10 ? 'matrix3d(' : 'matrix('; + for (i = 0; i < m.length - 1; i++) { + ms += (m[i] < 0.000001 && m[i] > -0.000001) ? '0,' : m[i] + ','; + } + ms += m[m.length - 1] + ')'; + return ms; + } }; var vector = exports.Vector = { - /** - * Length of a vector - * @param {Number[]} v - vector - * @return {Number} resultant length - * @public - */ - len: function(v) { - return Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); - }, - - /** - * Divides vector with a scalar value. - * @param {Number[]} v - vector - * @param {Number} s - scalar value to divide - * @return {Number[]} resultant vector - * @public - */ - divide: function(v, s) { - var divideVector = new Float32Array([v[0] / s, v[1] / s, v[2] / s]); - return divideVector; - }, - - /** - * Dot product of 3D vectors - * @param {Number[]} v1 - vector - * @param {Number[]} v2 - vector - * @return {Number} resultant dot product - * @public - */ - dot: function(v1, v2) { - return (v1[0] * v2[0]) + (v1[1] * v2[1]) + (v1[2] * v2[2]) + (v1[3] !== undefined && v2[3] !== undefined ? (v1[3] * v2[3]) : 0); - }, - - /** - * Cross product of two vectors - * @param {Number[]} v1 - vector - * @param {Number[]} v2 - vector - * @return {Number[]} resultant cross product - * @public - */ - cross: function(v1, v2) { - var crossProdMat = new Float32Array([v1[1] * v2[2] - v1[2] * v2[1], v1[2] * v2[0] - v1[0] * v2[2], v1[0] * v2[1] - v1[1] * v2[0]]); - return crossProdMat; - }, - - /** - * Combine scalar values with two vectors. - * Required during parsing scaler values matrix. - * @param {Number[]} a - first vector - * @param {Number[]} b - second vector - * @param {Number[]} ascl - first vector scalar - * @param {Number[]} bscl - second vector scalar - * @return {Number[]} resultant vector - * @public - */ - combine: function(a, b, ascl, bscl) { - var combineMat = new Float32Array([(ascl * a[0]) + (bscl * b[0]), (ascl * a[1]) + (bscl * b[1]), (ascl * a[2]) + (bscl * b[2])]); - return combineMat; - - } + /** + * Length of a vector + * @param {Number[]} v - vector + * @return {Number} resultant length + * @public + */ + len: function(v) { + return Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); + }, + + /** + * Divides vector with a scalar value. + * @param {Number[]} v - vector + * @param {Number} s - scalar value to divide + * @return {Number[]} resultant vector + * @public + */ + divide: function(v, s) { + var divideVector = new Float32Array([v[0] / s, v[1] / s, v[2] / s]); + return divideVector; + }, + + /** + * Dot product of 3D vectors + * @param {Number[]} v1 - vector + * @param {Number[]} v2 - vector + * @return {Number} resultant dot product + * @public + */ + dot: function(v1, v2) { + return (v1[0] * v2[0]) + (v1[1] * v2[1]) + (v1[2] * v2[2]) + (v1[3] !== undefined && v2[3] !== undefined ? (v1[3] * v2[3]) : 0); + }, + + /** + * Cross product of two vectors + * @param {Number[]} v1 - vector + * @param {Number[]} v2 - vector + * @return {Number[]} resultant cross product + * @public + */ + cross: function(v1, v2) { + var crossProdMat = new Float32Array([v1[1] * v2[2] - v1[2] * v2[1], v1[2] * v2[0] - v1[0] * v2[2], v1[0] * v2[1] - v1[1] * v2[0]]); + return crossProdMat; + }, + + /** + * Combine scalar values with two vectors. + * Required during parsing scaler values matrix. + * @param {Number[]} a - first vector + * @param {Number[]} b - second vector + * @param {Number[]} ascl - first vector scalar + * @param {Number[]} bscl - second vector scalar + * @return {Number[]} resultant vector + * @public + */ + combine: function(a, b, ascl, bscl) { + var combineMat = new Float32Array([(ascl * a[0]) + (bscl * b[0]), (ascl * a[1]) + (bscl * b[1]), (ascl * a[2]) + (bscl * b[2])]); + return combineMat; + + } }; var quaternion = exports.Quaternion = { - /** - * Gives the direction of motion from one vector to other. - * Returns true if moving towards positive direction. - * @param {Number[]} q1 - quant - * @param {Number[]} q2 - quant - * @return {boolean} true if positive, false otherwise. - * @public - */ - direction: function(q1, q2) { - return (q1[0] - q2[0]) < 0 || (q1[1] - q2[1]) < 0 || (q1[2] - q2[2]) < 0; - }, - - /** - * Dot product of 3D quanterion - * @param {Number[]} q1 - quanterion - * @param {Number[]} q2 - quanterion - * @return {Number} resultant dot product - * @public - */ - quantDot: function(q1, q2) { - return (q1[0] * q2[0]) + (q1[1] * q2[1]) + (q1[2] * q2[2]) + (q1[3] * q2[3]); - }, - - multiplication: function(q1, q2) { - return [q2[0] * q1[0] - q2[1] * q1[1] - q2[2] * q1[2] - q2[3] * q1[3], - q2[0] * q1[1] + q2[1] * q1[0] - q2[2] * q1[3] + q2[3] * q1[2], - q2[0] * q1[2] + q2[1] * q1[3] + q2[2] * q1[0] - q2[3] * q1[1], - q2[0] * q1[3] - q2[1] * q1[2] + q2[2] * q1[1] + q2[3] * q1[0]]; - }, - - /** - * Normalizing a vector is obtaining another unit vector in the same direction. - * To normalize a vector, divide the vector by its magnitude. - * @param {Number[]} q1 - quanterion - * @return {Number[]} resultant quanterion - * @public - */ - normalize: function(q) { - return vector.divide(q, vector.len(q)); - }, - - /** - * Converts a rotation vector to a quaternion vector. - * @param {Number[]} v - vector - * @return {Number[]} resultant quaternion - * @public - */ - toQuant: function(v) { - if (!v) v = []; - var p = parseFloat(v[1] || 0) * Math.PI / 360, - y = parseFloat(v[2] || 0) * Math.PI / 360, - r = parseFloat(v[0] || 0) * Math.PI / 360, - c1 = Math.cos(p), - c2 = Math.cos(y), - c3 = Math.cos(r), - s1 = Math.sin(p), - s2 = Math.sin(y), - s3 = Math.sin(r), - q; - - q = new Float32Array([ - Math.round((s1 * s2 * c3 + c1 * c2 * s3) * 100000) / 100000, - Math.round((s1 * c2 * c3 + c1 * s2 * s3) * 100000) / 100000, - Math.round((c1 * s2 * c3 - s1 * c2 * s3) * 100000) / 100000, - Math.round((c1 * c2 * c3 - s1 * s2 * s3) * 100000) / 100000 - ]); - - return q; - } - //TODO: Acheive the same fucntionality for other 11 choices XYX, XZX, XZY, YXY, YXZ, YZX, YZY, ZXY, ZXZ, ZYX, ZYZ + /** + * Gives the direction of motion from one vector to other. + * Returns true if moving towards positive direction. + * @param {Number[]} q1 - quant + * @param {Number[]} q2 - quant + * @return {boolean} true if positive, false otherwise. + * @public + */ + direction: function(q1, q2) { + return (q1[0] - q2[0]) < 0 || (q1[1] - q2[1]) < 0 || (q1[2] - q2[2]) < 0; + }, + + /** + * Dot product of 3D quanterion + * @param {Number[]} q1 - quanterion + * @param {Number[]} q2 - quanterion + * @return {Number} resultant dot product + * @public + */ + quantDot: function(q1, q2) { + return (q1[0] * q2[0]) + (q1[1] * q2[1]) + (q1[2] * q2[2]) + (q1[3] * q2[3]); + }, + + multiplication: function(q1, q2) { + return [q2[0] * q1[0] - q2[1] * q1[1] - q2[2] * q1[2] - q2[3] * q1[3], + q2[0] * q1[1] + q2[1] * q1[0] - q2[2] * q1[3] + q2[3] * q1[2], + q2[0] * q1[2] + q2[1] * q1[3] + q2[2] * q1[0] - q2[3] * q1[1], + q2[0] * q1[3] - q2[1] * q1[2] + q2[2] * q1[1] + q2[3] * q1[0]]; + }, + + /** + * Normalizing a vector is obtaining another unit vector in the same direction. + * To normalize a vector, divide the vector by its magnitude. + * @param {Number[]} q1 - quanterion + * @return {Number[]} resultant quanterion + * @public + */ + normalize: function(q) { + return vector.divide(q, vector.len(q)); + }, + + /** + * Converts a rotation vector to a quaternion vector. + * @param {Number[]} v - vector + * @return {Number[]} resultant quaternion + * @public + */ + toQuant: function(v) { + if (!v) v = []; + var p = parseFloat(v[1] || 0) * Math.PI / 360, + y = parseFloat(v[2] || 0) * Math.PI / 360, + r = parseFloat(v[0] || 0) * Math.PI / 360, + c1 = Math.cos(p), + c2 = Math.cos(y), + c3 = Math.cos(r), + s1 = Math.sin(p), + s2 = Math.sin(y), + s3 = Math.sin(r), + q; + + q = new Float32Array([ + Math.round((s1 * s2 * c3 + c1 * c2 * s3) * 100000) / 100000, + Math.round((s1 * c2 * c3 + c1 * s2 * s3) * 100000) / 100000, + Math.round((c1 * s2 * c3 - s1 * c2 * s3) * 100000) / 100000, + Math.round((c1 * c2 * c3 - s1 * s2 * s3) * 100000) / 100000 + ]); + + return q; + } + //TODO: Acheive the same fucntionality for other 11 choices XYX, XZX, XZY, YXY, YXZ, YZX, YZY, ZXY, ZXZ, ZYX, ZYZ }; \ No newline at end of file diff --git a/src/tween.js b/src/tween.js index c52129aef..18bd5e934 100644 --- a/src/tween.js +++ b/src/tween.js @@ -464,9 +464,7 @@ function getAnimatedProperty(node, props, initial) { tP.rotate = tP.rotate ? transform.Quaternion.multiplication(tP.rotate, v) : v; } else { t = k.replace(/[XYZ]$/, ''); - tP[t] = tP[t] ? tP[t].map(function(num, id) { - return num + v[id]; - }) : v; + tP[t] = tP[t] ? merge(tP[t], v) : v; } if (k.match(/[XYZ]$/)) { t = k.replace(/[XYZ]$/, ''); @@ -502,6 +500,13 @@ function getAnimatedProperty(node, props, initial) { }; } +function merge (ar1, ar2) { + ar1.map(function(num, id) { + return num + ar2[id]; + }); + return ar1; +} + /** * Converts comma separated values to array. @@ -610,7 +615,7 @@ function toPropertyValue(prop, val, ret) { val = 'rgb(' + val.slice(0, 3).map(function(v) { return parseInt(v, 10); }) + ') ' + val.slice(3).map(function(v) { - return v + 'px' + return v + 'px'; }).join(' '); } else { val = val[0] + 'px'; From b8e81abd105747e57b2126cae90948c4b46747a5 Mon Sep 17 00:00:00 2001 From: Ankur Mishra Date: Fri, 20 May 2016 16:34:33 +0530 Subject: [PATCH 03/32] Merge latest changes from branch 'sceneapproach' Enyo-DCO-1.1-Signed-off-by: Ankur Mishra --- src/scene.js | 6 +++++- src/tween.js | 43 +++++++++++++++++++++++++------------------ 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/src/scene.js b/src/scene.js index fe5bebd27..e06b1f3fc 100644 --- a/src/scene.js +++ b/src/scene.js @@ -184,6 +184,8 @@ var scene = module.exports = function (actor, props) { if (props) { var anims = utils.isArray(props) ? props : [props]; for (var i = 0, anim; (anim = anims[i]); i++) { + if (anim.delay) + this.addAnimation({duration: anim.delay}, anim.delay); this.addAnimation(anim, anim.duration || 0); } } @@ -218,7 +220,9 @@ scene.prototype.action = function(ts, pose) { update(pose, this.actor, tm - past, pose.span - past); this.step && this.step(this.actor); } else { - this.timeline = this.repeat ? 0 : this.span; + if (typeof this.repeat === "boolean") + this.repeat = this.repeat ? Infinity : 1; + this.timeline = --this.repeat ? 0 : this.span; if(!this.repeat) this.cut(); } } diff --git a/src/tween.js b/src/tween.js index 18bd5e934..8a1c827f0 100644 --- a/src/tween.js +++ b/src/tween.js @@ -501,7 +501,7 @@ function getAnimatedProperty(node, props, initial) { } function merge (ar1, ar2) { - ar1.map(function(num, id) { + ar1.map(function(num, id) { return num + ar2[id]; }); return ar1; @@ -521,20 +521,20 @@ function formatCSSValues(val, prop, length) { if (typeof val === 'function') { return val; } + if (prop === 'duration' || prop === 'delay') { + val = 0; + } if (SHADOW[prop] || COLOR[prop]) { if (val === 'none') { - return Array(7).fill(0); - } - if (val.indexOf('rgb') === 0) { - res = stringToMatrix(val.split(')')[0].replace(/^\w*\(/, '').concat(val.split(')')[1].split(' ').join())); + val = Array(7).fill(0); + } else if (val.indexOf('rgb') === 0) { + val = val.split(')')[0].replace(/^\w*\(/, '').concat(val.split(')')[1].split(' ').join()); } else { - res = stringToMatrix(val.split('rgb(')[1].replace(')', ',').concat(val.split('rgb(')[0]).replace(/, $/, '')); + val = val.split('rgb(')[1].replace(')',',').concat(val.split('rgb(')[0]).replace(/, $/,''); } } - if (prop === 'duration') { - return 0; - } - return length ? res.concat(Array(length - res.length).fill(0)) : res; + res = stringToMatrix(val); + return length ? res.concat(Array(length - res.length).fill(0)): res; } function formatTransformValues(val, prop) { @@ -543,20 +543,26 @@ function formatTransformValues(val, prop) { case 'translateX': case 'rotateX': case 'skewX': - return [parseFloat(val, 10), 0, 0]; + res = [parseFloat(val, 10), 0, 0]; + break; case 'translateY': case 'rotateY': case 'skewY': - return [0, parseFloat(val, 10), 0]; + res = [0, parseFloat(val, 10), 0]; + break; case 'translateZ': case 'rotateZ': - return [0, 0, parseFloat(val, 10)]; + res = [0, 0, parseFloat(val, 10)]; + break; case 'scaleX': - return [parseFloat(val, 10), 1, 1]; + res = [parseFloat(val, 10), 1, 1]; + break; case 'scaleY': - return [1, parseFloat(val, 10), 1]; + res = [1, parseFloat(val, 10), 1]; + break; case 'scaleZ': - return [1, 1, parseFloat(val, 10)]; + res = [1, 1, parseFloat(val, 10)]; + break; case 'matrix': res = transform.Matrix.identity(); val = stringToMatrix(val.replace(/^\w*\(/, '').replace(')', '')); @@ -571,10 +577,11 @@ function formatTransformValues(val, prop) { if (val.length == 16) { res = val; } - return res; + break; default: - return stringToMatrix(val); + res = stringToMatrix(val); } + return res; } /** From 596829ff29a838ea23eb169c9e397d81d1915f73 Mon Sep 17 00:00:00 2001 From: Anish_Ramesan Date: Fri, 20 May 2016 21:05:05 +0530 Subject: [PATCH 04/32] updates with multiple scenes and sequence Enyo-DCO-1.1-Signed-off-by: Anish Ramesan anish.ramesan@lge.com --- src/kind.js | 17 ++++--- src/scene.js | 137 +++++++++++++++++++++++++++++---------------------- src/tween.js | 2 +- 3 files changed, 90 insertions(+), 66 deletions(-) diff --git a/src/kind.js b/src/kind.js index bc8f25e1e..465dbab50 100644 --- a/src/kind.js +++ b/src/kind.js @@ -521,13 +521,16 @@ exports.createFromKind = function (nom, param) { * @return {Object} A scene object */ exports.animate = function(proto, properties, opts) { - var i, ctor, s, - ctors = utils.isArray(proto) ? proto : [proto]; + var i, ctor, ps, s; + + if (!utils.isArray(proto)) { + return new scene(proto, properties, opts); + } - for (i = 0; (ctor = ctors[i]); i++) { - s = new scene(ctor, properties); - if (opts && opts.delay) opts.delay += opts.delay; - utils.mixin(s, opts); + ps = new scene(); + for (i = 0; (ctor = proto[i]); i++) { + s = new scene(ctor, properties, opts); + ps.addScene(s); } - return s; + return ps; }; \ No newline at end of file diff --git a/src/scene.js b/src/scene.js index e06b1f3fc..0553301a9 100644 --- a/src/scene.js +++ b/src/scene.js @@ -38,6 +38,10 @@ var AnimationSupport = { * @public */ seekInterval: 0, + /** + * @public + */ + isSequence: true, /** * Starts the animation of the actor given in argument. @@ -86,24 +90,6 @@ var AnimationSupport = { this.direction = -1; }, - /** - * Changes the speed of the animation.
- * Speed of the animation changed based on the factor.
- * To slow down the speed use values between 0 and 1. For Example 0.5 to reduce the speed by 50%.
- * To increase the speed use values above 1. For Example 2 to increase the speed by 200%.
- * Animation will be paused if factor is 0. To pause the animation use {@link enyo/AnimationSupport/Editor.pause pause} API.
- * Speed will not be affected incase of negative multiplication factor. - * @param {Number} factor Multiplication factor which changes the speed - * @param [Component {@link module:enyo/Component~Component}] actor The component whose animating speed should be changed - * @public - */ - // speed: function(mul, actor) { - // if (mul < 0) return; - // this.cache(actor); - // actor = actor || this; - // actor.speed *= mul; - // }, - /** * Stops the animation of the actor given in argument. * If actor is not provided, animation of all the components linked to the {@link module:enyo/AnimationSupport/Scene} will be stopped. @@ -172,7 +158,7 @@ var AnimationSupport = { * @wip * @private */ -var scene = module.exports = function (actor, props) { +var scene = module.exports = function (actor, props, opts) { this.id = utils.uid("@"); this.poses = []; this.rolePlays = []; @@ -180,6 +166,7 @@ var scene = module.exports = function (actor, props) { this.rAFId = animation.subscribe(this, loop); utils.mixin(this, AnimationSupport); + if (opts) utils.mixin(this, opts); if (props) { var anims = utils.isArray(props) ? props : [props]; @@ -190,34 +177,46 @@ var scene = module.exports = function (actor, props) { } } }; +scene.prototype.isActive = function () { + if (this.actor) + return this.actor.generated; + + // making sure parent scenes are always active. + return true; +}; scene.prototype.getAnimation = function (index) { return index < 0 || this.poses[index]; }; scene.prototype.addAnimation = function (newProp, span) { - var l = this.poses.length, old; + var l = this.poses.length, old, + newSpan = newProp instanceof this.constructor ? newProp.span : span; - if (l > 0) { + if (l > 0 && this.isSequence) { old = this.poses[l-1]; - span += old.span; + newSpan += old.span; } - this.poses.push({animate: newProp, span: span}); - this.span = span; + this.poses.push({animate: newProp, span: newSpan, dur: span}); + this.span = newSpan; }; scene.prototype.action = function(ts, pose) { - var past, index, tm, + var tm, i, poses, dur = this.span; - if (this.actor && this.actor.generated) { + if (this.isActive()) { tm = rolePlay(ts, this); if (isNaN(tm) || tm < 0) return pose; else if (tm <= dur) { - index = animateAtTime(this.poses, tm); - pose = this.poses[index]; - past = index ? this.poses[index - 1].span : 0; - update(pose, this.actor, tm - past, pose.span - past); + poses = posesAtTime(this.poses, tm); + for (i = 0, pose; (pose = poses[i]); i++) { + if (pose instanceof this.constructor) { + this.toScene(pose).action(ts); + } else { + update(pose, this.actor, (tm - (pose.span - pose.dur)), pose.dur); + } + } this.step && this.step(this.actor); } else { if (typeof this.repeat === "boolean") @@ -241,22 +240,35 @@ scene.prototype.cut = function () { this.completed && this.completed(this.actor); }; -scene.prototype.addScene = function (scene) { - this.span = scene.span + this.span; - this.rolePlays.push({ - scene: scene, - span: this.span, - dur: scene.span - }); +scene.prototype.toScene = function (scene) { + scene.speed = this.speed; + scene.direction = this.direction; + scene.handleLayers = this.handleLayers; + return scene; }; +scene.prototype.addScene = function (sc) { + var l = this.poses.length, old, + newSpan = sc instanceof this.constructor ? sc.span : 0; + + if (l > 0 && this.isSequence) { + old = this.poses[l-1]; + newSpan += old.span; + sc.span = newSpan; + } + this.poses.push(sc); + this.span = newSpan; +}; + + + function loop (was, is) { if (this.animating) { _ts = is - (was || 0); _ts = (_ts > _framerate) ? _framerate : _ts; this.action(_ts); - } else if(this.actor.destroyed) { + } else if (this.actor && this.actor.destroyed) { animation.unsubscribe(this.rAFId); } } @@ -311,23 +323,32 @@ function rolePlay (t, actor) { * @return {number} - index of the animation * @private */ -function animateAtTime (anims, span) { - var startIndex = 0, - stopIndex = anims.length - 1, - middle = Math.floor((stopIndex + startIndex) / 2); - - if (span === 0) { - return startIndex; - } - - while (anims[middle].span != span && startIndex < stopIndex) { - if (span < anims[middle].span) { - stopIndex = middle; - } else if (span > anims[middle].span) { - startIndex = middle + 1; - } - - middle = Math.floor((stopIndex + startIndex) / 2); - } - return (anims[middle].span != span) ? startIndex : middle; -} \ No newline at end of file +// function animateAtTime (anims, span) { +// var startIndex = 0, +// stopIndex = anims.length - 1, +// middle = Math.floor((stopIndex + startIndex) / 2); + +// if (span === 0) { +// return startIndex; +// } + +// while (anims[middle].span != span && startIndex < stopIndex) { +// if (span < anims[middle].span) { +// stopIndex = middle; +// } else if (span > anims[middle].span) { +// startIndex = middle + 1; +// } + +// middle = Math.floor((stopIndex + startIndex) / 2); +// } +// return (anims[middle].span != span) ? startIndex : middle; +// } + +function posesAtTime(anims, span) { + function doFilter(val, idx, ar) { + if(idx === 0) + return span <= val.span; + return span > ar[idx -1].span && span <= val.span; + }; + return anims.filter(doFilter); +} diff --git a/src/tween.js b/src/tween.js index 8a1c827f0..a5cc78597 100644 --- a/src/tween.js +++ b/src/tween.js @@ -53,7 +53,7 @@ module.exports = { if (pose.props) { for (k in pose.props) { - if (!pose._endAnim[k] || k === 'duration' || k === 'ease') { + if (!pose._endAnim[k] || k === 'duration' || k === 'ease' || k === 'path') { continue; } From 8dd854a1f0cefb3373469b4af7df36d972dc0c12 Mon Sep 17 00:00:00 2001 From: "srirama.singeri" Date: Mon, 23 May 2016 20:47:57 +0530 Subject: [PATCH 05/32] Change the observer implementation from array to object Enyo-DCO-1.1-Signed-off-by: Srirama Singeri srirama.singeri@lge.com --- src/animation.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/animation.js b/src/animation.js index 68453dcbb..2d56f8779 100644 --- a/src/animation.js +++ b/src/animation.js @@ -16,7 +16,7 @@ var ms = Math.round(1000/60), cAF = 'cancelAnimationFrame', i, pl, p, wcRAF, wrAF, wcAF, _requestFrame, _cancelFrame, cancelFrame, - core = { ts: 0, obs: []}; + core = { ts: 0, obs: {}}; /* @@ -108,8 +108,9 @@ exports.cancelAnimationFrame = function(id) { * @public */ exports.subscribe = function(ctx,callback) { - core.obs.push(utils.bindSafely(ctx, callback)); - return core.obs.length -1; + var id = utils.uid("rAF"); + core.obs[id]=utils.bindSafely(ctx, callback); + return id; }; /** * Unsubcribes for animation frame ticks. @@ -119,7 +120,7 @@ exports.subscribe = function(ctx,callback) { * @public */ exports.unsubscribe = function(id) { - core.obs.splice(id, 1); + delete core.obs[id]; }; var startrAF = function(){ @@ -190,8 +191,8 @@ Object.defineProperty(core, 'ts', { }, set: function(newValue) { - for (var i = 0, ob; (ob = this.obs[i]); i++) { - ob(this.value, newValue); + for(var i in this.obs){ + this.obs[i](this.value, newValue); } this.value = newValue; } From 1c233ddb6c6b80c295371aaba24c2f5e7b70c65f Mon Sep 17 00:00:00 2001 From: Ankur Mishra Date: Tue, 24 May 2016 14:15:48 +0530 Subject: [PATCH 06/32] Fix bug in animation repeat and introduce fillmode Enyo-DCO-1.1-Signed-off-by: Ankur Mishra --- src/scene.js | 64 +++++++++++++++++++++++++++------------------------- src/tween.js | 18 +++++++++++---- 2 files changed, 47 insertions(+), 35 deletions(-) diff --git a/src/scene.js b/src/scene.js index 0553301a9..1a21c74f0 100644 --- a/src/scene.js +++ b/src/scene.js @@ -212,17 +212,24 @@ scene.prototype.action = function(ts, pose) { poses = posesAtTime(this.poses, tm); for (i = 0, pose; (pose = poses[i]); i++) { if (pose instanceof this.constructor) { - this.toScene(pose).action(ts); - } else { + this.toScene(pose).action(ts); + } else { update(pose, this.actor, (tm - (pose.span - pose.dur)), pose.dur); } } this.step && this.step(this.actor); } else { if (typeof this.repeat === "boolean") - this.repeat = this.repeat ? Infinity : 1; - this.timeline = --this.repeat ? 0 : this.span; - if(!this.repeat) this.cut(); + this.repeat = this.repeat ? Infinity : 1; + this.timeline = --this.repeat ? 0 : this.span; + if (this.repeat) { + this.actor.addStyles(this.actor.initalState); + } else { + if (this.fillmode === "backwards") { + this.actor.addStyles(this.actor.initalState); + } + this.cut(); + } } } return pose; @@ -269,7 +276,7 @@ function loop (was, is) { _ts = (_ts > _framerate) ? _framerate : _ts; this.action(_ts); } else if (this.actor && this.actor.destroyed) { - animation.unsubscribe(this.rAFId); + animation.unsubscribe(this.rAFId); } } @@ -297,12 +304,7 @@ function rolePlay (t, actor) { actor = actor || this; t = t * actor.speed * actor.direction; - if(actor.delay > 0) { - actor.delay -= t; - } else { - actor.timeline += t; - } - + actor.timeline += t; if(actor.seekInterval !== 0) { if((actor.seekInterval-actor.timeline)*actor.speed < 0) { actor.seekInterval = 0; @@ -324,24 +326,24 @@ function rolePlay (t, actor) { * @private */ // function animateAtTime (anims, span) { -// var startIndex = 0, -// stopIndex = anims.length - 1, -// middle = Math.floor((stopIndex + startIndex) / 2); - -// if (span === 0) { -// return startIndex; -// } - -// while (anims[middle].span != span && startIndex < stopIndex) { -// if (span < anims[middle].span) { -// stopIndex = middle; -// } else if (span > anims[middle].span) { -// startIndex = middle + 1; -// } - -// middle = Math.floor((stopIndex + startIndex) / 2); -// } -// return (anims[middle].span != span) ? startIndex : middle; +// var startIndex = 0, +// stopIndex = anims.length - 1, +// middle = Math.floor((stopIndex + startIndex) / 2); + +// if (span === 0) { +// return startIndex; +// } + +// while (anims[middle].span != span && startIndex < stopIndex) { +// if (span < anims[middle].span) { +// stopIndex = middle; +// } else if (span > anims[middle].span) { +// startIndex = middle + 1; +// } + +// middle = Math.floor((stopIndex + startIndex) / 2); +// } +// return (anims[middle].span != span) ? startIndex : middle; // } function posesAtTime(anims, span) { @@ -350,5 +352,5 @@ function posesAtTime(anims, span) { return span <= val.span; return span > ar[idx -1].span && span <= val.span; }; - return anims.filter(doFilter); + return anims.filter(doFilter); } diff --git a/src/tween.js b/src/tween.js index a5cc78597..f7c62e9fa 100644 --- a/src/tween.js +++ b/src/tween.js @@ -22,10 +22,16 @@ module.exports = { * @private */ init: function(actor, pose, initial) { + var k; + actor.initalState = actor.initalState || {}; if (!(actor && pose && pose.animate)) return; node = actor.hasNode(); - utils.mixin(pose, getAnimatedProperty(node, pose.animate, initial || actor.currentState)); + utils.mixin(pose, getAnimatedProperty(node, pose.animate, initial)); actor.currentState = pose.currentState; + for (k in pose.initalState) { + if (k !== "delay" && k !== "duration") + actor.initalState[k] = actor.initalState[k] || pose.initalState[k]; + } return pose; }, @@ -46,7 +52,7 @@ module.exports = { var k; domCSS = {}; node = actor.hasNode(); - state = actor.currentState = actor.currentState || pose.currentState || {}; + state = utils.clone(pose.currentState || pose._startAnim); points = pose.controlPoints = pose.controlPoints || {}; ease = pose.animate && pose.animate.ease ? pose.animate.ease : this.ease; path = pose.animate && pose.animate.path; @@ -99,14 +105,14 @@ module.exports = { state.perspective ); state.matrix = matrix; - actor.currentState = pose.currentState = state; + pose.currentState = state; domCSS = toTransformValue(matrix, domCSS); actor.addStyles(domCSS); }, halt: function(actor, pose) { - var matrix = actor.currentState && actor.currentState.matrix; + var matrix = pose.currentState && pose.currentState.matrix; pose = transform.Matrix.decompose2D(matrix); domCSS = toTransformValue(pose.matrix2D); @@ -448,6 +454,7 @@ function getAnimatedProperty(node, props, initial) { sP = initial ? utils.mixin({}, initial) : {}, tP = {}, dP = {}, + iP = {}, m, k, v, t, s = initial ? undefined : dom.getComputedStyle(node); @@ -455,6 +462,7 @@ function getAnimatedProperty(node, props, initial) { v = sP[k]; if (!isTransform(k)) { v = v || getStyleValue(s || dom.getComputedStyle(node), k); + iP[k] = v; sP[k] = formatCSSValues(v, k); eP[k] = formatCSSValues(props[k], k, sP[k] ? sP[k].length : sP[k]); } else { @@ -484,6 +492,7 @@ function getAnimatedProperty(node, props, initial) { m = getStyleValue(s || dom.getComputedStyle(node), dom.getCssTransformProp()); m = formatTransformValues(m, 'matrix'); transform.Matrix.decompose(m, dP); + iP.transform = "matrix3d("+m.toString()+")"; } for (k in dP) { @@ -495,6 +504,7 @@ function getAnimatedProperty(node, props, initial) { _endAnim: eP, _transform: dP, currentState: dP, + initalState: iP, matrix: m, props: props }; From 5806beaf342ce90aecca742857ddfe158cab5b2d Mon Sep 17 00:00:00 2001 From: Anish_Ramesan Date: Tue, 24 May 2016 16:03:26 +0530 Subject: [PATCH 07/32] sequence updates Enyo-DCO-1.1-Signed-off-by: Anish Ramesan --- src/kind.js | 5 +++-- src/scene.js | 50 +++++++++++++++----------------------------------- 2 files changed, 18 insertions(+), 37 deletions(-) diff --git a/src/kind.js b/src/kind.js index 465dbab50..ca25caef9 100644 --- a/src/kind.js +++ b/src/kind.js @@ -429,7 +429,7 @@ exports.concatHandler = function (ctor, props, instance) { base = base.prototype.base; } - // install common statics + // construct scene if (props.scene) { sctor = new scene(proto, props.scene); proto.scene = sctor; @@ -528,8 +528,9 @@ exports.animate = function(proto, properties, opts) { } ps = new scene(); + if (opts) utils.mixin(ps, opts); for (i = 0; (ctor = proto[i]); i++) { - s = new scene(ctor, properties, opts); + s = new scene(ctor, properties); ps.addScene(s); } return ps; diff --git a/src/scene.js b/src/scene.js index 1a21c74f0..f082fbc98 100644 --- a/src/scene.js +++ b/src/scene.js @@ -177,6 +177,7 @@ var scene = module.exports = function (actor, props, opts) { } } }; + scene.prototype.isActive = function () { if (this.actor) return this.actor.generated; @@ -190,14 +191,14 @@ scene.prototype.getAnimation = function (index) { }; scene.prototype.addAnimation = function (newProp, span) { - var l = this.poses.length, old, + var l = this.poses.length, old = 0, newSpan = newProp instanceof this.constructor ? newProp.span : span; if (l > 0 && this.isSequence) { - old = this.poses[l-1]; - newSpan += old.span; + old = this.poses[l-1].span; + newSpan += old; } - this.poses.push({animate: newProp, span: newSpan, dur: span}); + this.poses.push({animate: newProp, span: newSpan, begin: old }); this.span = newSpan; }; @@ -212,9 +213,9 @@ scene.prototype.action = function(ts, pose) { poses = posesAtTime(this.poses, tm); for (i = 0, pose; (pose = poses[i]); i++) { if (pose instanceof this.constructor) { - this.toScene(pose).action(ts); - } else { - update(pose, this.actor, (tm - (pose.span - pose.dur)), pose.dur); + this.toScene(pose).action(ts); + } else { + update(pose, this.actor, (tm - pose.begin), (pose.span - pose.begin)); } } this.step && this.step(this.actor); @@ -256,14 +257,16 @@ scene.prototype.toScene = function (scene) { scene.prototype.addScene = function (sc) { - var l = this.poses.length, old, + var l = this.poses.length, old = 0, newSpan = sc instanceof this.constructor ? sc.span : 0; if (l > 0 && this.isSequence) { - old = this.poses[l-1]; - newSpan += old.span; + old = this.poses[l-1].span; + newSpan += old; sc.span = newSpan; + sc.begin = old; } + this.poses.push(sc); this.span = newSpan; }; @@ -325,32 +328,9 @@ function rolePlay (t, actor) { * @return {number} - index of the animation * @private */ -// function animateAtTime (anims, span) { -// var startIndex = 0, -// stopIndex = anims.length - 1, -// middle = Math.floor((stopIndex + startIndex) / 2); - -// if (span === 0) { -// return startIndex; -// } - -// while (anims[middle].span != span && startIndex < stopIndex) { -// if (span < anims[middle].span) { -// stopIndex = middle; -// } else if (span > anims[middle].span) { -// startIndex = middle + 1; -// } - -// middle = Math.floor((stopIndex + startIndex) / 2); -// } -// return (anims[middle].span != span) ? startIndex : middle; -// } - function posesAtTime(anims, span) { function doFilter(val, idx, ar) { - if(idx === 0) - return span <= val.span; - return span > ar[idx -1].span && span <= val.span; - }; + return span > (val.begin || 0) && span <= val.span; + } return anims.filter(doFilter); } From f7a0b7c5c203d17b9f1c2c6ec78ebffb2a65eda8 Mon Sep 17 00:00:00 2001 From: Madala Cholan Satyanarayana Date: Fri, 27 May 2016 20:32:27 +0530 Subject: [PATCH 08/32] Added setAnimation feature to FW --- src/scene.js | 107 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 84 insertions(+), 23 deletions(-) diff --git a/src/scene.js b/src/scene.js index f082fbc98..4942892d7 100644 --- a/src/scene.js +++ b/src/scene.js @@ -168,14 +168,15 @@ var scene = module.exports = function (actor, props, opts) { utils.mixin(this, AnimationSupport); if (opts) utils.mixin(this, opts); - if (props) { - var anims = utils.isArray(props) ? props : [props]; - for (var i = 0, anim; (anim = anims[i]); i++) { - if (anim.delay) - this.addAnimation({duration: anim.delay}, anim.delay); - this.addAnimation(anim, anim.duration || 0); - } - } + if (props) { + var anims = utils.isArray(props) ? props : [props]; + for (var i = 0, anim; + (anim = anims[i]); i++) { + if (anim.delay) + this.addAnimation({ duration: anim.delay }, anim.delay); + this.addAnimation(anim, anim.duration || 0); + } + } }; scene.prototype.isActive = function () { @@ -186,13 +187,71 @@ scene.prototype.isActive = function () { return true; }; -scene.prototype.getAnimation = function (index) { - return index < 0 || this.poses[index]; +function modify(pose, currentTm) { + pose.span = currentTm; + delete pose._endAnim; + pose._endAnim = pose.currentState; + return pose; +}; + +function currPose(poseArr, tm, properties) { + var currentTime = tm; + for (var i = 0; i < poseArr.length; i++) { + + if (poseArr[i].begin <= currentTime && poseArr[i].span >= currentTime) { // check the current Pose + modify(poseArr[i], currentTime); + poseArr.splice((i + 1), poseArr.length - (i + 1)); + poseArr[(i + 1)] = { + animate: properties, + begin: currentTime, + span: currentTime + properties.duration + }; + break; + } + } +}; + +function hasPosesCheck(poseArr) { + var bool; + for (var i = 0; i < poseArr.length; i++) { + bool = poseArr[i].poses ? true : false; + if (bool === true) { + break; + } + } + return bool; +}; + +function loopPose(poseArr, tm, properties) { + var isArrayCheck, hasPoses; + isArrayCheck = utils.isArray(poseArr); + hasPoses = hasPosesCheck(poseArr); + + if (isArrayCheck === true && hasPoses === true) { + for (var i = 0; i < poseArr.length; i++) { + loopPose(poseArr[i].poses, tm, properties); + } + } else if (isArrayCheck === true && hasPoses === false) { + currPose(poseArr, tm, properties); + } +}; + + +scene.prototype.setAnimation = function(properties) { + var currentTime, currentPose; + currentTime = this.timeline; // current time + posesList = this.poses; // gets the poses + loopPose(posesList, currentTime, properties); +}; + +scene.prototype.getAnimation = function(index) { + return index < 0 || this.poses[index]; }; -scene.prototype.addAnimation = function (newProp, span) { - var l = this.poses.length, old = 0, - newSpan = newProp instanceof this.constructor ? newProp.span : span; +scene.prototype.addAnimation = function(newProp, span) { + var l = this.poses.length, + old = 0, + newSpan = newProp instanceof this.constructor ? newProp.span : span; if (l > 0 && this.isSequence) { old = this.poses[l-1].span; @@ -206,13 +265,14 @@ scene.prototype.action = function(ts, pose) { var tm, i, poses, dur = this.span; - if (this.isActive()) { - tm = rolePlay(ts, this); - if (isNaN(tm) || tm < 0) return pose; - else if (tm <= dur) { - poses = posesAtTime(this.poses, tm); - for (i = 0, pose; (pose = poses[i]); i++) { - if (pose instanceof this.constructor) { + if (this.isActive()) { + tm = rolePlay(ts, this); + if (isNaN(tm) || tm < 0) return pose; + else if (tm <= dur) { + poses = posesAtTime(this.poses, tm); + for (i = 0, pose; + (pose = poses[i]); i++) { + if (pose instanceof this.constructor) { this.toScene(pose).action(ts); } else { update(pose, this.actor, (tm - pose.begin), (pose.span - pose.begin)); @@ -256,9 +316,10 @@ scene.prototype.toScene = function (scene) { }; -scene.prototype.addScene = function (sc) { - var l = this.poses.length, old = 0, - newSpan = sc instanceof this.constructor ? sc.span : 0; +scene.prototype.addScene = function(sc) { + var l = this.poses.length, + old = 0, + newSpan = sc instanceof this.constructor ? sc.span : 0; if (l > 0 && this.isSequence) { old = this.poses[l-1].span; From c1bf240085610d4e9f8c93246f668c10149823ac Mon Sep 17 00:00:00 2001 From: Ankur Mishra Date: Mon, 30 May 2016 15:53:15 +0530 Subject: [PATCH 09/32] Fix some coding issue Enyo-DCO-1.1-Signed-off-by: Ankur Mishra --- src/scene.js | 150 +++++++++++++++++++++++++++------------------------ src/tween.js | 5 +- 2 files changed, 82 insertions(+), 73 deletions(-) diff --git a/src/scene.js b/src/scene.js index 4942892d7..224782ae5 100644 --- a/src/scene.js +++ b/src/scene.js @@ -168,15 +168,14 @@ var scene = module.exports = function (actor, props, opts) { utils.mixin(this, AnimationSupport); if (opts) utils.mixin(this, opts); - if (props) { - var anims = utils.isArray(props) ? props : [props]; - for (var i = 0, anim; - (anim = anims[i]); i++) { - if (anim.delay) - this.addAnimation({ duration: anim.delay }, anim.delay); - this.addAnimation(anim, anim.duration || 0); - } - } + if (props) { + var anims = utils.isArray(props) ? props : [props]; + for (var i = 0, anim; + (anim = anims[i]); i++) { + if (anim.delay) this.addAnimation({}, anim.delay); + this.addAnimation(anim, anim.duration || 0); + } + } }; scene.prototype.isActive = function () { @@ -188,70 +187,70 @@ scene.prototype.isActive = function () { }; function modify(pose, currentTm) { - pose.span = currentTm; - delete pose._endAnim; - pose._endAnim = pose.currentState; - return pose; + pose.span = currentTm; + delete pose._endAnim; + pose._endAnim = pose.currentState; + return pose; }; function currPose(poseArr, tm, properties) { - var currentTime = tm; - for (var i = 0; i < poseArr.length; i++) { - - if (poseArr[i].begin <= currentTime && poseArr[i].span >= currentTime) { // check the current Pose - modify(poseArr[i], currentTime); - poseArr.splice((i + 1), poseArr.length - (i + 1)); - poseArr[(i + 1)] = { - animate: properties, - begin: currentTime, - span: currentTime + properties.duration - }; - break; - } - } + var currentTime = tm; + for (var i = 0; i < poseArr.length; i++) { + + if (poseArr[i].begin <= currentTime && poseArr[i].span >= currentTime) { // check the current Pose + modify(poseArr[i], currentTime); + poseArr.splice((i + 1), poseArr.length - (i + 1)); + poseArr[(i + 1)] = { + animate: properties, + begin: currentTime, + span: currentTime + properties.duration + }; + break; + } + } }; function hasPosesCheck(poseArr) { - var bool; - for (var i = 0; i < poseArr.length; i++) { - bool = poseArr[i].poses ? true : false; - if (bool === true) { - break; - } - } - return bool; + var bool; + for (var i = 0; i < poseArr.length; i++) { + bool = poseArr[i].poses ? true : false; + if (bool === true) { + break; + } + } + return bool; }; function loopPose(poseArr, tm, properties) { - var isArrayCheck, hasPoses; - isArrayCheck = utils.isArray(poseArr); - hasPoses = hasPosesCheck(poseArr); - - if (isArrayCheck === true && hasPoses === true) { - for (var i = 0; i < poseArr.length; i++) { - loopPose(poseArr[i].poses, tm, properties); - } - } else if (isArrayCheck === true && hasPoses === false) { - currPose(poseArr, tm, properties); - } + var isArrayCheck, hasPoses; + isArrayCheck = utils.isArray(poseArr); + hasPoses = hasPosesCheck(poseArr); + + if (isArrayCheck === true && hasPoses === true) { + for (var i = 0; i < poseArr.length; i++) { + loopPose(poseArr[i].poses, tm, properties); + } + } else if (isArrayCheck === true && hasPoses === false) { + currPose(poseArr, tm, properties); + } }; scene.prototype.setAnimation = function(properties) { - var currentTime, currentPose; - currentTime = this.timeline; // current time - posesList = this.poses; // gets the poses - loopPose(posesList, currentTime, properties); + var currentTime, currentPose; + currentTime = this.timeline; // current time + posesList = this.poses; // gets the poses + loopPose(posesList, currentTime, properties); }; scene.prototype.getAnimation = function(index) { - return index < 0 || this.poses[index]; + return index < 0 || this.poses[index]; }; scene.prototype.addAnimation = function(newProp, span) { - var l = this.poses.length, - old = 0, - newSpan = newProp instanceof this.constructor ? newProp.span : span; + var l = this.poses.length, + old = 0, + newSpan = newProp instanceof this.constructor ? newProp.span : span; if (l > 0 && this.isSequence) { old = this.poses[l-1].span; @@ -265,28 +264,27 @@ scene.prototype.action = function(ts, pose) { var tm, i, poses, dur = this.span; - if (this.isActive()) { - tm = rolePlay(ts, this); - if (isNaN(tm) || tm < 0) return pose; - else if (tm <= dur) { - poses = posesAtTime(this.poses, tm); - for (i = 0, pose; - (pose = poses[i]); i++) { - if (pose instanceof this.constructor) { - this.toScene(pose).action(ts); - } else { + if (this.isActive()) { + tm = rolePlay(ts, this); + if (isNaN(tm) || tm < 0) return pose; + else if (tm <= dur) { + poses = posesAtTime(this.poses, tm); + for (i = 0, pose; + (pose = poses[i]); i++) { + if (pose instanceof this.constructor) { + this.toScene(pose).action(ts); + } else { update(pose, this.actor, (tm - pose.begin), (pose.span - pose.begin)); } } this.step && this.step(this.actor); } else { - if (typeof this.repeat === "boolean") - this.repeat = this.repeat ? Infinity : 1; + this.repeat = REPEAT[this.repeat] || this.repeat; this.timeline = --this.repeat ? 0 : this.span; if (this.repeat) { this.actor.addStyles(this.actor.initalState); } else { - if (this.fillmode === "backwards") { + if (FILLMODE[this.fillmode]) { this.actor.addStyles(this.actor.initalState); } this.cut(); @@ -317,9 +315,9 @@ scene.prototype.toScene = function (scene) { scene.prototype.addScene = function(sc) { - var l = this.poses.length, - old = 0, - newSpan = sc instanceof this.constructor ? sc.span : 0; + var l = this.poses.length, + old = 0, + newSpan = sc instanceof this.constructor ? sc.span : 0; if (l > 0 && this.isSequence) { old = this.poses[l-1].span; @@ -395,3 +393,15 @@ function posesAtTime(anims, span) { } return anims.filter(doFilter); } + +var + REPEAT = { + 'true': Infinity, + 'false': 1 + }, + FILLMODE = { + 'backwards': true, + 'forwards': false, + 'default': false, + 'none': false + }; \ No newline at end of file diff --git a/src/tween.js b/src/tween.js index f7c62e9fa..2d697ae68 100644 --- a/src/tween.js +++ b/src/tween.js @@ -29,8 +29,7 @@ module.exports = { utils.mixin(pose, getAnimatedProperty(node, pose.animate, initial)); actor.currentState = pose.currentState; for (k in pose.initalState) { - if (k !== "delay" && k !== "duration") - actor.initalState[k] = actor.initalState[k] || pose.initalState[k]; + actor.initalState[k] = actor.initalState[k] || pose.initalState[k]; } return pose; }, @@ -492,7 +491,7 @@ function getAnimatedProperty(node, props, initial) { m = getStyleValue(s || dom.getComputedStyle(node), dom.getCssTransformProp()); m = formatTransformValues(m, 'matrix'); transform.Matrix.decompose(m, dP); - iP.transform = "matrix3d("+m.toString()+")"; + iP.transform = transform.Matrix.toString(m); } for (k in dP) { From de4929717e96eff3f2b0f52e8723c5f2fd2488f4 Mon Sep 17 00:00:00 2001 From: Madala Cholan Satyanarayana Date: Tue, 31 May 2016 19:44:39 +0530 Subject: [PATCH 10/32] Added sceneSupport mixin --- src/kind.js | 225 ++++++++++++++++++++++---------------------- src/sceneSupport.js | 20 ++++ 2 files changed, 131 insertions(+), 114 deletions(-) create mode 100644 src/sceneSupport.js diff --git a/src/kind.js b/src/kind.js index ca25caef9..ede434d7a 100644 --- a/src/kind.js +++ b/src/kind.js @@ -241,30 +241,31 @@ kind.inherited = function (originals, replacements) { var target = originals.callee; var fn = target._inherited; - // regardless of how we got here, just ensure we actually - // have a function to call or else we throw a console - // warning to notify developers they are calling a - // super method that doesn't exist - if ('function' === typeof fn) { - var args = originals; - if (replacements) { - // combine the two arrays, with the replacements taking the first - // set of arguments, and originals filling up the rest. - args = []; - var i = 0, l = replacements.length; - for (; i < l; ++i) { - args[i] = replacements[i]; - } - l = originals.length; - for (; i < l; ++i) { - args[i] = originals[i]; - } - } - return fn.apply(this, args); - } else { - logger.warn('enyo.kind.inherited: unable to find requested ' + - 'super-method from -> ' + originals.callee.displayName + ' in ' + this.kindName); - } + // regardless of how we got here, just ensure we actually + // have a function to call or else we throw a console + // warning to notify developers they are calling a + // super method that doesn't exist + if ('function' === typeof fn) { + var args = originals; + if (replacements) { + // combine the two arrays, with the replacements taking the first + // set of arguments, and originals filling up the rest. + args = []; + var i = 0, + l = replacements.length; + for (; i < l; ++i) { + args[i] = replacements[i]; + } + l = originals.length; + for (; i < l; ++i) { + args[i] = originals[i]; + } + } + return fn.apply(this, args); + } else { + logger.warn('enyo.kind.inherited: unable to find requested ' + + 'super-method from -> ' + originals.callee.displayName + ' in ' + this.kindName); + } }; // dcl inspired super-inheritance @@ -351,47 +352,48 @@ kind.statics = { */ subclass: function (ctor, props) {}, - /** - * Allows for extension of the current [kind]{@glossary kind} without - * creating a new kind. This method is available on all - * [constructors]{@glossary constructor}, although calling it on a - * [deferred]{@glossary deferred} constructor will force it to be - * resolved at that time. This method does not re-run the - * {@link module:enyo/kind.features} against the constructor or instance. - * - * @name module:enyo/kind.extend - * @method - * @param {Object|Object[]} props A [hash]{@glossary Object} or [array]{@glossary Array} - * of [hashes]{@glossary Object}. Properties will override - * [prototype]{@glossary Object.prototype} properties. If a - * method that is being added already exists, the new method will - * supersede the existing one. The method may call - * `this.inherited()` or be wrapped with `kind.inherit()` to call - * the original method (this chains multiple methods tied to a - * single [kind]{@glossary kind}). - * @param {Object} [target] - The instance to be extended. If this is not specified, then the - * [constructor]{@glossary constructor} of the - * [object]{@glossary Object} this method is being called on will - * be extended. - * @returns {Object} The constructor of the class, or specific - * instance, that has been extended. - * @public - */ - extend: function (props, target) { - var ctor = this - , exts = utils.isArray(props)? props: [props] - , proto, fn; + /** + * Allows for extension of the current [kind]{@glossary kind} without + * creating a new kind. This method is available on all + * [constructors]{@glossary constructor}, although calling it on a + * [deferred]{@glossary deferred} constructor will force it to be + * resolved at that time. This method does not re-run the + * {@link module:enyo/kind.features} against the constructor or instance. + * + * @name module:enyo/kind.extend + * @method + * @param {Object|Object[]} props A [hash]{@glossary Object} or [array]{@glossary Array} + * of [hashes]{@glossary Object}. Properties will override + * [prototype]{@glossary Object.prototype} properties. If a + * method that is being added already exists, the new method will + * supersede the existing one. The method may call + * `this.inherited()` or be wrapped with `kind.inherit()` to call + * the original method (this chains multiple methods tied to a + * single [kind]{@glossary kind}). + * @param {Object} [target] - The instance to be extended. If this is not specified, then the + * [constructor]{@glossary constructor} of the + * [object]{@glossary Object} this method is being called on will + * be extended. + * @returns {Object} The constructor of the class, or specific + * instance, that has been extended. + * @public + */ + extend: function(props, target) { + var ctor = this, + exts = utils.isArray(props) ? props : [props], + proto, fn; fn = function (key, value) { return !(typeof value == 'function' || isInherited(value)) && concatenated.indexOf(key) === -1; }; - proto = target || ctor.prototype; - for (var i=0, ext; (ext=exts[i]); ++i) { - kind.concatHandler(proto, ext, true); - kind.extendMethods(proto, ext, true); - utils.mixin(proto, ext, {filter: fn}); - } + proto = target || ctor.prototype; + for (var i = 0, ext; + (ext = exts[i]); ++i) { + kind.concatHandler(proto, ext, true); + kind.extendMethods(proto, ext, true); + utils.mixin(proto, ext, { filter: fn }); + } return target || ctor; }, @@ -417,24 +419,19 @@ kind.statics = { }; /** -* @method -* @private -*/ -exports.concatHandler = function (ctor, props, instance) { - var proto = ctor.prototype || ctor, - base = proto.ctor, sctor; + * @method + * @private + */ +exports.concatHandler = function(ctor, props, instance) { - while (base) { - if (base.concat) base.concat(ctor, props, instance); - base = base.prototype.base; - } + var proto = ctor.prototype || ctor, + base = proto.ctor, + sctor; - // construct scene - if (props.scene) { - sctor = new scene(proto, props.scene); - proto.scene = sctor; - delete props.scene; - } + while (base) { + if (base.concat) base.concat(ctor, props, instance); + base = base.prototype.base; + } }; var kindCtors = @@ -448,33 +445,32 @@ var kindCtors = exports._kindCtors = {}; /** -* @method -* @private -*/ -var constructorForKind = exports.constructorForKind = function (kind) { - if (kind === null) { - return kind; - } else if (kind === undefined) { - return getDefaultCtor(); - } - else if (utils.isFunction(kind)) { - return kind; - } - logger.warn('Creating instances by name is deprecated. Name used:', kind); - // use memoized constructor if available... - var ctor = kindCtors[kind]; - if (ctor) { - return ctor; - } - // otherwise look it up and memoize what we find - // - // if kind is an object in enyo, say "Control", then ctor = enyo["Control"] - // if kind is a path under enyo, say "Heritage.Button", then ctor = enyo["Heritage.Button"] || enyo.Heritage.Button - // if kind is a fully qualified path, say "enyo.Heritage.Button", then ctor = enyo["enyo.Heritage.Button"] || enyo.enyo.Heritage.Button || enyo.Heritage.Button - // - // Note that kind "Foo" will resolve to enyo.Foo before resolving to global "Foo". - // This is important so "Image" will map to built-in Image object, instead of enyo.Image control. - ctor = Theme[kind] || (global.enyo && global.enyo[kind]) || utils.getPath.call(global, 'enyo.' + kind) || global[kind] || utils.getPath.call(global, kind); + * @method + * @private + */ +var constructorForKind = exports.constructorForKind = function(kind) { + if (kind === null) { + return kind; + } else if (kind === undefined) { + return getDefaultCtor(); + } else if (utils.isFunction(kind)) { + return kind; + } + logger.warn('Creating instances by name is deprecated. Name used:', kind); + // use memoized constructor if available... + var ctor = kindCtors[kind]; + if (ctor) { + return ctor; + } + // otherwise look it up and memoize what we find + // + // if kind is an object in enyo, say "Control", then ctor = enyo["Control"] + // if kind is a path under enyo, say "Heritage.Button", then ctor = enyo["Heritage.Button"] || enyo.Heritage.Button + // if kind is a fully qualified path, say "enyo.Heritage.Button", then ctor = enyo["enyo.Heritage.Button"] || enyo.enyo.Heritage.Button || enyo.Heritage.Button + // + // Note that kind "Foo" will resolve to enyo.Foo before resolving to global "Foo". + // This is important so "Image" will map to built-in Image object, instead of enyo.Image control. + ctor = Theme[kind] || (global.enyo && global.enyo[kind]) || utils.getPath.call(global, 'enyo.' + kind) || global[kind] || utils.getPath.call(global, kind); // If what we found at this namespace isn't a function, it's definitely not a kind constructor if (!utils.isFunction(ctor)) { @@ -523,15 +519,16 @@ exports.createFromKind = function (nom, param) { exports.animate = function(proto, properties, opts) { var i, ctor, ps, s; - if (!utils.isArray(proto)) { - return new scene(proto, properties, opts); - } - - ps = new scene(); - if (opts) utils.mixin(ps, opts); - for (i = 0; (ctor = proto[i]); i++) { - s = new scene(ctor, properties); - ps.addScene(s); - } - return ps; + if (!utils.isArray(proto)) { + return new scene(proto, properties, opts); + } + + ps = new scene(); + if (opts) utils.mixin(ps, opts); + for (i = 0; + (ctor = proto[i]); i++) { + s = new scene(ctor, properties); + ps.addScene(s); + } + return ps; }; \ No newline at end of file diff --git a/src/sceneSupport.js b/src/sceneSupport.js new file mode 100644 index 000000000..0eec768f1 --- /dev/null +++ b/src/sceneSupport.js @@ -0,0 +1,20 @@ +var + kind = require('./kind'), + scene = require('./scene'); + +var SceneSupport = { + + create: kind.inherit(function(sup) { + var ctor, proto, sctor; + return function() { + sup.apply(this, arguments); + + if (this.scene) { + sctor = new scene(this, this.scene); + this.scene = sctor; + } + }; + }) +}; + +module.exports = SceneSupport; From 2c4008e385df73db943be9b9408c3cb6d6a12fd9 Mon Sep 17 00:00:00 2001 From: Ankur Mishra Date: Wed, 1 Jun 2016 16:21:46 +0530 Subject: [PATCH 11/32] Now support duration in % We can give duration in % in each scene object, but total duration should in actor itself. This will support within scene object in kind and inside kind.animate. Enyo-DCO-1.1-Signed-off-by: Ankur Mishra --- src/scene.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/scene.js b/src/scene.js index 224782ae5..aa0cb59c9 100644 --- a/src/scene.js +++ b/src/scene.js @@ -172,8 +172,8 @@ var scene = module.exports = function (actor, props, opts) { var anims = utils.isArray(props) ? props : [props]; for (var i = 0, anim; (anim = anims[i]); i++) { - if (anim.delay) this.addAnimation({}, anim.delay); - this.addAnimation(anim, anim.duration || 0); + if (anim.delay) this.addAnimation({}, anim.delay, actor.duration); + this.addAnimation(anim, anim.duration || 0, actor.duration); } } }; @@ -247,9 +247,10 @@ scene.prototype.getAnimation = function(index) { return index < 0 || this.poses[index]; }; -scene.prototype.addAnimation = function(newProp, span) { +scene.prototype.addAnimation = function(newProp, span, dur) { var l = this.poses.length, old = 0, + span = span.toString().match(/%$/) ? (span.replace(/%$/,'') * dur / 100) : span, newSpan = newProp instanceof this.constructor ? newProp.span : span; if (l > 0 && this.isSequence) { From 6ed52b8284c08c1c760cc54a97e5dce1c613b617 Mon Sep 17 00:00:00 2001 From: Madala Cholan Satyanarayana Date: Wed, 1 Jun 2016 17:23:07 +0530 Subject: [PATCH 12/32] Added prepareAnimate api --- src/kind.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/kind.js b/src/kind.js index ede434d7a..b86c98038 100644 --- a/src/kind.js +++ b/src/kind.js @@ -517,7 +517,18 @@ exports.createFromKind = function (nom, param) { * @return {Object} A scene object */ exports.animate = function(proto, properties, opts) { - var i, ctor, ps, s; + var scene = scenePrepare(proto, properties, opts); + scene.play(); + return scene; +}; + +exports.prepareAnimate = function(proto, properties, opts) { + var scene = scenePrepare(proto, properties, opts); + return scene; +}; + +function scenePrepare(proto, properties, opts) { + var i, ctor, ps, s; if (!utils.isArray(proto)) { return new scene(proto, properties, opts); From 36b68964e2c7103062c1aea78c7a513af9f14bec Mon Sep 17 00:00:00 2001 From: "srirama.singeri" Date: Mon, 6 Jun 2016 16:23:09 +0530 Subject: [PATCH 13/32] Update comments for scene --- src/scene.js | 144 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 95 insertions(+), 49 deletions(-) diff --git a/src/scene.js b/src/scene.js index aa0cb59c9..416e6b28a 100644 --- a/src/scene.js +++ b/src/scene.js @@ -2,6 +2,10 @@ var tween = require('./tween'), utils = require('./utils'), animation = require('./animation'); +/** +* Contains the declaration for the {@link module:enyo/scene~scene} kind. +* @module enyo/scene +*/ var _ts, _framerate = 16.6; @@ -44,10 +48,9 @@ var AnimationSupport = { isSequence: true, /** - * Starts the animation of the actor given in argument. - * If actor is not provided, animation of all the components linked to the {@link module:enyo/AnimationSupport/Scene} will be started. - * @param [Component]{@link module:enyo/Component~Component} actor The component to be animated + * Starts the animation of scene. * @public + * @memberOf module:enyo/scene */ play: function () { this.direction = this.speed = 1; @@ -59,9 +62,8 @@ var AnimationSupport = { }, /** - * Resumes the paused animation of the actor given in argument. - * If actor is not provided, animation of all the components linked to the {@link module:enyo/AnimationSupport/Scene} will be resumed. - * @param [Component]{@link module:enyo/Component~Component} actor The component to be animated + * Resumes the paused animation of scene. + * @memberOf module:enyo/scene * @public */ resume: function() { @@ -70,9 +72,8 @@ var AnimationSupport = { }, /** - * Pauses the animation of the actor given in argument. - * If actor is not provided, animation of all the components linked to the {@link module:enyo/AnimationSupport/Scene} will be paused. - * @param [Component]{@link module:enyo/Component~Component} actor The component to be animated + * Pauses the animation of scene. + * @memberOf module:enyo/scene * @public */ pause: function () { @@ -81,9 +82,8 @@ var AnimationSupport = { }, /** - * Reverses the animation of the actor given in argument. - * If actor is not provided, animation of all the components linked to the {@link module:enyo/AnimationSupport/Scene} will be reversed. - * @param [Component]{@link module:enyo/Component~Component} actor The component to be animated + * Reverses the animation of scene. + * @memberOf module:enyo/scene * @public */ reverse: function () { @@ -91,9 +91,8 @@ var AnimationSupport = { }, /** - * Stops the animation of the actor given in argument. - * If actor is not provided, animation of all the components linked to the {@link module:enyo/AnimationSupport/Scene} will be stopped. - * @param [Component]{@link module:enyo/Component~Component} actor The component to be animated + * Stops the animation of scene. + * @memberOf module:enyo/scene * @public */ stop: function () { @@ -102,10 +101,10 @@ var AnimationSupport = { }, /** - * Seeks the animation of the actor to the position provided in seek + * Seeks the animation to the position provided in seek * The value of seek should be between 0 to duration of the animation. - * @param {Number} seek Value in seek where the animation has to be seeked - * @param [Component]{@link module:enyo/Component~Component} actor The component to be animated + * @param {Number} seek where the animation has to be seeked + * @memberOf module:enyo/scene * @public */ seek: function(seek) { @@ -113,10 +112,10 @@ var AnimationSupport = { }, /** - * Seeks actor with animation to the position provided in seek + * Seeks the animation to the position provided in seek with animation * The value of seek should be between 0 to duration of the animation. - * @param {Number} seek Value in seek where the animation has to be seeked - * @param [Component]{@link module:enyo/Component~Component} actor The component to be animated + * @param {Number} seek where the animation has to be seeked + * @memberOf module:enyo/scene * @public */ seekAnimate: function(seek) { @@ -137,26 +136,28 @@ var AnimationSupport = { //TODO: Move these events to Event Delegator /** * Event to identify when the scene has done animating. - * @memberOf module:enyo/AnimationSupport/Actor + * @memberOf module:enyo/scene * @public */ completed: function() {}, /** * Event to identify when the scene has done a step(rAF updatation of time) in the animation. - * @memberOf module:enyo/AnimationSupport/Actor + * @memberOf module:enyo/scene * @public */ step: function() {} }; /** -* {@link module:enyo/Scene~Scene} is a work-in-progress module +* {@link module:enyo/Scene~Scene} * * @class Scene * @extends module:enyo/Scene~Scene -* @wip -* @private +* @param {Object} actor component which has to be animated +* @param {Object} props properties of the component +* @param {Object} opts additional options +* @public */ var scene = module.exports = function (actor, props, opts) { this.id = utils.uid("@"); @@ -177,7 +178,12 @@ var scene = module.exports = function (actor, props, opts) { } } }; - +/** + * Checks whether the scene is in a active state, which then can be animated + * @return {Boolean} generated value in true or false. true in case of the parent scene + * @memberOf module:enyo/scene + * @public + */ scene.prototype.isActive = function () { if (this.actor) return this.actor.generated; @@ -185,14 +191,18 @@ scene.prototype.isActive = function () { // making sure parent scenes are always active. return true; }; - +/** + * @private + */ function modify(pose, currentTm) { pose.span = currentTm; delete pose._endAnim; pose._endAnim = pose.currentState; return pose; -}; - +} +/** + * @private + */ function currPose(poseArr, tm, properties) { var currentTime = tm; for (var i = 0; i < poseArr.length; i++) { @@ -208,8 +218,10 @@ function currPose(poseArr, tm, properties) { break; } } -}; - +} +/** + * @private + */ function hasPosesCheck(poseArr) { var bool; for (var i = 0; i < poseArr.length; i++) { @@ -219,8 +231,10 @@ function hasPosesCheck(poseArr) { } } return bool; -}; - +} +/** + * @private + */ function loopPose(poseArr, tm, properties) { var isArrayCheck, hasPoses; isArrayCheck = utils.isArray(poseArr); @@ -233,20 +247,38 @@ function loopPose(poseArr, tm, properties) { } else if (isArrayCheck === true && hasPoses === false) { currPose(poseArr, tm, properties); } -}; - +} +/** + * Sets the new animations with the properties passed. + * @param {Object} properties Animation properties + * @memberOf module:enyo/scene + * @public + */ scene.prototype.setAnimation = function(properties) { var currentTime, currentPose; currentTime = this.timeline; // current time posesList = this.poses; // gets the poses loopPose(posesList, currentTime, properties); }; - +/** + * Gets the current animation pose. + * @param {Number} index animation index + * @return {Object} pose pose with the passed index + * @memberOf module:enyo/scene + * @public + */ scene.prototype.getAnimation = function(index) { return index < 0 || this.poses[index]; }; - +/** + * addAnimation is used for adding new animation with the passed properties at run time. + * @param {Object} newProp animation properties for new animation + * @param {Number} span span between the animation + * @param {Number} dur duration for the new animation + * @memberOf module:enyo/scene + * @public + */ scene.prototype.addAnimation = function(newProp, span, dur) { var l = this.poses.length, old = 0, @@ -260,7 +292,9 @@ scene.prototype.addAnimation = function(newProp, span, dur) { this.poses.push({animate: newProp, span: newSpan, begin: old }); this.span = newSpan; }; - +/** + * @private + */ scene.prototype.action = function(ts, pose) { var tm, i, poses, dur = this.span; @@ -294,7 +328,9 @@ scene.prototype.action = function(ts, pose) { } return pose; }; - +/** + * @private + */ scene.prototype.cut = function () { if (this.handleLayers) { this.speed = 0; @@ -306,7 +342,9 @@ scene.prototype.cut = function () { this.animating = false; this.completed && this.completed(this.actor); }; - +/** + * @private + */ scene.prototype.toScene = function (scene) { scene.speed = this.speed; scene.direction = this.direction; @@ -314,7 +352,12 @@ scene.prototype.toScene = function (scene) { return scene; }; - +/** + * Add a new animation scene for the animation. + * @param {Object} sc scene which has to be added + * @memberOf module:enyo/scene + * @public + */ scene.prototype.addScene = function(sc) { var l = this.poses.length, old = 0, @@ -331,18 +374,21 @@ scene.prototype.addScene = function(sc) { this.span = newSpan; }; - - +/** + * @private + */ function loop (was, is) { if (this.animating) { _ts = is - (was || 0); _ts = (_ts > _framerate) ? _framerate : _ts; this.action(_ts); } else if (this.actor && this.actor.destroyed) { - animation.unsubscribe(this.rAFId); + animation.unsubscribe(this.rAFId); } } - +/** + * @private + */ function update (pose, actor, since, dur) { var t; if (!pose._startAnim) tween.init(actor, pose); @@ -374,15 +420,15 @@ function rolePlay (t, actor) { actor.speed = 0; } } - + if (actor.timeline === undefined || actor.timeline < 0) actor.timeline = 0; return actor.timeline; } /** - * Returns animation pose index for a particular - * instance of time from the list of + * Returns animation pose index for a particular + * instance of time from the list of * animations added to the scene. * @param {number} span - Time span from the animation timeline * @return {number} - index of the animation From d6265838d80535d64c6530f176ff2c636caeb32b Mon Sep 17 00:00:00 2001 From: Madala Cholan Satyanarayana Date: Mon, 6 Jun 2016 17:21:30 +0530 Subject: [PATCH 14/32] Defect fixes and Review changes --- src/kind.js | 35 ------------------------- src/scene.js | 64 ++++++++++++++++++++++++++++++++------------- src/sceneSupport.js | 2 +- 3 files changed, 47 insertions(+), 54 deletions(-) diff --git a/src/kind.js b/src/kind.js index b86c98038..492a52b1f 100644 --- a/src/kind.js +++ b/src/kind.js @@ -508,38 +508,3 @@ exports.createFromKind = function (nom, param) { return new Ctor(param); } }; -/** - * Interface which accepts the animation details and returns a scene object - * @param {Array} proto Actors - * @param {Object} properties Animation Properties - * @param {number} duration Animation duration - * @param {String} completed Callback function on completion - * @return {Object} A scene object - */ -exports.animate = function(proto, properties, opts) { - var scene = scenePrepare(proto, properties, opts); - scene.play(); - return scene; -}; - -exports.prepareAnimate = function(proto, properties, opts) { - var scene = scenePrepare(proto, properties, opts); - return scene; -}; - -function scenePrepare(proto, properties, opts) { - var i, ctor, ps, s; - - if (!utils.isArray(proto)) { - return new scene(proto, properties, opts); - } - - ps = new scene(); - if (opts) utils.mixin(ps, opts); - for (i = 0; - (ctor = proto[i]); i++) { - s = new scene(ctor, properties); - ps.addScene(s); - } - return ps; -}; \ No newline at end of file diff --git a/src/scene.js b/src/scene.js index 416e6b28a..94924208c 100644 --- a/src/scene.js +++ b/src/scene.js @@ -256,10 +256,10 @@ function loopPose(poseArr, tm, properties) { * @public */ scene.prototype.setAnimation = function(properties) { - var currentTime, currentPose; - currentTime = this.timeline; // current time - posesList = this.poses; // gets the poses - loopPose(posesList, currentTime, properties); + var currentTime, posesList; + currentTime = this.timeline; // current time + posesList = this.poses; // gets the poses + loopPose(posesList, currentTime, properties); }; /** * Gets the current animation pose. @@ -280,10 +280,10 @@ scene.prototype.getAnimation = function(index) { * @public */ scene.prototype.addAnimation = function(newProp, span, dur) { - var l = this.poses.length, - old = 0, - span = span.toString().match(/%$/) ? (span.replace(/%$/,'') * dur / 100) : span, - newSpan = newProp instanceof this.constructor ? newProp.span : span; + var l = this.poses.length, + old = 0, + spanCache = span.toString().match(/%$/) ? (span.replace(/%$/, '') * dur / 100) : span, + newSpan = newProp instanceof this.constructor ? newProp.span : spanCache; if (l > 0 && this.isSequence) { old = this.poses[l-1].span; @@ -442,13 +442,41 @@ function posesAtTime(anims, span) { } var - REPEAT = { - 'true': Infinity, - 'false': 1 - }, - FILLMODE = { - 'backwards': true, - 'forwards': false, - 'default': false, - 'none': false - }; \ No newline at end of file + REPEAT = { + 'true': Infinity, + 'false': 1 + }, + FILLMODE = { + 'backwards': true, + 'forwards': false, + 'default': false, + 'none': false + }; +/** + * Interface which accepts the animation details and returns a scene object + * @param {Array} proto Actors + * @param {Object} properties Animation Properties + * @param {number} duration Animation duration + * @param {String} completed Callback function on completion + * @return {Object} A scene object + */ +function animate(proto, properties, opts) { + var i, ctor, ps, s; + + if (!utils.isArray(proto)) { + return new scene(proto, properties, opts); + } + + ps = new scene(); + if (opts) utils.mixin(ps, opts); + for (i = 0; + (ctor = proto[i]); i++) { + s = new scene(ctor, properties); + ps.addScene(s); + } + if (opts.autoPlay) { + ps.play(); + } + return ps; +} +module.exports = animate; diff --git a/src/sceneSupport.js b/src/sceneSupport.js index 0eec768f1..fdebfada5 100644 --- a/src/sceneSupport.js +++ b/src/sceneSupport.js @@ -5,7 +5,7 @@ var var SceneSupport = { create: kind.inherit(function(sup) { - var ctor, proto, sctor; + var sctor; return function() { sup.apply(this, arguments); From ba6621f94d23130d73ad91c27a3eae8d84bd8447 Mon Sep 17 00:00:00 2001 From: Madala Cholan Satyanarayana Date: Mon, 6 Jun 2016 17:55:58 +0530 Subject: [PATCH 15/32] Defect fix in Kind --- src/kind.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/kind.js b/src/kind.js index 492a52b1f..e8f3ea66a 100644 --- a/src/kind.js +++ b/src/kind.js @@ -425,8 +425,7 @@ kind.statics = { exports.concatHandler = function(ctor, props, instance) { var proto = ctor.prototype || ctor, - base = proto.ctor, - sctor; + base = proto.ctor; while (base) { if (base.concat) base.concat(ctor, props, instance); From e6a016ef8eab396c7423eab4c7ab41c08999d827 Mon Sep 17 00:00:00 2001 From: Madala Cholan Satyanarayana Date: Tue, 7 Jun 2016 16:50:59 +0530 Subject: [PATCH 16/32] Code optimizations in Scene --- src/scene.js | 56 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/src/scene.js b/src/scene.js index 94924208c..f8f5b1cb3 100644 --- a/src/scene.js +++ b/src/scene.js @@ -222,31 +222,39 @@ function currPose(poseArr, tm, properties) { /** * @private */ -function hasPosesCheck(poseArr) { - var bool; - for (var i = 0; i < poseArr.length; i++) { - bool = poseArr[i].poses ? true : false; - if (bool === true) { - break; - } - } - return bool; +function hasPropCheck(poseArr, propCheck) { + var bool; + if (!utils.isArray(poseArr)) { + bool = poseArr[propCheck] ? true : false; + } else { + for (var i = 0; i < poseArr.length; i++) { + bool = poseArr[i][propCheck] ? true : false; + console.log(bool); + if (bool === true) { + break; + } + } + } + return bool; } /** * @private */ -function loopPose(poseArr, tm, properties) { - var isArrayCheck, hasPoses; - isArrayCheck = utils.isArray(poseArr); - hasPoses = hasPosesCheck(poseArr); - - if (isArrayCheck === true && hasPoses === true) { - for (var i = 0; i < poseArr.length; i++) { - loopPose(poseArr[i].poses, tm, properties); - } - } else if (isArrayCheck === true && hasPoses === false) { - currPose(poseArr, tm, properties); - } +function loopPose(poseArr, propCheck) { + var isArrayCheck, hasProp, currNode; + isArrayCheck = utils.isArray(poseArr); + currNode = poseArr; + hasProp = hasPropCheck(poseArr, propCheck); + if (hasProp === true) { + if (isArrayCheck === true) { + for (var i = 0; i < poseArr.length; i++) { + currNode = loopPose(currNode[i].poses, propCheck); + } + } else { + currNode = loopPose(currNode.poses, propCheck); + } + } + return currNode; } /** @@ -256,10 +264,12 @@ function loopPose(poseArr, tm, properties) { * @public */ scene.prototype.setAnimation = function(properties) { - var currentTime, posesList; + var currentPose, currentTime, posesList; currentTime = this.timeline; // current time posesList = this.poses; // gets the poses - loopPose(posesList, currentTime, properties); + currentPose = loopPose(posesList, "poses"); + + currPose(currentPose, currentTime, properties); }; /** * Gets the current animation pose. From e7c957b3676b827e986de520eb35cdc71ff24264 Mon Sep 17 00:00:00 2001 From: Madala Cholan Satyanarayana Date: Tue, 7 Jun 2016 17:04:20 +0530 Subject: [PATCH 17/32] removed consoles --- src/scene.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/scene.js b/src/scene.js index f8f5b1cb3..78ffe8057 100644 --- a/src/scene.js +++ b/src/scene.js @@ -229,7 +229,6 @@ function hasPropCheck(poseArr, propCheck) { } else { for (var i = 0; i < poseArr.length; i++) { bool = poseArr[i][propCheck] ? true : false; - console.log(bool); if (bool === true) { break; } @@ -265,10 +264,9 @@ function loopPose(poseArr, propCheck) { */ scene.prototype.setAnimation = function(properties) { var currentPose, currentTime, posesList; - currentTime = this.timeline; // current time - posesList = this.poses; // gets the poses - currentPose = loopPose(posesList, "poses"); - + currentTime = this.timeline; + posesList = this.poses; + currentPose = loopPose(posesList, "poses"); currPose(currentPose, currentTime, properties); }; /** From 7e1ffc5c7e87c5305e540765e8fdca9311795bae Mon Sep 17 00:00:00 2001 From: Ankur Mishra Date: Wed, 8 Jun 2016 12:01:03 +0530 Subject: [PATCH 18/32] Correct repeat related issue in various scene scenario Enyo-DCO-1.1-Signed-off-by: Ankur Mishra --- src/scene.js | 36 +++++++++++++++++++++--------------- src/tween.js | 8 ++++---- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/src/scene.js b/src/scene.js index 78ffe8057..fe64e8e3e 100644 --- a/src/scene.js +++ b/src/scene.js @@ -229,9 +229,7 @@ function hasPropCheck(poseArr, propCheck) { } else { for (var i = 0; i < poseArr.length; i++) { bool = poseArr[i][propCheck] ? true : false; - if (bool === true) { - break; - } + if (bool) break; } } return bool; @@ -240,22 +238,30 @@ function hasPropCheck(poseArr, propCheck) { * @private */ function loopPose(poseArr, propCheck) { - var isArrayCheck, hasProp, currNode; - isArrayCheck = utils.isArray(poseArr); - currNode = poseArr; - hasProp = hasPropCheck(poseArr, propCheck); - if (hasProp === true) { - if (isArrayCheck === true) { + var parentNode, currNode = poseArr; + if (hasPropCheck(poseArr, propCheck)) { + if (utils.isArray(poseArr)) { for (var i = 0; i < poseArr.length; i++) { + parentNode = currNode[i]; currNode = loopPose(currNode[i].poses, propCheck); } } else { + parentNode = currNode; currNode = loopPose(currNode.poses, propCheck); } } - return currNode; + return parentNode ? parentNode[propCheck] : parentNode; } +/** + * @private + */ +function addInitialStyle(node) { + node = node.actor ? node : loopPose(node.poses, "actor"); + node = node.actor || node; + node.addStyles(node.initialState); +}; + /** * Sets the new animations with the properties passed. * @param {Object} properties Animation properties @@ -266,7 +272,7 @@ scene.prototype.setAnimation = function(properties) { var currentPose, currentTime, posesList; currentTime = this.timeline; posesList = this.poses; - currentPose = loopPose(posesList, "poses"); + currentPose = loopPose(posesList, "poses"); currPose(currentPose, currentTime, properties); }; /** @@ -324,11 +330,11 @@ scene.prototype.action = function(ts, pose) { } else { this.repeat = REPEAT[this.repeat] || this.repeat; this.timeline = --this.repeat ? 0 : this.span; - if (this.repeat) { - this.actor.addStyles(this.actor.initalState); + if (this.repeat > 0) { + addInitialStyle(this); } else { if (FILLMODE[this.fillmode]) { - this.actor.addStyles(this.actor.initalState); + addInitialStyle(this); } this.cut(); } @@ -452,7 +458,7 @@ function posesAtTime(anims, span) { var REPEAT = { 'true': Infinity, - 'false': 1 + 'false': 0 }, FILLMODE = { 'backwards': true, diff --git a/src/tween.js b/src/tween.js index 2d697ae68..28140c298 100644 --- a/src/tween.js +++ b/src/tween.js @@ -23,13 +23,13 @@ module.exports = { */ init: function(actor, pose, initial) { var k; - actor.initalState = actor.initalState || {}; + actor.initialState = actor.initialState || {}; if (!(actor && pose && pose.animate)) return; node = actor.hasNode(); utils.mixin(pose, getAnimatedProperty(node, pose.animate, initial)); actor.currentState = pose.currentState; - for (k in pose.initalState) { - actor.initalState[k] = actor.initalState[k] || pose.initalState[k]; + for (k in pose.initialState) { + actor.initialState[k] = actor.initialState[k] || pose.initialState[k]; } return pose; }, @@ -503,7 +503,7 @@ function getAnimatedProperty(node, props, initial) { _endAnim: eP, _transform: dP, currentState: dP, - initalState: iP, + initialState: iP, matrix: m, props: props }; From 89da7431559267df6218223efd1444e4a7182287 Mon Sep 17 00:00:00 2001 From: "srirama.singeri" Date: Fri, 10 Jun 2016 18:04:49 +0530 Subject: [PATCH 19/32] Update comments for transform --- src/transform.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/transform.js b/src/transform.js index 6a603e721..b9ba52ea9 100644 --- a/src/transform.js +++ b/src/transform.js @@ -1,3 +1,7 @@ +/** +* Contains the declaration for the {@link module:enyo/transform~transform} kind. +* @module enyo/transform +*/ require('enyo'); /** @@ -292,7 +296,7 @@ exports.Matrix = { * To multiply 2 Martix3d (n*n order) * @param {Number[]} m1 1st Matrix3d * @param {Number[]} m2 2nd Matrix3d - * @return {[type]} Resultant Matrix3d + * @return {Number[]} Resultant Matrix3d */ multiplyN: function(m1, m2) { var i, j, sum, From 20142ad3bf410bb20b2d8d4eea061cbbdce83422 Mon Sep 17 00:00:00 2001 From: Madala Cholan Satyanarayana Date: Wed, 15 Jun 2016 13:18:40 +0530 Subject: [PATCH 20/32] Name of the module capitalized --- src/sceneSupport.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sceneSupport.js b/src/sceneSupport.js index fdebfada5..74db3b7b5 100644 --- a/src/sceneSupport.js +++ b/src/sceneSupport.js @@ -17,4 +17,4 @@ var SceneSupport = { }) }; -module.exports = SceneSupport; +module.exports = SceneSupport; \ No newline at end of file From d850434f9a1e8ebabfb47d814ee5145a7f57ddc0 Mon Sep 17 00:00:00 2001 From: Anish_Ramesan Date: Wed, 15 Jun 2016 14:30:43 +0530 Subject: [PATCH 21/32] API updates Enyo-DCO-1.1-Signed-off-by: Anish Ramesan --- src/animation.js | 2 +- src/scene.js | 506 ++++++++++++++++++++++++-------------------- src/sceneSupport.js | 6 +- 3 files changed, 286 insertions(+), 228 deletions(-) diff --git a/src/animation.js b/src/animation.js index 2d56f8779..791414e48 100644 --- a/src/animation.js +++ b/src/animation.js @@ -109,7 +109,7 @@ exports.cancelAnimationFrame = function(id) { */ exports.subscribe = function(ctx,callback) { var id = utils.uid("rAF"); - core.obs[id]=utils.bindSafely(ctx, callback); + core.obs[id] = utils.bindSafely(ctx, callback); return id; }; /** diff --git a/src/scene.js b/src/scene.js index fe64e8e3e..7b9c40e1c 100644 --- a/src/scene.js +++ b/src/scene.js @@ -3,56 +3,112 @@ var utils = require('./utils'), animation = require('./animation'); /** -* Contains the declaration for the {@link module:enyo/scene~scene} kind. -* @module enyo/scene -*/ + * Contains the declaration for the {@link module:enyo/scene~scene} of an animation. + * @module enyo/scene + */ var _ts, _framerate = 16.6; var AnimationSupport = { /** - * @public - */ - span: 0, - /** - * @private - */ - timeline: 0, - /** - * @public - */ + * Reiterates the animation applied to the component. + * It could be; + * true, for infinite iteration + * [Number], for how many times animation should iterate. + * false, for no repetition + * @public + * @memberOf module:enyo/scene + */ repeat: false, /** - * @public - */ + * Reduces GPU layers when the animation is completed. + * As most of the transform animations happens on + * GPU layer, ans stays there even after the animations + * is completed. However, need to be carefull while using this + * feature as if the component tends to animate regularly, this + * feature would be an overhead. + * when true, GPU memory is freed + * false, layer remain intact. + * @public + * @memberOf module:enyo/scene + */ handleLayers: false, /** - * @public - */ + * Indentifies whether the animation is in progress or not. + * when true, animation is in progress + * false, otherwise. + * @public + * @memberOf module:enyo/scene + */ animating: false, /** - * @public - */ + * Specifies the rate at which animation should be played. + * When 0, animation is still + * 1, animation plays with normal speed + * 2, animation plays with 2X fast speed + * 0.5, animation plays with slow speed at half of normal speed. + * @public + * @memberOf module:enyo/scene + */ direction: 0, /** - * @public - */ + * Specifies the rate at which animation should be played. + * When 0, animation is still + * 1, animation plays with normal speed + * 2, animation plays with 2X fast speed + * 0.5, animation plays with slow speed at half of normal speed. + * @public + * @memberOf module:enyo/scene + */ speed: 0, /** - * @public - */ + * Moves animation to a particular point within the span of + * an animation. Its value could lie between 0 and total duration + * of the animation. + * @public + * @memberOf module:enyo/scene + */ seekInterval: 0, /** - * @public - */ + * Plays animation in sequence when set to true else + * its a parallal animation. This could be applied for + * animation properties as well as for scenes within a + * scene. + * @public + * @memberOf module:enyo/scene + */ isSequence: true, - + /** + * Starts animation when scene is initialized, + * when this property is set to true. When false scene instance has + * to be explicity played using 'play' api. + * @public + * @memberOf module:enyo/scene + */ + autoPlay: true, + /** + * The limit for an animation, which could be an instance + * of time as well as distance. + * @public + * @memberOf module:enyo/scene + */ + span: 0, + /** + * The current time state of animation. This represents the + * time at which animation is progressed upon. As this property + * directly impacts the state of animation, updating this value + * have direct effect on animation unless its animation is halted. + * The range lies between 0 to overall span of animation. + * @public + * @memberOf module:enyo/scene + */ + timeline: 0, /** * Starts the animation of scene. * @public * @memberOf module:enyo/scene */ - play: function () { + play: function() { this.direction = this.speed = 1; if (isNaN(this.timeline) || !this.timeline) { this.timeline = 0; @@ -76,7 +132,7 @@ var AnimationSupport = { * @memberOf module:enyo/scene * @public */ - pause: function () { + pause: function() { this.direction = 0; return this; }, @@ -86,7 +142,7 @@ var AnimationSupport = { * @memberOf module:enyo/scene * @public */ - reverse: function () { + reverse: function() { this.direction = -1; }, @@ -95,7 +151,7 @@ var AnimationSupport = { * @memberOf module:enyo/scene * @public */ - stop: function () { + stop: function() { this.speed = 0; this.timeline = 0; }, @@ -119,11 +175,11 @@ var AnimationSupport = { * @public */ seekAnimate: function(seek) { - if (seek >= 0 ) { + if (seek >= 0) { if (!this.animating) this.play(); this.speed = 1; - }else{ + } else { this.speed = -1; } this.seekInterval = this.timeline + seek; @@ -150,16 +206,42 @@ var AnimationSupport = { }; /** -* {@link module:enyo/Scene~Scene} -* -* @class Scene -* @extends module:enyo/Scene~Scene -* @param {Object} actor component which has to be animated -* @param {Object} props properties of the component -* @param {Object} opts additional options -* @public -*/ -var scene = module.exports = function (actor, props, opts) { + * Interface which accepts the animation details and returns a scene object + * @param {Object} actor component which has to be animated + * @param {Object} props properties of the component + * @param {Object} opts additional options + * @return {Object} A scene object + */ +module.exports = function (proto, properties, opts) { + var i, ctor, ps, s; + + if (!utils.isArray(proto)) { + ps = new scene(proto, properties, opts); + } else { + ps = new scene(); + if (opts) utils.mixin(ps, opts); + for (i = 0; + (ctor = proto[i]); i++) { + s = new scene(ctor, properties); + ps.addScene(s); + } + } + + ps.autoPlay && ps.play(); + return ps; +}; + +/** + * {@link module:enyo/Scene~Scene} + * + * @class Scene + * @extends module:enyo/Scene~Scene + * @param {Object} actor component which has to be animated + * @param {Object} props properties of the component + * @param {Object} opts additional options + * @public + */ +function scene(actor, props, opts) { this.id = utils.uid("@"); this.poses = []; this.rolePlays = []; @@ -177,90 +259,21 @@ var scene = module.exports = function (actor, props, opts) { this.addAnimation(anim, anim.duration || 0, actor.duration); } } -}; +} + /** * Checks whether the scene is in a active state, which then can be animated * @return {Boolean} generated value in true or false. true in case of the parent scene * @memberOf module:enyo/scene * @public */ -scene.prototype.isActive = function () { +scene.prototype.isActive = function() { if (this.actor) return this.actor.generated; // making sure parent scenes are always active. return true; }; -/** - * @private - */ -function modify(pose, currentTm) { - pose.span = currentTm; - delete pose._endAnim; - pose._endAnim = pose.currentState; - return pose; -} -/** - * @private - */ -function currPose(poseArr, tm, properties) { - var currentTime = tm; - for (var i = 0; i < poseArr.length; i++) { - - if (poseArr[i].begin <= currentTime && poseArr[i].span >= currentTime) { // check the current Pose - modify(poseArr[i], currentTime); - poseArr.splice((i + 1), poseArr.length - (i + 1)); - poseArr[(i + 1)] = { - animate: properties, - begin: currentTime, - span: currentTime + properties.duration - }; - break; - } - } -} -/** - * @private - */ -function hasPropCheck(poseArr, propCheck) { - var bool; - if (!utils.isArray(poseArr)) { - bool = poseArr[propCheck] ? true : false; - } else { - for (var i = 0; i < poseArr.length; i++) { - bool = poseArr[i][propCheck] ? true : false; - if (bool) break; - } - } - return bool; -} -/** - * @private - */ -function loopPose(poseArr, propCheck) { - var parentNode, currNode = poseArr; - if (hasPropCheck(poseArr, propCheck)) { - if (utils.isArray(poseArr)) { - for (var i = 0; i < poseArr.length; i++) { - parentNode = currNode[i]; - currNode = loopPose(currNode[i].poses, propCheck); - } - } else { - parentNode = currNode; - currNode = loopPose(currNode.poses, propCheck); - } - } - return parentNode ? parentNode[propCheck] : parentNode; -} - -/** - * @private - */ -function addInitialStyle(node) { - node = node.actor ? node : loopPose(node.poses, "actor"); - node = node.actor || node; - node.addStyles(node.initialState); -}; /** * Sets the new animations with the properties passed. @@ -269,12 +282,10 @@ function addInitialStyle(node) { * @public */ scene.prototype.setAnimation = function(properties) { - var currentPose, currentTime, posesList; - currentTime = this.timeline; - posesList = this.poses; - currentPose = loopPose(posesList, "poses"); - currPose(currentPose, currentTime, properties); + var currentPose = findScene(this.poses, "poses"); + setScene(currentPose, this.timeline, properties); }; + /** * Gets the current animation pose. * @param {Number} index animation index @@ -285,6 +296,7 @@ scene.prototype.setAnimation = function(properties) { scene.prototype.getAnimation = function(index) { return index < 0 || this.poses[index]; }; + /** * addAnimation is used for adding new animation with the passed properties at run time. * @param {Object} newProp animation properties for new animation @@ -294,123 +306,126 @@ scene.prototype.getAnimation = function(index) { * @public */ scene.prototype.addAnimation = function(newProp, span, dur) { - var l = this.poses.length, - old = 0, - spanCache = span.toString().match(/%$/) ? (span.replace(/%$/, '') * dur / 100) : span, - newSpan = newProp instanceof this.constructor ? newProp.span : spanCache; + var l = this.poses.length, + old = 0, + spanCache = span.toString().match(/%$/) ? (span.replace(/%$/, '') * dur / 100) : span, + newSpan = newProp instanceof this.constructor ? newProp.span : spanCache; if (l > 0 && this.isSequence) { - old = this.poses[l-1].span; + old = this.poses[l - 1].span; newSpan += old; } - this.poses.push({animate: newProp, span: newSpan, begin: old }); + this.poses.push({ + animate: newProp, + span: newSpan, + begin: old + }); this.span = newSpan; }; + +/** + * Add a new animation scene for the animation. + * @param {Object} sc scene which has to be added + * @memberOf module:enyo/scene + * @public + */ +scene.prototype.addScene = function(sc) { + var l = this.poses.length, + old = 0, + newSpan = sc instanceof this.constructor ? sc.span : 0; + + if (l > 0 && this.isSequence) { + old = this.poses[l - 1].span; + newSpan += old; + sc.span = newSpan; + sc.begin = old; + } + + this.poses.push(sc); + this.span = newSpan; +}; + /** * @private */ -scene.prototype.action = function(ts, pose) { +function action(ts, pose) { var tm, i, poses, - dur = this.span; + dur = this.span, + actor = this.actor; if (this.isActive()) { tm = rolePlay(ts, this); if (isNaN(tm) || tm < 0) return pose; - else if (tm <= dur) { - poses = posesAtTime(this.poses, tm); - for (i = 0, pose; - (pose = poses[i]); i++) { - if (pose instanceof this.constructor) { - this.toScene(pose).action(ts); - } else { - update(pose, this.actor, (tm - pose.begin), (pose.span - pose.begin)); - } - } - this.step && this.step(this.actor); - } else { - this.repeat = REPEAT[this.repeat] || this.repeat; - this.timeline = --this.repeat ? 0 : this.span; - if (this.repeat > 0) { - addInitialStyle(this); + + poses = posesAtTime(this.poses, tm > dur ? dur : tm); + for (i = 0, pose; + (pose = poses[i]); i++) { + if (pose instanceof this.constructor) { + pose.speed = this.speed; + pose.direction = this.direction; + pose.handleLayers = this.handleLayers; + action.call(pose, ts); } else { - if (FILLMODE[this.fillmode]) { - addInitialStyle(this); - } - this.cut(); + update(pose, actor, (tm - pose.begin), (pose.span - pose.begin)); } } + this.step && this.step(actor); + + if (tm > dur) cut.call(this, actor); } return pose; -}; +} + /** * @private */ -scene.prototype.cut = function () { +function cut(actor) { + this.repeat = REPEAT[this.repeat] || this.repeat; + this.timeline = --this.repeat ? 0 : this.span; + + if (this.repeat > 0) { + applyInitialStyle(this); + return; + } else { + if (FILLMODE[this.fillmode]) { + applyInitialStyle(this); + } + } + if (this.handleLayers) { this.speed = 0; if (this.active) { this.active = false; - tween.halt(this.actor); + tween.halt(actor); } } this.animating = false; - this.completed && this.completed(this.actor); -}; -/** - * @private - */ -scene.prototype.toScene = function (scene) { - scene.speed = this.speed; - scene.direction = this.direction; - scene.handleLayers = this.handleLayers; - return scene; -}; - -/** - * Add a new animation scene for the animation. - * @param {Object} sc scene which has to be added - * @memberOf module:enyo/scene - * @public - */ -scene.prototype.addScene = function(sc) { - var l = this.poses.length, - old = 0, - newSpan = sc instanceof this.constructor ? sc.span : 0; - - if (l > 0 && this.isSequence) { - old = this.poses[l-1].span; - newSpan += old; - sc.span = newSpan; - sc.begin = old; - } - - this.poses.push(sc); - this.span = newSpan; -}; + this.completed && this.completed(actor); +} /** * @private */ -function loop (was, is) { +function loop(was, is) { if (this.animating) { _ts = is - (was || 0); _ts = (_ts > _framerate) ? _framerate : _ts; - this.action(_ts); + action.call(this, _ts); } else if (this.actor && this.actor.destroyed) { animation.unsubscribe(this.rAFId); } } + /** * @private */ -function update (pose, actor, since, dur) { +function update(pose, actor, since, dur) { var t; if (!pose._startAnim) tween.init(actor, pose); - if (since < 0) since = 0; if (since <= dur && dur !== 0) { t = since / dur; - tween.step(actor, pose, t, dur); + tween.step(actor, pose, t > 0.98 ? 1 : t, dur); } else { tween.step(actor, pose, 1, dur); } @@ -423,13 +438,13 @@ function update (pose, actor, since, dur) { * @return {Number} Returns the updated timeline of the actor * @private */ -function rolePlay (t, actor) { +function rolePlay(t, actor) { actor = actor || this; t = t * actor.speed * actor.direction; actor.timeline += t; - if(actor.seekInterval !== 0) { - if((actor.seekInterval-actor.timeline)*actor.speed < 0) { + if (actor.seekInterval !== 0) { + if ((actor.seekInterval - actor.timeline) * actor.speed < 0) { actor.seekInterval = 0; actor.speed = 0; } @@ -455,42 +470,85 @@ function posesAtTime(anims, span) { return anims.filter(doFilter); } -var - REPEAT = { - 'true': Infinity, - 'false': 0 - }, - FILLMODE = { - 'backwards': true, - 'forwards': false, - 'default': false, - 'none': false - }; /** - * Interface which accepts the animation details and returns a scene object - * @param {Array} proto Actors - * @param {Object} properties Animation Properties - * @param {number} duration Animation duration - * @param {String} completed Callback function on completion - * @return {Object} A scene object + * @private */ -function animate(proto, properties, opts) { - var i, ctor, ps, s; - - if (!utils.isArray(proto)) { - return new scene(proto, properties, opts); - } +function modify(pose, currentTm) { + pose.span = currentTm; + delete pose._endAnim; + pose._endAnim = pose.currentState; + return pose; +} +/** + * @private + */ +function currPose(poseArr, tm, properties) { + var currentTime = tm; + for (var i = 0; i < poseArr.length; i++) { - ps = new scene(); - if (opts) utils.mixin(ps, opts); - for (i = 0; - (ctor = proto[i]); i++) { - s = new scene(ctor, properties); - ps.addScene(s); + if (poseArr[i].begin <= currentTime && poseArr[i].span >= currentTime) { // check the current Pose + modify(poseArr[i], currentTime); + poseArr.splice((i + 1), poseArr.length - (i + 1)); + poseArr[(i + 1)] = { + animate: properties, + begin: currentTime, + span: currentTime + properties.duration + }; + break; + } + } +} +/** + * @private + */ +function hasPropCheck(poseArr, propCheck) { + var bool; + if (!utils.isArray(poseArr)) { + bool = poseArr[propCheck] ? true : false; + } else { + for (var i = 0; i < poseArr.length; i++) { + bool = poseArr[i][propCheck] ? true : false; + if (bool) break; + } } - if (opts.autoPlay) { - ps.play(); + return bool; +} +/** + * @private + */ +function loopPose(poseArr, propCheck) { + var parentNode, currNode = poseArr; + if (hasPropCheck(poseArr, propCheck)) { + if (utils.isArray(poseArr)) { + for (var i = 0; i < poseArr.length; i++) { + parentNode = currNode[i]; + currNode = loopPose(currNode[i].poses, propCheck); + } + } else { + parentNode = currNode; + currNode = loopPose(currNode.poses, propCheck); + } } - return ps; + return parentNode ? parentNode[propCheck] : parentNode; +} + +/** + * @private + */ +function addInitialStyle(node) { + node = node.actor ? node : loopPose(node.poses, "actor"); + node = node.actor || node; + node.addStyles(node.initialState); } -module.exports = animate; + +var + REPEAT = { + 'true': Infinity, + 'false': 0 + }, + FILLMODE = { + 'backwards': true, + 'forwards': false, + 'default': false, + 'none': false + }; diff --git a/src/sceneSupport.js b/src/sceneSupport.js index 74db3b7b5..c798c9435 100644 --- a/src/sceneSupport.js +++ b/src/sceneSupport.js @@ -8,9 +8,9 @@ var SceneSupport = { var sctor; return function() { sup.apply(this, arguments); - - if (this.scene) { - sctor = new scene(this, this.scene); + sctor = this.scene; + if (sctor) { + sctor = scene(this, sctor); this.scene = sctor; } }; From 8a02ea78927bbad15e2e690b5273f99b35cef3fb Mon Sep 17 00:00:00 2001 From: Anish_Ramesan Date: Wed, 15 Jun 2016 14:33:00 +0530 Subject: [PATCH 22/32] removed sceneSupport Enyo-DCO-1.1-Signed-off-by: Anish Ramesan --- src/sceneSupport.js | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 src/sceneSupport.js diff --git a/src/sceneSupport.js b/src/sceneSupport.js deleted file mode 100644 index c798c9435..000000000 --- a/src/sceneSupport.js +++ /dev/null @@ -1,20 +0,0 @@ -var - kind = require('./kind'), - scene = require('./scene'); - -var SceneSupport = { - - create: kind.inherit(function(sup) { - var sctor; - return function() { - sup.apply(this, arguments); - sctor = this.scene; - if (sctor) { - sctor = scene(this, sctor); - this.scene = sctor; - } - }; - }) -}; - -module.exports = SceneSupport; \ No newline at end of file From d20135faae7730d74eda38f307f463fe0706a300 Mon Sep 17 00:00:00 2001 From: Anish_Ramesan Date: Wed, 15 Jun 2016 14:33:57 +0530 Subject: [PATCH 23/32] added SceneSupport Enyo-DCO-1.1-Signed-off-by: Anish Ramesan --- src/SceneSupport.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/SceneSupport.js diff --git a/src/SceneSupport.js b/src/SceneSupport.js new file mode 100644 index 000000000..7a420dee6 --- /dev/null +++ b/src/SceneSupport.js @@ -0,0 +1,20 @@ +var + kind = require('./kind'), + scene = require('./scene'); + +var SceneSupport = { + + create: kind.inherit(function(sup) { + var sctor; + return function() { + sup.apply(this, arguments); + sctor = this.scene; + if (sctor) { + sctor = scene(this, sctor); + this.scene = sctor; + } + }; + }) +}; + +module.exports = SceneSupport; From b0526769b2024c2b37244243a3f1b34233cb3781 Mon Sep 17 00:00:00 2001 From: Ankur Mishra Date: Thu, 16 Jun 2016 15:48:10 +0530 Subject: [PATCH 24/32] Accept duration in % during runtime Enyo-DCO-1.1-Signed-off-by: Ankur Mishra --- src/scene.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/scene.js b/src/scene.js index 7b9c40e1c..f08956e17 100644 --- a/src/scene.js +++ b/src/scene.js @@ -306,6 +306,7 @@ scene.prototype.getAnimation = function(index) { * @public */ scene.prototype.addAnimation = function(newProp, span, dur) { + dur = dur || this.span; var l = this.poses.length, old = 0, spanCache = span.toString().match(/%$/) ? (span.replace(/%$/, '') * dur / 100) : span, @@ -535,7 +536,7 @@ function loopPose(poseArr, propCheck) { /** * @private */ -function addInitialStyle(node) { +function applyInitialStyle(node) { node = node.actor ? node : loopPose(node.poses, "actor"); node = node.actor || node; node.addStyles(node.initialState); From 97d25e672183edad12c8b2458e292d748125a33c Mon Sep 17 00:00:00 2001 From: Anish_Ramesan Date: Thu, 16 Jun 2016 19:47:14 +0530 Subject: [PATCH 25/32] Merge code fixes Enyo-DCO-1.1-Signed-off-by: Anish Ramesan --- src/SceneSupport.js | 2 ++ src/scene.js | 58 ++++++++++++++++++++++----------------------- 2 files changed, 31 insertions(+), 29 deletions(-) diff --git a/src/SceneSupport.js b/src/SceneSupport.js index 7a420dee6..870bb7905 100644 --- a/src/SceneSupport.js +++ b/src/SceneSupport.js @@ -1,5 +1,6 @@ var kind = require('./kind'), + utils = require('./utils'), scene = require('./scene'); var SceneSupport = { @@ -11,6 +12,7 @@ var SceneSupport = { sctor = this.scene; if (sctor) { sctor = scene(this, sctor); + utils.mixin(sctor, this.sceneOptions); this.scene = sctor; } }; diff --git a/src/scene.js b/src/scene.js index f08956e17..4037f6e41 100644 --- a/src/scene.js +++ b/src/scene.js @@ -269,7 +269,7 @@ function scene(actor, props, opts) { */ scene.prototype.isActive = function() { if (this.actor) - return this.actor.generated; + return this.actor.generated && !this.actor.destroyed; // making sure parent scenes are always active. return true; @@ -483,7 +483,7 @@ function modify(pose, currentTm) { /** * @private */ -function currPose(poseArr, tm, properties) { +function setScene(poseArr, tm, properties) { var currentTime = tm; for (var i = 0; i < poseArr.length; i++) { @@ -502,42 +502,42 @@ function currPose(poseArr, tm, properties) { /** * @private */ -function hasPropCheck(poseArr, propCheck) { - var bool; - if (!utils.isArray(poseArr)) { - bool = poseArr[propCheck] ? true : false; - } else { - for (var i = 0; i < poseArr.length; i++) { - bool = poseArr[i][propCheck] ? true : false; - if (bool) break; - } - } - return bool; +function hasScene(poseArr, propCheck) { + var bool; + if (!utils.isArray(poseArr)) { + bool = poseArr[propCheck] ? true : false; + } else { + for (var i = 0; i < poseArr.length; i++) { + bool = poseArr[i][propCheck] ? true : false; + if (bool) break; + } + } + return bool; } /** * @private */ -function loopPose(poseArr, propCheck) { - var parentNode, currNode = poseArr; - if (hasPropCheck(poseArr, propCheck)) { - if (utils.isArray(poseArr)) { - for (var i = 0; i < poseArr.length; i++) { - parentNode = currNode[i]; - currNode = loopPose(currNode[i].poses, propCheck); - } - } else { - parentNode = currNode; - currNode = loopPose(currNode.poses, propCheck); - } - } - return parentNode ? parentNode[propCheck] : parentNode; +function findScene(poseArr, propCheck) { + var parentNode, currNode = poseArr; + if (hasScene(poseArr, propCheck)) { + if (utils.isArray(poseArr)) { + for (var i = 0; i < poseArr.length; i++) { + parentNode = currNode[i]; + currNode = findScene(currNode[i].poses, propCheck); + } + } else { + parentNode = currNode; + currNode = findScene(currNode.poses, propCheck); + } + } + return parentNode ? parentNode[propCheck] : parentNode; } /** * @private */ function applyInitialStyle(node) { - node = node.actor ? node : loopPose(node.poses, "actor"); + node = node.actor ? node : findScene(node.poses, "actor"); node = node.actor || node; node.addStyles(node.initialState); } @@ -552,4 +552,4 @@ var 'forwards': false, 'default': false, 'none': false - }; + }; \ No newline at end of file From d1cfcab9240f2b5f8784152350eebb8265ef7421 Mon Sep 17 00:00:00 2001 From: Anish_Ramesan Date: Thu, 16 Jun 2016 21:09:14 +0530 Subject: [PATCH 26/32] easing documentation Enyo-DCO-1.1-Signed-off-by: Anish Ramesan --- src/easing.js | 393 +++++++++++++++++--------------------------------- 1 file changed, 133 insertions(+), 260 deletions(-) diff --git a/src/easing.js b/src/easing.js index 0f991ebfb..55bf3c4d3 100644 --- a/src/easing.js +++ b/src/easing.js @@ -5,40 +5,28 @@ var easing = module.exports = { /** - * linear - * + * Linear ease with no acceleration * @public */ linear: function(n) { return n; }, /** - * cubicIn - * + * Accelerating with second-degree polynomial. * @public */ - cubicIn: function(n) { - return Math.pow(n, 3); - }, - /** - * cubicOut - * - * @public - */ - cubicOut: function(n) { - return Math.pow(n - 1, 3) + 1; + quadIn: function(t) { + return t * t; }, /** - * expoOut - * + * Deaccelerating with second-degree polynomial. * @public */ - expoOut: function(n) { - return (n == 1) ? 1 : (-1 * Math.pow(2, -10 * n) + 1); + quadOut: function(t) { + return -1 * t * (t - 2); }, /** - * quadInOut - * + * Halfway accelerating and then deaccelerating with second-degree polynomial. * @public */ quadInOut: function(n) { @@ -48,262 +36,151 @@ var easing = module.exports = { } return -1 * ((--n) * (n - 2) - 1) / 2; }, - - /** - * EaseInQuad - * @public - * @param {number} t - current time - * @return {number} - calculated time - */ - easeInQuad: function(t) { - return t * t; - }, - - /** - * EaseOutQuad - * @public - * @param {number} t - current time - * @return {number} calculated time - */ - easeOutQuad: function(t) { - return -1 * t * (t - 2); - }, - /** - * EaseInOutQuad - * @public - * @param {number} t - current time - * @return {number} calculated time - */ - easeInOutQuad: function(t) { - if ((t *= 2) < 1) return 0.5 * t * t; - return -0.5 * ((--t) * (t - 2) - 1); - }, - - /** - * EaseInCubic - * @public - * @param {number} t - current time - * @return {number} calculated time - */ - easeInCubic: function(t) { - return t * t * t; + * Accelerating with third-degree polynomial. + * @public + */ + cubicIn: function(n) { + return Math.pow(n, 3); }, - /** - * EaseOutCubic - * @public - * @param {number} t - current time - * @return {number} calculated time - */ - easeOutCubic: function(t) { - return --t * t * t + 1; + * Deaccelerating with third-degree polynomial. + * @public + */ + cubicOut: function(n) { + return Math.pow(n - 1, 3) + 1; }, - /** - * EaseInOutCubic - * @public - * @param {number} t - current time - * @return {number} calculated time - */ - easeInOutCubic: function(t) { + * Halfway accelerating and then deaccelerating with third-degree polynomial. + * @public + */ + cubicInOut: function(t) { if ((t *= 2) < 1) return 0.5 * t * t * t; return 0.5 * ((t -= 2) * t * t + 2); }, - /** - * EaseInQuart - * @public - * @param {number} t - current time - * @return {number} calculated time - */ - easeInQuart: function(t) { + * Accelerating with fourth-degree polynomial + * @public + */ + quartIn: function(t) { return t * t * t * t; }, - /** - * EaseOutQuart - * @public - * @param {number} t - current time - * @return {number} calculated time - */ - easeOutQuart: function(t) { + * Deaccelerating with fourth-degree polynomial + * @public + */ + quartOut: function(t) { return -1 * (--t * t * t * t - 1); }, - /** - * EaseInOutQuart - * @public - * @param {number} t - current time - * @return {number} calculated time - */ + * Halfway accelerating and then deaccelerating with fourth-degree polynomial + * @public + */ easeInOutQuart: function(t) { if ((t *= 2) < 1) return 0.5 * t * t * t * t; return -0.5 * ((t -= 2) * t * t * t - 2); }, - /** - * EaseInQuint - * @public - * @param {number} t - current time - * @return {number} calculated time - */ - easeInQuint: function(t) { + * Accelerating with fifth-degree polynomial + * @public + */ + quintIn: function(t) { return t * t * t * t * t; }, /** - * EaseOutQuint - * @public - * @param {number} t - current time - * @return {number} calculated time - */ - easeOutQuint: function(t) { + * Deaccelerating with fifth-degree polynomial + * @public + */ + quintOut: function(t) { return --t * t * t * t * t + 1; }, - /** - * EaseInOutQuint - * @public - * @param {number} t - current time - * @return {number} calculated time - */ - easeInOutQuint: function(t, d) { + * Halfway accelerating and then deaccelerating with fifth-degree polynomial + * @public + */ + quintInOut: function(t, d) { if ((t *= 2) < 1) return 0.5 * t * t * t * t * t; return 0.5 * ((t -= 2) * t * t * t * t + 2); }, - /** - * EaseInSine - * @public - * @param {number} t - current time - * @return {number} calculated time - */ - easeInSine: function(t) { + * Accelerating using a sine formula + * @public + */ + sineIn: function(t) { return -1 * Math.cos(t * (Math.PI / 2)) + 1; }, - /** - * EaseOutSine - * @public - * @param {number} t - current time - * @return {number} calculated time - */ - easeOutSine: function(t) { + * Deaccelerating using a sine formula + * @public + */ + sineOut: function(t) { return Math.sin(t * (Math.PI / 2)); }, - /** - * EaseInOutSine - * @public - * @param {number} t - current time - * @return {number} calculated time - */ - easeInOutSine: function(t) { + * Halfway accelerating and then deaccelerating using a sine formula + * @public + */ + sineInOut: function(t) { return -0.5 * (Math.cos(Math.PI * t) - 1); }, - /** - * EaseInExpo - * @public - * @param {number} t - current time - * @return {number} calculated time - */ - easeInExpo: function(t) { + * Accelerating using an exponential formula + * @public + */ + expoIn: function(t) { return (t === 0) ? 0 : Math.pow(2, 10 * (t - 1)); }, - /** - * EaseOutExpo - * @public - * @param {number} t - current time - * @return {number} calculated time - */ - easeOutExpo: function(t) { - return (t === 1) ? 1 : -Math.pow(2, -10 * t) + 1; + * Deaccelerating using an exponential formula + * @public + */ + expoOut: function(n) { + return (n == 1) ? 1 : (-1 * Math.pow(2, -10 * n) + 1); }, - /** - * EaseInOutExpo - * @public - * @param {number} t - current time - * @return {number} calculated time - */ - easeInOutExpo: function(t) { + * Halfway accelerating and then deaccelerating using an exponential formula + * @public + */ + expoInOut: function(t) { if (t === 0) return 0; if (t === 1) return 1; if ((t *= 2) < 1) return 0.5 * Math.pow(2, 10 * (t - 1)); return 0.5 * (-Math.pow(2, -10 * --t) + 2); }, - /** - * EaseInCirc - * @public - * @param {number} t - current time - * @return {number} calculated time - */ - easeInCirc: function(t) { + * Accelerating using a circular function + * @public + */ + circIn: function(t) { return -1 * (Math.sqrt(1 - t * t) - 1); }, - /** - * EaseOutCirc - * @public - * @param {number} t - current time - * @return {number} calculated time - */ - easeOutCirc: function(t) { + * Deaccelerating using a circular function + * @public + */ + circOut: function(t) { return Math.sqrt(1 - (--t * t)); }, - /** - * EaseInOutCirc - * @public - * @param {number} t - current time - * @return {number} calculated time - */ - easeInOutCirc: function(t) { + * Halfway accelerating and then deaccelerating using a circular function + * @public + */ + circInOut: function(t) { if ((t *= 2) < 1) return -0.5 * (Math.sqrt(1 - t * t) - 1); return 0.5 * (Math.sqrt(1 - (t -= 2) * t) + 1); }, - - /** - * EaseInElastic - * @public - * @param {number} t - current time - * @param {number} d - duration - * @return {number} calculated time - */ - easeInElastic: function(t, d) { - var a = 1, - p = 0, - s = 1.70158; - if (t === 0) return 0; - if (t === 1) return 1; - if (!p) p = d * 0.3; - if (a < 1) { - a = 1; - s = p / 4; - } else s = p / (2 * Math.PI) * Math.asin(1 / a); - return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)); - }, - /** - * EaseInBounce - * @public - * @param {number} t - current time - * @return {number} calculated time - */ - easeInBounce: function(t) { + * Accelerating with a bouncing effect + * @public + */ + bounceIn: function(t) { return 1 - easing.easeOutBounce(1 - t); }, - /** - * EaseOutBounce - * @public - * @param {number} t - current time - * @return {number} calculated time - */ - easeOutBounce: function(t) { + * Deaccelerating with a bouncing effect + * @public + */ + bounceOut: function(t) { if (t < 0.363636) { return 7.5625 * t * t; } else if (t < 0.727272) { @@ -314,26 +191,36 @@ var easing = module.exports = { return 7.5625 * (t -= 0.954545) * t + 0.984375; } }, - /** - * EaseInOutBounce - * @public - * @param {number} t - current time - * @return {number} calculated time - */ - easeInOutBounce: function(t) { + * Halfway accelerating and then deaccelerating with a bouncing effect + * @public + */ + bounceInOut: function(t) { if (t < 0.5) return easing.easeInBounce(t * 2) * 0.5; return easing.easeOutBounce(t * 2 - 1) * 0.5 + 0.5; }, - /** - * EaseOutElastic - * @public - * @param {number} t - current time - * @param {number} d - duration - * @return {number} calculated time - */ - easeOutElastic: function(t, d) { + * Accelerating as a spring oscillating back and forth until it comes to rest + * @public + */ + elasticIn: function(t, d) { + var a = 1, + p = 0, + s = 1.70158; + if (t === 0) return 0; + if (t === 1) return 1; + if (!p) p = d * 0.3; + if (a < 1) { + a = 1; + s = p / 4; + } else s = p / (2 * Math.PI) * Math.asin(1 / a); + return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)); + }, + /** + * Deaccelerating as a spring oscillating back and forth until it comes to rest + * @public + */ + elasticOut: function(t, d) { var a = 1, p = 0, s = 1.70158; @@ -346,15 +233,12 @@ var easing = module.exports = { } else s = p / (2 * Math.PI) * Math.asin(1 / a); return a * Math.pow(2, -10 * t) * Math.sin((t * d - s) * (2 * Math.PI) / p) + 1; }, - /** - * EaseInOutElastic - * @public - * @param {number} t - current time - * @param {number} d - duration - * @return {number} calculated time - */ - easeInOutElastic: function(t, d) { + * Halfway accelerating and then deaccelerating as a spring + * oscillating back and forth until it comes to rest + * @public + */ + elasticInOut: function(t, d) { var a = 1, p = 0, s = 1.70158; @@ -368,39 +252,28 @@ var easing = module.exports = { if (t < 1) return -0.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)); return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p) * 0.5 + 1; }, - /** - * EaseInBack - * @public - * @param {number} t - current time - * @param {number} d - duration - * @return {number} calculated time - */ - easeInBack: function(t, d, s) { + * Accelerating while retracting slightly before it begins to animate in the path indicated + * @public + */ + backIn: function(t, d, s) { if (!s) s = 1.70158; return t * t * ((s + 1) * t - s); }, - /** - * EaseOutBack - * @public - * @param {number} t - current time - * @param {number} d - duration - * @return {number} calculated time - */ - easeOutBack: function(t, d, s) { + * Deaccelerating while retracting slightly before it begins to animate in the path indicated + * @public + */ + backOut: function(t, d, s) { if (!s) s = 1.70158; return --t * t * ((s + 1) * t + s) + 1; }, - /** - * EaseInOutBack - * @public - * @param {number} t - current time - * @param {number} d - duration - * @return {number} calculated time - */ - easeInOutBack: function(t, d, s) { + * Halfway accelerating and then deaccelerating while retracting + * slightly before it begins to animate in the path indicated + * @public + */ + backInOut: function(t, d, s) { if (!s) s = 1.70158; if ((t *= 2) < 1) return 0.5 * (t * t * (((s *= (1.525)) + 1) * t - s)); return 0.5 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2); From 4438b93493275d24dddf28d2ee594bc8b711884f Mon Sep 17 00:00:00 2001 From: Anish_Ramesan Date: Thu, 16 Jun 2016 21:15:22 +0530 Subject: [PATCH 27/32] easing update Enyo-DCO-1.1-Signed-off-by: Anish Ramesan --- src/easing.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/easing.js b/src/easing.js index 55bf3c4d3..daf5f0122 100644 --- a/src/easing.js +++ b/src/easing.js @@ -174,7 +174,7 @@ var easing = module.exports = { * @public */ bounceIn: function(t) { - return 1 - easing.easeOutBounce(1 - t); + return 1 - easing.bounceOut(1 - t); }, /** * Deaccelerating with a bouncing effect @@ -196,8 +196,8 @@ var easing = module.exports = { * @public */ bounceInOut: function(t) { - if (t < 0.5) return easing.easeInBounce(t * 2) * 0.5; - return easing.easeOutBounce(t * 2 - 1) * 0.5 + 0.5; + if (t < 0.5) return easing.bounceIn(t * 2) * 0.5; + return easing.bounceOut(t * 2 - 1) * 0.5 + 0.5; }, /** * Accelerating as a spring oscillating back and forth until it comes to rest From fed3bfd79d9794d405b494eaa07b7a4dff27a331 Mon Sep 17 00:00:00 2001 From: Ankur Mishra Date: Fri, 17 Jun 2016 11:54:32 +0530 Subject: [PATCH 28/32] Update remaining easing Enyo-DCO-1.1-Signed-off-by: Ankur Mishra --- src/easing.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/easing.js b/src/easing.js index daf5f0122..080decc92 100644 --- a/src/easing.js +++ b/src/easing.js @@ -76,7 +76,7 @@ var easing = module.exports = { * Halfway accelerating and then deaccelerating with fourth-degree polynomial * @public */ - easeInOutQuart: function(t) { + quartInOut: function(t) { if ((t *= 2) < 1) return 0.5 * t * t * t * t; return -0.5 * ((t -= 2) * t * t * t - 2); }, From 40dfb4fec823d42caf2f29eb900d97b66535be84 Mon Sep 17 00:00:00 2001 From: Anish_Ramesan Date: Fri, 17 Jun 2016 16:16:50 +0530 Subject: [PATCH 29/32] tween api documented Enyo-DCO-1.1-Signed-off-by: Anish Ramesan --- src/tween.js | 202 +++++++++++++++++++++++++++++---------------------- 1 file changed, 116 insertions(+), 86 deletions(-) diff --git a/src/tween.js b/src/tween.js index 28140c298..402b19e29 100644 --- a/src/tween.js +++ b/src/tween.js @@ -19,7 +19,12 @@ var fn, state, ease, points, path, oldState, newState, node, matrix, cState = [] module.exports = { /** - * @private + * Indentifies initial pose of an element. + * @param {Object} actor - Element to be animated + * @param {Object} pose - Current behavior in the animation (at a given time) + * @param {Object} pose - Current behavior in the animation (at a given time) + * @memberOf module:enyo/tween + * @public */ init: function(actor, pose, initial) { var k; @@ -41,7 +46,7 @@ module.exports = { * @param {Number} t - Fraction which represents the animation (between 0 to 1) * @param {Number} d - Duration of the current pose * @memberOf module:enyo/tween - * @private + * @public */ step: function(actor, pose, t, d) { if (!(actor && pose && pose.animate)) return; @@ -110,6 +115,13 @@ module.exports = { actor.addStyles(domCSS); }, + /** + * This causes the stopped animation to be removed from GPU layer. + * @param {Object} actor - Element to be animated + * @param {Object} pose - Current behavior in the animation (at a given time) + * @memberOf module:enyo/tween + * @public + */ halt: function(actor, pose) { var matrix = pose.currentState && pose.currentState.matrix; @@ -122,8 +134,8 @@ module.exports = { * Overridden function for applying the default ease. * @param {Number} t - Fraction which represents the animation (between 0 to 1) * @return {Number} t - * @memberOf module:enyo/AnimationSupport/Tween - * @private + * @memberOf module:enyo/tween + * @public * @override */ ease: function(t) { @@ -137,8 +149,8 @@ module.exports = { * @param {Number} t - Fraction which represents the animation (between 0 to 1) * @param {Number[]} vR - Resultant vector * @return {Number[]} vR - * @memberOf module:enyo/AnimationSupport/Tween - * @private + * @memberOf module:enyo/tween + * @public */ lerp: function(vA, vB, t, vR) { if (!vA) return; @@ -158,8 +170,8 @@ module.exports = { * @param {Number} t - Fraction which represents the animation (between 0 to 1) * @param {Number[]} qR - Resultant quaternion * @return {Number[]} qR - * @memberOf module:enyo/AnimationSupport/Tween - * @private + * @memberOf module:enyo/tween + * @public */ slerp: function(qA, qB, t, qR) { if (!qA) return; @@ -190,7 +202,8 @@ module.exports = { * @param {Number[]} points - knot and control points * @param {Number[]} vR - Resulting points * @return {Number[]} vR - * @memberOf module:enyo/AnimationSupport/Tween + * @memberOf module:enyo/tween + * @public */ bezier: function(t, points, vR) { if (!points) return; @@ -224,7 +237,8 @@ module.exports = { * @param {Number[]} endPoint - End point of the curve * @param {Number[]} points - control points * @return {Number[]} points - * @memberOf module:enyo/AnimationSupport/Tween + * @memberOf module:enyo/tween + * @public */ bezierPoints: function(easeObj, startPoint, endPoint, points) { if (!easeObj) return; @@ -268,7 +282,8 @@ module.exports = { * @param {Number[]} path - Array of points * @param {Number[]} vR Resulatant Array * @return {Number[]} vR - * @memberOf module:enyo/AnimationSupport/Tween + * @memberOf module:enyo/tween + * @public */ traversePath: function(t, path, vR) { if (!path) return; @@ -297,7 +312,8 @@ module.exports = { * @param {Number[]} endPoint - Final Destination point * @param {Number[]} splinePoints - spline control points * @return {Number[]} splinePoints - * @memberOf module:enyo/AnimationSupport/Tween + * @memberOf module:enyo/tween + * @public */ bezierSPoints: function(ease, startQuat, endQuat, endPoint, splinePoints) { if (!ease) return; @@ -348,7 +364,8 @@ module.exports = { * @param {Number[]} points - knot and control points * @param {Number[]} vR - Resulting points * @return {Number[]} vR - * @memberOf module:enyo/AnimationSupport/Tween + * @memberOf module:enyo/tween + * @public */ bezierSpline: function(t, points, vR) { if (!points) return; @@ -375,40 +392,13 @@ module.exports = { return vR; }, - /** - * This function returns the coefficents based on the order and the current position - * @private - * @param {number} n - order - * @param {number} k - current position - * @return {object} - coefficients - */ - getCoeff: function(n, k) { - n = parseInt(n, 10); - k = parseInt(k, 10); - // Credits - // https://math.stackexchange.com/questions/202554/how-do-i-compute-binomial-coefficients-efficiently#answer-927064 - if (isNaN(n) || isNaN(k)) - return void 0; - if ((n < 0) || (k < 0)) - return void 0; - if (k > n) - return void 0; - if (k === 0) - return 1; - if (k === n) - return 1; - if (k > n / 2) - return this.getCoeff(n, n - k); - - return n * this.getCoeff(n - 1, k - 1) / k; - }, - /** * Function to get the bezier coeffients based on the time and order - * @public * @param {number} t - time * @param {number} n - order * @return {object} - bezier coefficients + * @memberOf module:enyo/tween + * @public */ getBezierValues: function(t, n) { t = parseFloat(t, 10), @@ -430,7 +420,7 @@ module.exports = { // Binomial theorem to expand (x+y)^n // for (var k = 0; k <= n; k++) { - c = this.getCoeff(n, k) * Math.pow(x, (n - k)) * Math.pow(y, k); + c = getCoeff(n, k) * Math.pow(x, (n - k)) * Math.pow(y, k); values.push(c); } @@ -438,13 +428,41 @@ module.exports = { } }; +/** + * This function returns the coefficents based on the order and the current position + * @param {number} n - order + * @param {number} k - current position + * @return {object} - coefficients + * @private + */ +function getCoeff (n, k) { + n = parseInt(n, 10); + k = parseInt(k, 10); + // Credits + // https://math.stackexchange.com/questions/202554/how-do-i-compute-binomial-coefficients-efficiently#answer-927064 + if (isNaN(n) || isNaN(k)) + return void 0; + if ((n < 0) || (k < 0)) + return void 0; + if (k > n) + return void 0; + if (k === 0) + return 1; + if (k === n) + return 1; + if (k > n / 2) + return getCoeff(n, n - k); + + return n * getCoeff(n - 1, k - 1) / k; +} + /** * Get DOM node animation properties. - * @public * @param {HTMLElement} node DOM node * @param {Object} props Properties to fetch from DOM. * @param {Object} initial Default properties to be applied. * @return {Object} Object with various animation properties. + * @private */ function getAnimatedProperty(node, props, initial) { if (!node) return; @@ -509,6 +527,9 @@ function getAnimatedProperty(node, props, initial) { }; } +/** +* @private +*/ function merge (ar1, ar2) { ar1.map(function(num, id) { return num + ar2[id]; @@ -519,7 +540,7 @@ function merge (ar1, ar2) { /** * Converts comma separated values to array. - * @public + * @private * @param {String} val Value of required animation in any property. * @param {Number} length [description] * @param {[type]} prop [description] @@ -546,49 +567,52 @@ function formatCSSValues(val, prop, length) { return length ? res.concat(Array(length - res.length).fill(0)): res; } +/** +* @private +*/ function formatTransformValues(val, prop) { var res; switch (prop) { - case 'translateX': - case 'rotateX': - case 'skewX': - res = [parseFloat(val, 10), 0, 0]; - break; - case 'translateY': - case 'rotateY': - case 'skewY': - res = [0, parseFloat(val, 10), 0]; - break; - case 'translateZ': - case 'rotateZ': - res = [0, 0, parseFloat(val, 10)]; - break; - case 'scaleX': - res = [parseFloat(val, 10), 1, 1]; - break; - case 'scaleY': - res = [1, parseFloat(val, 10), 1]; - break; - case 'scaleZ': - res = [1, 1, parseFloat(val, 10)]; - break; - case 'matrix': - res = transform.Matrix.identity(); - val = stringToMatrix(val.replace(/^\w*\(/, '').replace(')', '')); - if (val.length <= 6) { - res[0] = val[0]; - res[1] = val[1]; - res[4] = val[2]; - res[5] = val[3]; - res[12] = val[4]; - res[13] = val[5]; - } - if (val.length == 16) { - res = val; - } - break; - default: - res = stringToMatrix(val); + case 'translateX': + case 'rotateX': + case 'skewX': + res = [parseFloat(val, 10), 0, 0]; + break; + case 'translateY': + case 'rotateY': + case 'skewY': + res = [0, parseFloat(val, 10), 0]; + break; + case 'translateZ': + case 'rotateZ': + res = [0, 0, parseFloat(val, 10)]; + break; + case 'scaleX': + res = [parseFloat(val, 10), 1, 1]; + break; + case 'scaleY': + res = [1, parseFloat(val, 10), 1]; + break; + case 'scaleZ': + res = [1, 1, parseFloat(val, 10)]; + break; + case 'matrix': + res = transform.Matrix.identity(); + val = stringToMatrix(val.replace(/^\w*\(/, '').replace(')', '')); + if (val.length <= 6) { + res[0] = val[0]; + res[1] = val[1]; + res[4] = val[2]; + res[5] = val[3]; + res[12] = val[4]; + res[13] = val[5]; + } + if (val.length == 16) { + res = val; + } + break; + default: + res = stringToMatrix(val); } return res; } @@ -603,6 +627,9 @@ function isTransform(transform) { return TRANSFORM[transform]; } +/** +* @private +*/ function stringToMatrix(val) { if (!val || val === "auto" || val === 'none') { return 0; @@ -612,6 +639,9 @@ function stringToMatrix(val) { }); } +/** +* @private +*/ function toPropertyValue(prop, val, ret) { if (!val) return; ret = ret || {}; @@ -657,7 +687,7 @@ function toTransformValue (matrix, ret) { /** * Gets a style property applied from the DOM element. - * @public + * @private * @param {HTMLElement} style Computed style of a DOM. * @param {String} key Property name for which style has to be fetched. * @return {Number|HTMLElement} From 5e87d50ddcc6d7f29095ed1feebf8f7541c1c15b Mon Sep 17 00:00:00 2001 From: Ankur Mishra Date: Fri, 17 Jun 2016 17:04:33 +0530 Subject: [PATCH 30/32] Some bug fix related to non transformable properties Enyo-DCO-1.1-Signed-off-by: Ankur Mishra --- src/tween.js | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/src/tween.js b/src/tween.js index 402b19e29..85dfcb11c 100644 --- a/src/tween.js +++ b/src/tween.js @@ -467,7 +467,9 @@ function getCoeff (n, k) { function getAnimatedProperty(node, props, initial) { if (!node) return; - var eP = {}, + var + diff, + eP = {}, sP = initial ? utils.mixin({}, initial) : {}, tP = {}, dP = {}, @@ -481,7 +483,15 @@ function getAnimatedProperty(node, props, initial) { v = v || getStyleValue(s || dom.getComputedStyle(node), k); iP[k] = v; sP[k] = formatCSSValues(v, k); - eP[k] = formatCSSValues(props[k], k, sP[k] ? sP[k].length : sP[k]); + eP[k] = formatCSSValues(props[k], k); + if (sP[k].length) { + diff = sP[k].length - eP[k].length; + if(diff > 0) { + eP[k] = eP[k].concat(Array(diff).fill(0)); + } else { + sP[k] = sP[k].concat(Array(-1 * diff).fill(0)); + } + } } else { v = formatTransformValues(props[k], k); if (k.match(/rotate/)) { @@ -541,13 +551,11 @@ function merge (ar1, ar2) { /** * Converts comma separated values to array. * @private - * @param {String} val Value of required animation in any property. - * @param {Number} length [description] - * @param {[type]} prop [description] + * @param {String} val Value of required animation in any property. + * @param {String} prop Property name of which value has been provided. * @return {Number[]} Create array from val. */ -function formatCSSValues(val, prop, length) { - var res; +function formatCSSValues(val, prop) { if (typeof val === 'function') { return val; } @@ -563,8 +571,7 @@ function formatCSSValues(val, prop, length) { val = val.split('rgb(')[1].replace(')',',').concat(val.split('rgb(')[0]).replace(/, $/,''); } } - res = stringToMatrix(val); - return length ? res.concat(Array(length - res.length).fill(0)): res; + return stringToMatrix(val); } /** @@ -653,7 +660,9 @@ function toPropertyValue(prop, val, ret) { } else if (INT_UNIT[prop]) { val = parseInt(val[0], 10); } else if (BORDER[prop]) { - val = val[0] + '%'; + val = val.map(function(v) { + return v + '%'; + }).join(' '); } else if (OPACITY[prop]) { val = val[0].toFixed(6); val = (val <= 0) ? '0.000001' : val; From de78f70e74a8e484d7b997cd571686503d9f08fc Mon Sep 17 00:00:00 2001 From: Ankur Mishra Date: Fri, 17 Jun 2016 18:26:53 +0530 Subject: [PATCH 31/32] Replace switch case in 'formatTransformValues' function Enyo-DCO-1.1-Signed-off-by: Ankur Mishra --- src/tween.js | 42 ++++++++++++++---------------------------- 1 file changed, 14 insertions(+), 28 deletions(-) diff --git a/src/tween.js b/src/tween.js index 85dfcb11c..5c6d975ef 100644 --- a/src/tween.js +++ b/src/tween.js @@ -578,32 +578,13 @@ function formatCSSValues(val, prop) { * @private */ function formatTransformValues(val, prop) { - var res; - switch (prop) { - case 'translateX': - case 'rotateX': - case 'skewX': - res = [parseFloat(val, 10), 0, 0]; - break; - case 'translateY': - case 'rotateY': - case 'skewY': - res = [0, parseFloat(val, 10), 0]; - break; - case 'translateZ': - case 'rotateZ': - res = [0, 0, parseFloat(val, 10)]; - break; - case 'scaleX': - res = [parseFloat(val, 10), 1, 1]; - break; - case 'scaleY': - res = [1, parseFloat(val, 10), 1]; - break; - case 'scaleZ': - res = [1, 1, parseFloat(val, 10)]; - break; - case 'matrix': + var + res, + X, Y, Z, + last = prop.match(/[XYZ]$/), + defalt = prop.match(/scale/) ? 1 : 0; + + if (prop === 'matrix') { res = transform.Matrix.identity(); val = stringToMatrix(val.replace(/^\w*\(/, '').replace(')', '')); if (val.length <= 6) { @@ -617,8 +598,13 @@ function formatTransformValues(val, prop) { if (val.length == 16) { res = val; } - break; - default: + } else if (last) { + val = parseFloat(val, 10); + X = (last[0] === 'X') ? val : defalt; + Y = (last[0] === 'Y') ? val : defalt; + Z = (last[0] === 'Z') ? val : defalt; + res = [X, Y, Z]; + } else { res = stringToMatrix(val); } return res; From e3cbd9b421f14211ced26e109daf16376dbe691b Mon Sep 17 00:00:00 2001 From: Ankur Mishra Date: Wed, 22 Jun 2016 10:05:01 +0530 Subject: [PATCH 32/32] Made correction in time comparision Enyo-DCO-1.1-Signed-off-by: Ankur Mishra --- src/scene.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scene.js b/src/scene.js index 4037f6e41..5ec9270d8 100644 --- a/src/scene.js +++ b/src/scene.js @@ -426,7 +426,7 @@ function update(pose, actor, since, dur) { if (since < 0) since = 0; if (since <= dur && dur !== 0) { t = since / dur; - tween.step(actor, pose, t > 0.98 ? 1 : t, dur); + tween.step(actor, pose, t, dur); } else { tween.step(actor, pose, 1, dur); }