collide updates

This commit is contained in:
Adam Bradley
2015-04-28 10:34:47 -05:00
parent d1c78bc5bf
commit 19c16e7433
4 changed files with 90 additions and 77 deletions

View File

@ -3,6 +3,7 @@ import {Collide} from './collide'
import {processElement} from './process-element' import {processElement} from './process-element'
import {animationStop} from './animation-stop' import {animationStop} from './animation-stop'
import {startTick} from './tick' import {startTick} from './tick'
import {dom} from 'ionic/util'
const data = Collide.data; const data = Collide.data;
@ -12,6 +13,8 @@ export class Animation {
this._elements = null; this._elements = null;
this._options = {}; this._options = {};
this._properties = {}; this._properties = {};
this._resolve = null;
this._call = null;
} }
elements(ele) { elements(ele) {
@ -22,40 +25,69 @@ export class Animation {
} }
} }
_setupElements(clearCache) { _setupElements(clearCache, onNextFrame) {
/**********************************
Animation Call-Wide Variables
**********************************/
/* A container for CSS unit conversion ratios (e.g. %, rem, and em ==> px) that is used to cache ratios across all elements // ensure another animation wasnt about to start
being animated in a single Collide call. Calculating unit ratios necessitates DOM querying and updating, and is therefore if (this._nextAF) {
avoided (via caching) wherever possible. This container is call-wide instead of page-wide to avoid the risk of using stale dom.rafCancel(this._nextAF);
conversion metrics across Collide animations that are not immediately consecutively chained. */
this._unitConversion = {
lastParent: null,
lastPosition: null,
lastFontSize: null,
lastPercentToPxWidth: null,
lastPercentToPxHeight: null,
lastEmToPx: null,
remToPx: null,
vwToPx: null,
vhToPx: null
};
this._call = [];
this._options = util.extend({}, Collide.defaults, this._options);
for (var i = 0, ii = this._elements.length; i < ii; i++) {
processElement('start', this, i, clearCache);
} }
if (this.isAnimating()) {
this.stop();
}
this._promise = new Promise(res => {
this._resolve = res;
});
this._call = null;
// in the next frame, do all the DOM GETs to load element info
this._nextAF = dom.raf(() => {
/**********************************
Animation Call-Wide Variables
**********************************/
/* A container for CSS unit conversion ratios (e.g. %, rem, and em ==> px) that is used to cache ratios across all elements
being animated in a single Collide call. Calculating unit ratios necessitates DOM querying and updating, and is therefore
avoided (via caching) wherever possible. This container is call-wide instead of page-wide to avoid the risk of using stale
conversion metrics across Collide animations that are not immediately consecutively chained. */
this._unitConversion = {
lastParent: null,
lastPosition: null,
lastFontSize: null,
lastPercentToPxWidth: null,
lastPercentToPxHeight: null,
lastEmToPx: null,
remToPx: null,
vwToPx: null,
vhToPx: null
};
this._call = [];
this._options = util.extend({}, Collide.defaults, this._options);
// get the elements ready
for (var i = 0, ii = this._elements.length; i < ii; i++) {
processElement('start', this, i, clearCache);
}
onNextFrame();
});
} }
_queueAnimation() { _queueAnimation() {
/* Switch on the element's animating flag. */ /* Switch on the element's animating flag. */
if (this._call === null) return;
var eleData;
for (var i = 0, ii = this._elements.length, element; i < ii && (element = this._elements[i]); i++) { for (var i = 0, ii = this._elements.length, element; i < ii && (element = this._elements[i]); i++) {
data(element).isAnimating = true; eleData = data(element);
if (eleData) {
eleData.isAnimating = true;
}
/********************* /*********************
Auto-Dequeuing Auto-Dequeuing
@ -87,27 +119,37 @@ export class Animation {
} }
start() { start() {
// get the elements ready var clearCache = (this._aniType !== 'start');
if (this.isAnimating()) {
this.stop();
if (this._resolve) {
this._resolve();
}
}
this._resolve; this._setupElements(clearCache, () => {
this._promise = new Promise(res => { this._aniType = 'start';
this._resolve = res; this._queueAnimation();
}); });
this._setupElements(this._lastType !== 'start');
this._lastType = 'start';
this._queueAnimation();
return this._promise; return this._promise;
} }
ready() {
var clearCache = (this._aniType !== 'percent');
this._setupElements(clearCache, () => {
this._aniType = 'percent';
});
return this._promise;
}
percent(percentComplete) {
// go to and stop at a specific point in the animation
if (this._aniType = 'percent') {
this._options.percentComplete = percentComplete;
this._queueAnimation();
startTick();
}
}
stop() { stop() {
// immediately stop where it's at // immediately stop where it's at
animationStop(this._elements, 'stop'); animationStop(this._elements, 'stop');
@ -118,37 +160,6 @@ export class Animation {
animationStop(this._elements, 'finish'); animationStop(this._elements, 'finish');
} }
ready() {
// get the elements ready
if (this.isAnimating()) {
this.stop();
if (this._resolve) {
this._resolve();
}
}
this._resolve;
this._promise = new Promise(res => {
this._resolve = res;
});
this._setupElements(this._lastType !== 'percent');
this._lastType = 'percent';
return this._promise;
}
percent(percentComplete) {
// go to and stop at a specific point in the animation
// must call ready() first
this._options.percentComplete = parseFloat(percentComplete);
this._queueAnimation();
startTick();
}
isAnimating() { isAnimating() {
var eleData; var eleData;
if (this._elements) { if (this._elements) {

View File

@ -155,7 +155,7 @@ export function completeCall(callIndex, isStopped) {
/* Iterate through the calls array to determine if this was the final in-progress animation. /* Iterate through the calls array to determine if this was the final in-progress animation.
If so, set a flag to end ticking and clear the calls array. */ If so, set a flag to end ticking and clear the calls array. */
for (var j = 0, jj = Collide.State.calls.length; j < jj; j++) { for (var j = 0, jj = Collide.State.calls.length; j < jj; j++) {
if (Collide.State.calls[j] !== false) { if (Collide.State.calls[j] !== false && Collide.State.calls[j][0]) {
remainingCallsExist = true; remainingCallsExist = true;
break; break;
} }

View File

@ -613,8 +613,6 @@ export function processElement(action, animation, elementIndex, clearCache) {
}; };
if (Collide.debug) console.log('tweensContainer (' + property + '): ' + JSON.stringify(tweensContainer[property]), element); if (Collide.debug) console.log('tweensContainer (' + property + '): ' + JSON.stringify(tweensContainer[property]), element);
console.log('processElement parsePropertyValue: startValue', startValue, 'currentValue', currentValue, 'endValue', endValue);
} }
/* Along with its property data, store a reference to the element itself onto tweensContainer. */ /* Along with its property data, store a reference to the element itself onto tweensContainer. */

View File

@ -65,6 +65,10 @@ function tick(timestamp) {
firstTick = !!timeStart, firstTick = !!timeStart,
tweenDummyValue = null; tweenDummyValue = null;
if (!call) {
continue;
}
/* If timeStart is undefined, then this is the first time that this call has been processed by tick(). /* If timeStart is undefined, then this is the first time that this call has been processed by tick().
We assign timeStart now so that its value is as close to the real animation start time as possible. We assign timeStart now so that its value is as close to the real animation start time as possible.
(Conversely, had timeStart been defined when this call was added to Collide.State.calls, the delay (Conversely, had timeStart been defined when this call was added to Collide.State.calls, the delay
@ -79,7 +83,7 @@ function tick(timestamp) {
var percentComplete; var percentComplete;
if (opts.percentComplete !== undefined) { if (opts.percentComplete !== undefined) {
percentComplete = Math.max(Math.min(opts.percentComplete, 1), 0); percentComplete = Math.max(Math.min(parseFloat(opts.percentComplete), 1), 0);
} else { } else {
/* The tween's completion percentage is relative to the tween's start time, not the tween's start value /* The tween's completion percentage is relative to the tween's start time, not the tween's start value