mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
just a few minor animation tweaks
This commit is contained in:
@@ -1,28 +1,30 @@
|
||||
import * as util from 'ionic/util/util';
|
||||
import {CSS} from '../util/dom';
|
||||
|
||||
|
||||
let registry = {};
|
||||
let AnimationRegistry = {};
|
||||
|
||||
export class Animation {
|
||||
|
||||
constructor(el) {
|
||||
this._el = [];
|
||||
this._parent = null;
|
||||
this._children = [];
|
||||
this._players = [];
|
||||
const self = this;
|
||||
|
||||
this._from = null;
|
||||
this._to = null;
|
||||
this._duration = null;
|
||||
this._easing = null;
|
||||
this._rate = null;
|
||||
self._el = [];
|
||||
self._parent = null;
|
||||
self._children = [];
|
||||
self._animations = [];
|
||||
|
||||
this._beforeAddCls = [];
|
||||
this._beforeRmvCls = [];
|
||||
this._afterAddCls = [];
|
||||
this._afterRmvCls = [];
|
||||
self._from = null;
|
||||
self._to = null;
|
||||
self._duration = null;
|
||||
self._easing = null;
|
||||
self._rate = null;
|
||||
|
||||
this.elements(el);
|
||||
self._bfAdd = [];
|
||||
self._bfRmv = [];
|
||||
self._afAdd = [];
|
||||
self._afRmv = [];
|
||||
|
||||
self.elements(el);
|
||||
}
|
||||
|
||||
elements(el) {
|
||||
@@ -79,12 +81,12 @@ export class Animation {
|
||||
playbackRate(value) {
|
||||
if (arguments.length) {
|
||||
this._rate = value;
|
||||
var i;
|
||||
let i;
|
||||
for (i = 0; i < this._children.length; i++) {
|
||||
this._children[i].playbackRate(value);
|
||||
}
|
||||
for (i = 0; i < this._players.length; i++) {
|
||||
this._players[i].playbackRate(value);
|
||||
for (i = 0; i < this._animations.length; i++) {
|
||||
this._animations[i].playbackRate(value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@@ -107,192 +109,253 @@ export class Animation {
|
||||
return this;
|
||||
}
|
||||
|
||||
get beforePlay() {
|
||||
fromTo(property, from, to) {
|
||||
return this.from(property, from).to(property, to);
|
||||
}
|
||||
|
||||
fadeIn() {
|
||||
return this.fromTo('opacity', 0, 1);
|
||||
}
|
||||
|
||||
fadeOut() {
|
||||
return this.fromTo('opacity', 1, 0);
|
||||
}
|
||||
|
||||
get before() {
|
||||
return {
|
||||
addClass: (className) => {
|
||||
this._beforeAddCls.push(className);
|
||||
this._bfAdd.push(className);
|
||||
return this;
|
||||
},
|
||||
removeClass: (className) => {
|
||||
this._beforeRmvCls.push(className);
|
||||
this._bfRmv.push(className);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
get afterFinish() {
|
||||
get after() {
|
||||
return {
|
||||
addClass: (className) => {
|
||||
this._afterAddCls.push(className);
|
||||
this._afAdd.push(className);
|
||||
return this;
|
||||
},
|
||||
removeClass: (className) => {
|
||||
this._afterRmvCls.push(className);
|
||||
this._afRmv.push(className);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
play() {
|
||||
let i, l;
|
||||
const self = this;
|
||||
const animations = self._animations;
|
||||
const children = self._children;
|
||||
let promises = [];
|
||||
let players = this._players;
|
||||
let i, l;
|
||||
|
||||
for (i = 0, l = this._children.length; i < l; i++) {
|
||||
promises.push( this._children[i].play() );
|
||||
}
|
||||
// the actual play() method which may or may not start async
|
||||
function beginPlay() {
|
||||
let i, l;
|
||||
let promises = [];
|
||||
|
||||
if (!players.length) {
|
||||
// first time played
|
||||
for (i = 0; i < this._el.length; i++) {
|
||||
players.push(
|
||||
new Animate( this._el[i],
|
||||
this._from,
|
||||
this._to,
|
||||
this.duration(),
|
||||
this.easing(),
|
||||
this.playbackRate() )
|
||||
);
|
||||
for (i = 0, l = children.length; i < l; i++) {
|
||||
promises.push( children[i].play() );
|
||||
}
|
||||
|
||||
this._onReady();
|
||||
|
||||
} else {
|
||||
// has been paused, now play again
|
||||
for (i = 0, l = players.length; i < l; i++) {
|
||||
players[i].play();
|
||||
for (i = 0, l = animations.length; i < l; i++) {
|
||||
promises.push( animations[i].play() );
|
||||
}
|
||||
|
||||
return Promise.all(promises);
|
||||
}
|
||||
|
||||
for (i = 0, l = players.length; i < l; i++) {
|
||||
if (players[i].promise) {
|
||||
promises.push(players[i].promise);
|
||||
if (!self._parent) {
|
||||
// this is the top level animation and is in full control
|
||||
// of when the async play() should actually kick off
|
||||
|
||||
// stage all animations and child animations at their starting point
|
||||
self.stage();
|
||||
|
||||
let resolve;
|
||||
let promise = new Promise(res => { resolve = res; });
|
||||
|
||||
function kickoff() {
|
||||
beginPlay().then(() => {
|
||||
for (let i = 0, l = children.length; i < l; i++) {
|
||||
children[i]._onFinish();
|
||||
}
|
||||
self._onFinish();
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
|
||||
if (this._duration > 36) {
|
||||
// begin each animation when everything is rendered in their starting point
|
||||
// give the browser some time to render everything in place before starting
|
||||
setTimeout(() => {
|
||||
kickoff();
|
||||
}, 36);
|
||||
|
||||
} else {
|
||||
// no need to render everything in there place before animating in
|
||||
// just kick it off immediately to render them in their "to" locations
|
||||
kickoff();
|
||||
}
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
let promise = Promise.all(promises);
|
||||
|
||||
promise.then(() => {
|
||||
this._onFinish();
|
||||
});
|
||||
|
||||
return promise;
|
||||
// this is a child animation, it is told exactly when to
|
||||
// start by the top level animation
|
||||
return beginPlay();
|
||||
}
|
||||
|
||||
pause() {
|
||||
this._hasFinished = false;
|
||||
stage() {
|
||||
const self = this;
|
||||
|
||||
var i;
|
||||
for (i = 0; i < this._children.length; i++) {
|
||||
this._children[i].pause();
|
||||
}
|
||||
if (!self._isStaged) {
|
||||
self._isStaged = true;
|
||||
|
||||
for (i = 0; i < this._players.length; i++) {
|
||||
this._players[i].pause();
|
||||
}
|
||||
}
|
||||
let i, l, j, ele;
|
||||
|
||||
progress(value) {
|
||||
var i;
|
||||
for (i = 0, l = self._children.length; i < l; i++) {
|
||||
self._children[i].stage();
|
||||
}
|
||||
|
||||
for (i = 0; i < this._children.length; i++) {
|
||||
this._children[i].progress(value);
|
||||
}
|
||||
for (i = 0; i < self._el.length; i++) {
|
||||
ele = self._el[i];
|
||||
|
||||
if (!this._players.length) {
|
||||
this.play();
|
||||
this.pause();
|
||||
}
|
||||
|
||||
for (i = 0; i < this._players.length; i++) {
|
||||
this._players[i].progress(value);
|
||||
}
|
||||
}
|
||||
|
||||
_onReady() {
|
||||
if (!this._hasPlayed) {
|
||||
this._hasPlayed = true;
|
||||
|
||||
var i, j, ele;
|
||||
for (i = 0; i < this._el.length; i++) {
|
||||
ele = this._el[i];
|
||||
|
||||
for (j = 0; j < this._beforeAddCls.length; j++) {
|
||||
ele.classList.add(this._beforeAddCls[j]);
|
||||
for (j = 0; j < self._bfAdd.length; j++) {
|
||||
ele.classList.add(self._bfAdd[j]);
|
||||
}
|
||||
|
||||
for (j = 0; j < this._beforeRmvCls.length; j++) {
|
||||
ele.classList.remove(this._beforeRmvCls[j]);
|
||||
for (j = 0; j < self._bfRmv.length; j++) {
|
||||
ele.classList.remove(self._bfRmv[j]);
|
||||
}
|
||||
}
|
||||
|
||||
this.onReady && this.onReady();
|
||||
if (self._to) {
|
||||
// only animate the elements if there are defined "to" effects
|
||||
for (i = 0; i < self._el.length; i++) {
|
||||
|
||||
var animation = new Animate( self._el[i],
|
||||
self._from,
|
||||
self._to,
|
||||
self.duration(),
|
||||
self.easing(),
|
||||
self.playbackRate() );
|
||||
|
||||
if (animation.shouldAnimate) {
|
||||
self._animations.push(animation);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
self.onReady && self.onReady();
|
||||
}
|
||||
}
|
||||
|
||||
_onFinish() {
|
||||
if (!this._hasFinished) {
|
||||
this._hasFinished = true;
|
||||
const self = this;
|
||||
let i, j, ele;
|
||||
|
||||
var i, j, ele;
|
||||
if (!self._isFinished) {
|
||||
self._isFinished = true;
|
||||
|
||||
if (this.playbackRate() < 0) {
|
||||
if (self.playbackRate() < 0) {
|
||||
// reverse direction
|
||||
for (i = 0; i < this._el.length; i++) {
|
||||
ele = this._el[i];
|
||||
for (i = 0; i < self._el.length; i++) {
|
||||
ele = self._el[i];
|
||||
|
||||
for (j = 0; j < this._beforeAddCls.length; j++) {
|
||||
ele.classList.remove(this._beforeAddCls[j]);
|
||||
for (j = 0; j < self._bfAdd.length; j++) {
|
||||
ele.classList.remove(self._bfAdd[j]);
|
||||
}
|
||||
|
||||
for (j = 0; j < this._beforeRmvCls.length; j++) {
|
||||
ele.classList.add(this._beforeRmvCls[j]);
|
||||
for (j = 0; j < self._bfRmv.length; j++) {
|
||||
ele.classList.add(self._bfRmv[j]);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// normal direction
|
||||
for (i = 0; i < this._el.length; i++) {
|
||||
ele = this._el[i];
|
||||
for (i = 0; i < self._el.length; i++) {
|
||||
ele = self._el[i];
|
||||
|
||||
for (j = 0; j < this._afterAddCls.length; j++) {
|
||||
ele.classList.add(this._afterAddCls[j]);
|
||||
for (j = 0; j < self._afAdd.length; j++) {
|
||||
ele.classList.add(self._afAdd[j]);
|
||||
}
|
||||
|
||||
for (j = 0; j < this._afterRmvCls.length; j++) {
|
||||
ele.classList.remove(this._afterRmvCls[j]);
|
||||
for (j = 0; j < self._afRmv.length; j++) {
|
||||
ele.classList.remove(self._afRmv[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.onFinish && this.onFinish();
|
||||
self.onFinish && self.onFinish();
|
||||
}
|
||||
}
|
||||
|
||||
pause() {
|
||||
this._hasFinished = false;
|
||||
|
||||
let i;
|
||||
for (i = 0; i < this._children.length; i++) {
|
||||
this._children[i].pause();
|
||||
}
|
||||
|
||||
for (i = 0; i < this._animations.length; i++) {
|
||||
this._animations[i].pause();
|
||||
}
|
||||
}
|
||||
|
||||
progress(value) {
|
||||
let i;
|
||||
|
||||
for (i = 0; i < this._children.length; i++) {
|
||||
this._children[i].progress(value);
|
||||
}
|
||||
|
||||
if (!this._initProgress) {
|
||||
this._initProgress = true;
|
||||
this.play();
|
||||
this.pause();
|
||||
}
|
||||
|
||||
for (i = 0; i < this._animations.length; i++) {
|
||||
this._animations[i].progress(value);
|
||||
}
|
||||
}
|
||||
|
||||
dispose() {
|
||||
var i;
|
||||
let i;
|
||||
|
||||
for (i = 0; i < this._children.length; i++) {
|
||||
this._children[i].dispose();
|
||||
}
|
||||
for (i = 0; i < this._players.length; i++) {
|
||||
this._players[i].dispose();
|
||||
for (i = 0; i < this._animations.length; i++) {
|
||||
this._animations[i].dispose();
|
||||
}
|
||||
this._el = this._parent = this._children = this._players = null;
|
||||
this._el = this._parent = this._children = this._animations = null;
|
||||
}
|
||||
|
||||
/*
|
||||
STATIC CLASSES
|
||||
*/
|
||||
static create(element, name) {
|
||||
let AnimationClass = registry[name];
|
||||
let AnimationClass = AnimationRegistry[name];
|
||||
|
||||
if (!AnimationClass) {
|
||||
// couldn't find an animation by the given name
|
||||
// fallback to just the base Animation class
|
||||
AnimationClass = Animation;
|
||||
}
|
||||
return new AnimationClass(element);
|
||||
}
|
||||
|
||||
static register(name, AnimationClass) {
|
||||
registry[name] = AnimationClass;
|
||||
AnimationRegistry[name] = AnimationClass;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -300,52 +363,67 @@ export class Animation {
|
||||
class Animate {
|
||||
|
||||
constructor(ele, fromEffect, toEffect, duration, easingConfig, playbackRate) {
|
||||
|
||||
if (!toEffect) {
|
||||
// not an actual animation that tweens between from and to properties
|
||||
// probably just adding/removing CSS classes, so resolve it right away
|
||||
return;
|
||||
}
|
||||
|
||||
// https://w3c.github.io/web-animations/
|
||||
// not using the direct API methods because they're still in flux
|
||||
// however, element.animate() seems locked in and uses the latest
|
||||
// and correct API methods under the hood, so really doesn't matter
|
||||
const self = this;
|
||||
|
||||
fromEffect = parseEffect(fromEffect);
|
||||
toEffect = parseEffect(toEffect);
|
||||
self.toEffect = parseEffect(toEffect);
|
||||
|
||||
this._duration = duration;
|
||||
self.shouldAnimate = (duration > 36);
|
||||
|
||||
var easingName = easingConfig && easingConfig.name || 'linear';
|
||||
|
||||
var effects = [ convertProperties(fromEffect) ];
|
||||
|
||||
if (easingName in EASING_FN) {
|
||||
insertEffects(effects, fromEffect, toEffect, easingConfig);
|
||||
|
||||
} else if (easingName in CUBIC_BEZIERS) {
|
||||
easingName = 'cubic-bezier(' + CUBIC_BEZIERS[easingName] + ')';
|
||||
if (!self.shouldAnimate) {
|
||||
return inlineStyle(ele, self.toEffect);
|
||||
}
|
||||
|
||||
effects.push( convertProperties(toEffect) );
|
||||
self.ele = ele;
|
||||
self.resolve;
|
||||
self.promise = new Promise(res => { self.resolve = res; });
|
||||
|
||||
this.player = ele.animate(effects, {
|
||||
duration: duration || 0,
|
||||
easing: easingName,
|
||||
playbackRate: playbackRate || 1
|
||||
});
|
||||
// stage where the element will start from
|
||||
fromEffect = parseEffect(fromEffect);
|
||||
inlineStyle(ele, fromEffect);
|
||||
|
||||
this.promise = new Promise(resolve => {
|
||||
this.player.onfinish = () => {
|
||||
resolve();
|
||||
};
|
||||
});
|
||||
self.duration = duration;
|
||||
self.rate = playbackRate;
|
||||
|
||||
self.easing = easingConfig && easingConfig.name || 'linear';
|
||||
|
||||
self.effects = [ convertProperties(fromEffect) ];
|
||||
|
||||
if (self.easing in EASING_FN) {
|
||||
insertEffects(self.effects, fromEffect, self.toEffect, easingConfig);
|
||||
|
||||
} else if (self.easing in CUBIC_BEZIERS) {
|
||||
self.easing = 'cubic-bezier(' + CUBIC_BEZIERS[self.easing] + ')';
|
||||
}
|
||||
|
||||
self.effects.push( convertProperties(self.toEffect) );
|
||||
}
|
||||
|
||||
play() {
|
||||
this.player && this.player.play();
|
||||
const self = this;
|
||||
|
||||
if (self.player) {
|
||||
self.player.play();
|
||||
|
||||
} else {
|
||||
self.player = self.ele.animate(self.effects, {
|
||||
duration: self.duration || 0,
|
||||
easing: self.easing,
|
||||
playbackRate: self.rate || 1
|
||||
});
|
||||
|
||||
self.player.onfinish = () => {
|
||||
// lock in where the element will stop at
|
||||
inlineStyle(self.ele, self.rate < 0 ? self.fromEffect : self.toEffect);
|
||||
|
||||
self.resolve();
|
||||
};
|
||||
}
|
||||
|
||||
return self.promise;
|
||||
}
|
||||
|
||||
pause() {
|
||||
@@ -355,53 +433,55 @@ class Animate {
|
||||
progress(value) {
|
||||
let player = this.player;
|
||||
|
||||
if (!player) return;
|
||||
if (player) {
|
||||
// passed a number between 0 and 1
|
||||
value = Math.max(0, Math.min(1, value));
|
||||
|
||||
// passed a number between 0 and 1
|
||||
value = Math.max(0, Math.min(1, value));
|
||||
if (value >= 1) {
|
||||
player.currentTime = (this.duration * 0.999);
|
||||
return player.play();
|
||||
}
|
||||
|
||||
if (value === 1) {
|
||||
player.currentTime = (this._duration * 0.9999);
|
||||
player.play();
|
||||
return;
|
||||
if (player.playState !== 'paused') {
|
||||
player.pause();
|
||||
}
|
||||
|
||||
player.currentTime = (this.duration * value);
|
||||
}
|
||||
|
||||
if (player.playState !== 'paused') {
|
||||
player.pause();
|
||||
}
|
||||
|
||||
player.currentTime = (this._duration * value);
|
||||
}
|
||||
|
||||
playbackRate(value) {
|
||||
this.rate = value;
|
||||
if (this.player) {
|
||||
this.player.playbackRate = value;
|
||||
}
|
||||
}
|
||||
|
||||
dispose() {
|
||||
this.player = null;
|
||||
this.ele = this.player = this.effects = this.toEffect = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function insertEffects(effects, fromEffect, toEffect, easingConfig) {
|
||||
easingConfig.opts = easingConfig.opts || {};
|
||||
var increment = easingConfig.opts.increment || 0.04;
|
||||
|
||||
var easingFn = EASING_FN[easingConfig.name];
|
||||
const increment = easingConfig.opts.increment || 0.04;
|
||||
const easingFn = EASING_FN[easingConfig.name];
|
||||
|
||||
for(var pos = increment; pos <= (1 - increment); pos += increment) {
|
||||
let pos, tweenEffect, addEffect, property, toProperty, fromValue, diffValue;
|
||||
|
||||
var tweenEffect = {};
|
||||
var addEffect = false;
|
||||
for(pos = increment; pos <= (1 - increment); pos += increment) {
|
||||
tweenEffect = {};
|
||||
addEffect = false;
|
||||
|
||||
for (property in toEffect) {
|
||||
toProperty = toEffect[property];
|
||||
|
||||
for (var property in toEffect) {
|
||||
var toProperty = toEffect[property];
|
||||
if (toProperty.tween) {
|
||||
|
||||
var fromValue = fromEffect[property].num
|
||||
var diffValue = toProperty.num - fromValue;
|
||||
fromValue = fromEffect[property].num
|
||||
diffValue = toProperty.num - fromValue;
|
||||
|
||||
tweenEffect[property] = {
|
||||
value: roundValue( (easingFn(pos, easingConfig.opts) * diffValue) + fromValue ) + toProperty.unit
|
||||
@@ -419,8 +499,8 @@ function insertEffects(effects, fromEffect, toEffect, easingConfig) {
|
||||
}
|
||||
|
||||
function parseEffect(inputEffect) {
|
||||
var val, r, num, property;
|
||||
var outputEffect = {};
|
||||
let val, r, num, property;
|
||||
let outputEffect = {};
|
||||
|
||||
for (property in inputEffect) {
|
||||
val = inputEffect[property];
|
||||
@@ -439,11 +519,12 @@ function parseEffect(inputEffect) {
|
||||
}
|
||||
|
||||
function convertProperties(inputEffect) {
|
||||
var outputEffect = {};
|
||||
var transforms = [];
|
||||
let outputEffect = {};
|
||||
let transforms = [];
|
||||
let value, property;
|
||||
|
||||
for (var property in inputEffect) {
|
||||
var value = inputEffect[property].value;
|
||||
for (property in inputEffect) {
|
||||
value = inputEffect[property].value;
|
||||
|
||||
if (TRANSFORMS.indexOf(property) > -1) {
|
||||
transforms.push(property + '(' + value + ')');
|
||||
@@ -454,12 +535,36 @@ function convertProperties(inputEffect) {
|
||||
}
|
||||
|
||||
if (transforms.length) {
|
||||
transforms.push('translateZ(0px)');
|
||||
outputEffect.transform = transforms.join(' ');
|
||||
}
|
||||
|
||||
return outputEffect;
|
||||
}
|
||||
|
||||
function inlineStyle(ele, effect) {
|
||||
if (ele && effect) {
|
||||
let transforms = [];
|
||||
let value, property;
|
||||
|
||||
for (property in effect) {
|
||||
value = effect[property].value;
|
||||
|
||||
if (TRANSFORMS.indexOf(property) > -1) {
|
||||
transforms.push(property + '(' + value + ')');
|
||||
|
||||
} else {
|
||||
ele.style[property] = value;
|
||||
}
|
||||
}
|
||||
|
||||
if (transforms.length) {
|
||||
transforms.push('translateZ(0px)');
|
||||
ele.style[CSS.transform] = transforms.join(' ');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function roundValue(val) {
|
||||
return Math.round(val * 10000) / 10000;
|
||||
}
|
||||
@@ -519,7 +624,7 @@ const CUBIC_BEZIERS = {
|
||||
|
||||
// Back
|
||||
'ease-in-back': '0.6,-0.28,0.735,0.045',
|
||||
'ease-out-back': '0.175, 0.885,0.32,1.275',
|
||||
'ease-out-back': '0.175,0.885,0.32,1.275',
|
||||
'ease-in-out-back': '0.68,-0.55,0.265,1.55',
|
||||
};
|
||||
|
||||
@@ -531,18 +636,18 @@ const EASING_FN = {
|
||||
},
|
||||
|
||||
'swing-from-to': function(pos, opts) {
|
||||
var s = opts.s || 1.70158;
|
||||
let s = opts.s || 1.70158;
|
||||
return ((pos /= 0.5) < 1) ? 0.5 * (pos * pos * (((s *= (1.525)) + 1) * pos - s)) :
|
||||
0.5 * ((pos -= 2) * pos * (((s *= (1.525)) + 1) * pos + s) + 2);
|
||||
},
|
||||
|
||||
'swing-from': function(pos, opts) {
|
||||
var s = opts.s || 1.70158;
|
||||
let s = opts.s || 1.70158;
|
||||
return pos * pos * ((s + 1) * pos - s);
|
||||
},
|
||||
|
||||
'swing-to': function(pos, opts) {
|
||||
var s = opts.s || 1.70158;
|
||||
let s = opts.s || 1.70158;
|
||||
return (pos -= 1) * pos * ((s + 1) * pos + s) + 1;
|
||||
},
|
||||
|
||||
@@ -597,8 +702,8 @@ const EASING_FN = {
|
||||
* https://raw.github.com/madrobby/scripty2/master/src/effects/transitions/transitions.js
|
||||
*/
|
||||
'spring': function(pos, opts) {
|
||||
var damping = opts.damping || 4.5;
|
||||
var elasticity = opts.elasticity || 6;
|
||||
let damping = opts.damping || 4.5;
|
||||
let elasticity = opts.elasticity || 6;
|
||||
return 1 - (Math.cos(pos * damping * Math.PI) * Math.exp(-pos * elasticity));
|
||||
},
|
||||
|
||||
|
||||
@@ -8,22 +8,43 @@ class SlideIn extends Animation {
|
||||
this
|
||||
.easing('cubic-bezier(0.1,0.7,0.1,1)')
|
||||
.duration(400)
|
||||
.from('translateY', '100%')
|
||||
.to('translateY', '0%');
|
||||
.fromTo('translateY', '100%', '0%');
|
||||
}
|
||||
}
|
||||
|
||||
Animation.register('slide-in', SlideIn);
|
||||
|
||||
|
||||
class SlideOut extends Animation {
|
||||
constructor(element) {
|
||||
super(element);
|
||||
this
|
||||
.easing('ease-out')
|
||||
.duration(250)
|
||||
.from('translateY', '0%')
|
||||
.to('translateY', '100%');
|
||||
.fromTo('translateY', '0%', '100%');
|
||||
}
|
||||
}
|
||||
|
||||
Animation.register('slide-out', SlideOut);
|
||||
|
||||
|
||||
class FadeIn extends Animation {
|
||||
constructor(element) {
|
||||
super(element);
|
||||
this
|
||||
.easing('ease-in')
|
||||
.duration(400)
|
||||
.fadeIn();
|
||||
}
|
||||
}
|
||||
Animation.register('fade-in', FadeIn);
|
||||
|
||||
|
||||
class FadeOut extends Animation {
|
||||
constructor(element) {
|
||||
super(element);
|
||||
this
|
||||
.easing('ease-out')
|
||||
.duration(250)
|
||||
.fadeOut();
|
||||
}
|
||||
}
|
||||
Animation.register('fade-out', FadeOut);
|
||||
|
||||
@@ -59,12 +59,11 @@ ion-pane {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
display:none;
|
||||
&.show-pane {
|
||||
display: flex;
|
||||
}
|
||||
transform: translateZ(0px);
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
@@ -92,6 +91,8 @@ ion-navbar {
|
||||
min-height: 4.4rem;
|
||||
order: $flex-order-toolbar-top;
|
||||
|
||||
transform: translateZ(0px);
|
||||
|
||||
display: none;
|
||||
&.show-navbar {
|
||||
display: flex;
|
||||
@@ -127,11 +128,11 @@ ion-content {
|
||||
// Hardware Acceleration
|
||||
.transitioning {
|
||||
|
||||
ion-view,
|
||||
.ion-view,
|
||||
.nav-item,
|
||||
ion-navbar,
|
||||
.back-button,
|
||||
ion-title {
|
||||
.navbar-title,
|
||||
.navbar-item {
|
||||
will-change: transform, opacity;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ class IonicApp {
|
||||
.from('translateX', '0px')
|
||||
.to('translateX', '250px')
|
||||
|
||||
this.animation.addChild(ball);
|
||||
this.animation.add(ball);
|
||||
|
||||
|
||||
var row1 = new Animation( document.querySelectorAll('.square') );
|
||||
@@ -36,7 +36,7 @@ class IonicApp {
|
||||
.from('opacity', 0.8)
|
||||
.to('opacity', 0.2)
|
||||
|
||||
this.animation.addChild(row1);
|
||||
this.animation.add(row1);
|
||||
|
||||
var row2 = new Animation( document.querySelectorAll('.square2') );
|
||||
row2
|
||||
@@ -44,10 +44,10 @@ class IonicApp {
|
||||
.from('scale', '1')
|
||||
.to('rotate', '90deg')
|
||||
.to('scale', '0.5')
|
||||
.beforePlay.addClass('added-before-play')
|
||||
.afterFinish.addClass('added-after-finish')
|
||||
.before.addClass('added-before-play')
|
||||
.after.addClass('added-after-finish')
|
||||
|
||||
this.animation.children(row1, row2);
|
||||
this.animation.add(row1, row2);
|
||||
|
||||
this.animation.onReady = () => {
|
||||
console.log('onReady');
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Animation Tests</title>
|
||||
<script src="./web-animations-js/web-animations-next.dev.js"></script>
|
||||
<style>
|
||||
.ball-container {
|
||||
position: absolute;
|
||||
|
||||
@@ -97,8 +97,8 @@ $content-padding: 10px !default;
|
||||
// --------------------------------------------------
|
||||
|
||||
$swipe-handle-width: 20px !default;
|
||||
$swipe-handle-top: 80px !default;
|
||||
$swipe-handle-bottom: 80px !default;
|
||||
$swipe-handle-top: 70px !default;
|
||||
$swipe-handle-bottom: 70px !default;
|
||||
|
||||
.swipe-handle {
|
||||
position: absolute;
|
||||
@@ -108,22 +108,11 @@ $swipe-handle-bottom: 80px !default;
|
||||
width: $swipe-handle-width;
|
||||
z-index: $z-index-swipe-handle;
|
||||
|
||||
background: red;
|
||||
opacity: 0.2;
|
||||
//background: red;
|
||||
//opacity: 0.2;
|
||||
|
||||
transform: translate3d(-999px, 0px, 0px);
|
||||
&.show-handle {
|
||||
transform: translate3d(0px, 0px, 0px);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Node Inserted Animation
|
||||
// --------------------------------------------------
|
||||
// Used by the toolbar to know when the title has been rendered
|
||||
// http://davidwalsh.name/detect-node-insertion
|
||||
|
||||
@keyframes nodeInserted {
|
||||
from { transform: scale(0.999); }
|
||||
to { transform: scale(1); }
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ $content-container-ios-background-color: #000 !default;
|
||||
$content-ios-background-color: #efeff4 !default;
|
||||
|
||||
|
||||
.nav-ios {
|
||||
.nav-ios.show-pane {
|
||||
|
||||
.content-container {
|
||||
background-color: $content-container-ios-background-color;
|
||||
|
||||
@@ -115,14 +115,16 @@ class ModalContainer {
|
||||
|
||||
open(animation) {
|
||||
console.log('Opening w/ anim', animation);
|
||||
var slideIn = Animation.create(this.domElement, animation);
|
||||
return slideIn.play();
|
||||
var enterAnimation = Animation.create(this.domElement, animation);
|
||||
enterAnimation.before.addClass('show-modal');
|
||||
return enterAnimation.play();
|
||||
}
|
||||
|
||||
close(animation) {
|
||||
console.log('Closing w/ anim', animation);
|
||||
var slideOut = Animation.create(this.domElement, animation);
|
||||
return slideOut.play();
|
||||
var leavingAnimation = Animation.create(this.domElement, animation);
|
||||
leavingAnimation.after.removeClass('show-modal');
|
||||
return leavingAnimation.play();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,6 @@ $tabs-height: 40;
|
||||
}
|
||||
|
||||
ion-modal {
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
z-index: $z-index-modal;
|
||||
@@ -45,23 +44,14 @@ ion-modal {
|
||||
width: 100%;
|
||||
background-color: $modal-bg-color;
|
||||
|
||||
//transform: translate3d(0, 100%, 0);
|
||||
//transition: all cubic-bezier(.1, .7, .1, 1) 400ms;
|
||||
transform: translateZ(0px);
|
||||
|
||||
display: none;
|
||||
&.show-modal {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
// Slide up from the bottom, used for modals
|
||||
// -------------------------------
|
||||
|
||||
ion-modal.active {
|
||||
//transform: translate3d(0, 0, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
ion-modal.slide-in-up.ng-leave,
|
||||
ion-modal.slide-in-up > .ng-leave {
|
||||
transition: all ease-in-out 250ms;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
@media (min-width: $modal-inset-mode-break-point) {
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
import {Component} from 'angular2/src/core/annotations_impl/annotations';
|
||||
import {View} from 'angular2/src/core/annotations_impl/view';
|
||||
import {ElementRef} from 'angular2/src/core/compiler/element_ref';
|
||||
|
||||
import {IonicComponent} from 'ionic/config/component';
|
||||
import {ViewItem} from '../view/view-item';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'back-button',
|
||||
hostProperties: {
|
||||
'!item.enableBack': 'hidden'
|
||||
},
|
||||
hostListeners: {
|
||||
'^click': 'goBack($event)'
|
||||
},
|
||||
})
|
||||
@View({
|
||||
template: `
|
||||
<icon class="back-button-icon ion-ios-arrow-back"></icon>
|
||||
<span class="back-button-text">
|
||||
<span class="back-default">Back</span>
|
||||
<span class="back-title"></span>
|
||||
</span>`
|
||||
})
|
||||
export class BackButton {
|
||||
constructor(item: ViewItem, @ElementRef() element: ElementRef) {
|
||||
this.item = item;
|
||||
this.domElement = element.domElement;
|
||||
|
||||
setTimeout(() => {
|
||||
// HACK!
|
||||
this.config = BackButton.config.invoke(this);
|
||||
});
|
||||
}
|
||||
|
||||
goBack(ev) {
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
|
||||
let item = this.item;
|
||||
item && item.viewCtrl && item.viewCtrl.pop();
|
||||
}
|
||||
}
|
||||
|
||||
new IonicComponent(BackButton, {
|
||||
properties: {
|
||||
icon: {
|
||||
defaults: {
|
||||
ios: 'ion-ios-arrow-back',
|
||||
android: 'ion-android-arrow-back',
|
||||
core: 'ion-chevron-left'
|
||||
}
|
||||
},
|
||||
text: {
|
||||
defaults: {
|
||||
ios: 'Back',
|
||||
android: '',
|
||||
core: ''
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -47,12 +47,12 @@ $navbar-ios-button-background-color: transparent !default;
|
||||
|
||||
ion-title {
|
||||
order: map-get($navbar-order-ios, 'title');
|
||||
text-align: center;
|
||||
font-size: $navbar-ios-title-font-size;
|
||||
font-weight: 500;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.navbar-back-button {
|
||||
.back-button {
|
||||
order: map-get($navbar-order-ios, 'back-button');
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import {Component, Directive, onInit} from 'angular2/src/core/annotations_impl/annotations';
|
||||
import {Component, Directive} from 'angular2/src/core/annotations_impl/annotations';
|
||||
import {View} from 'angular2/src/core/annotations_impl/view';
|
||||
import {ElementRef} from 'angular2/src/core/compiler/element_ref';
|
||||
import {ProtoViewRef} from 'angular2/src/core/compiler/view_ref';
|
||||
import {NgZone} from 'angular2/src/core/zone/ng_zone';
|
||||
|
||||
import {ViewItem} from '../view/view-item';
|
||||
import {BackButton} from './back-button';
|
||||
import * as dom from '../../util/dom';
|
||||
|
||||
|
||||
@@ -15,9 +14,15 @@ import * as dom from '../../util/dom';
|
||||
@View({
|
||||
template: `
|
||||
<div class="navbar-inner">
|
||||
<back-button class="button navbar-item"></back-button>
|
||||
<button class="back-button button">
|
||||
<icon class="back-button-icon ion-ios-arrow-back"></icon>
|
||||
<span class="back-button-text">
|
||||
<span class="back-default">Back</span>
|
||||
<span class="back-title"></span>
|
||||
</span>
|
||||
</button>
|
||||
<div class="navbar-title">
|
||||
<div class="navbar-inner-title navbar-title-hide">
|
||||
<div class="navbar-inner-title">
|
||||
<content select="ion-title"></content>
|
||||
</div>
|
||||
</div>
|
||||
@@ -29,70 +34,50 @@ import * as dom from '../../util/dom';
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
directives: [BackButton],
|
||||
lifecycle: [onInit]
|
||||
directives: [BackButton, Title, NavbarItem]
|
||||
})
|
||||
export class Navbar {
|
||||
constructor(item: ViewItem, elementRef: ElementRef, ngZone: NgZone) {
|
||||
constructor(item: ViewItem, elementRef: ElementRef) {
|
||||
item.navbarElement(elementRef.domElement);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Directive({
|
||||
selector: '.back-button',
|
||||
hostListeners: {
|
||||
'^click': 'goBack($event)'
|
||||
}
|
||||
})
|
||||
class BackButton {
|
||||
constructor(item: ViewItem, elementRef: ElementRef) {
|
||||
this.item = item;
|
||||
this.domElement = elementRef.domElement;
|
||||
this.zone = ngZone;
|
||||
item.backButtonElement(elementRef.domElement);
|
||||
}
|
||||
|
||||
onInit() {
|
||||
this.zone.runOutsideAngular(() => {
|
||||
setTimeout(() => {
|
||||
this.alignTitle();
|
||||
}, 32);
|
||||
});
|
||||
goBack(ev) {
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
this.item.viewCtrl.pop();
|
||||
}
|
||||
}
|
||||
|
||||
alignTitle() {
|
||||
const navbarEle = this.domElement;
|
||||
const innerTitleEle = this._innerTitleEle || (this._innerTitleEle = navbarEle.querySelector('.navbar-inner-title'));
|
||||
const titleEle = this._titleEle || (this._titleEle = innerTitleEle.querySelector('ion-title'));
|
||||
const style = this._style || (this._style = window.getComputedStyle(titleEle));
|
||||
|
||||
const titleOffsetWidth = titleEle.offsetWidth;
|
||||
const titleOffsetLeft = titleEle.offsetLeft;
|
||||
const titleScrollWidth = titleEle.scrollWidth;
|
||||
const navbarOffsetWidth = navbarEle.offsetWidth;
|
||||
|
||||
// TODO!!! When an element is being reused by angular2, it'll sometimes keep the
|
||||
// styles from the original element's use, causing these calculations to be wrong
|
||||
if (window.getComputedStyle(innerTitleEle).margin !== '0px') {
|
||||
this._showTitle();
|
||||
return;
|
||||
}
|
||||
|
||||
// only align if the title is center and if it isn't already overflowing
|
||||
if (style.textAlign !== 'center' || titleOffsetWidth < titleScrollWidth) {
|
||||
this._showTitle();
|
||||
|
||||
} else {
|
||||
let rightMargin = navbarOffsetWidth - (titleOffsetLeft + titleOffsetWidth);
|
||||
let centerMargin = titleOffsetLeft - rightMargin;
|
||||
|
||||
innerTitleEle.style.margin = `0 ${centerMargin}px 0 0`;
|
||||
|
||||
dom.raf(() => {
|
||||
if (titleEle.offsetWidth < titleEle.scrollWidth) {
|
||||
// not enough room yet, just left align title
|
||||
innerTitleEle.style.margin = '';
|
||||
innerTitleEle.style.textAlign = 'left';
|
||||
}
|
||||
this._showTitle();
|
||||
})
|
||||
}
|
||||
@Directive({
|
||||
selector: '.navbar-title'
|
||||
})
|
||||
export class Title {
|
||||
constructor(item: ViewItem, elementRef: ElementRef) {
|
||||
item.titleElement(elementRef.domElement);
|
||||
}
|
||||
}
|
||||
|
||||
_showTitle() {
|
||||
if (!this._shown) {
|
||||
this._shown = true;
|
||||
this._innerTitleEle.classList.remove('navbar-title-hide');
|
||||
}
|
||||
@Directive({
|
||||
selector: '.navbar-item'
|
||||
})
|
||||
export class NavbarItem {
|
||||
constructor(item: ViewItem, elementRef: ElementRef) {
|
||||
item.navbarItemElements(elementRef.domElement);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -21,8 +21,14 @@ ion-navbar {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
ion-navbar back-button.navbar-item {
|
||||
.back-button {
|
||||
order: map-get($navbar-order, 'back-button');
|
||||
transform: translateZ(0px);
|
||||
|
||||
display: none;
|
||||
&.show-back-button {
|
||||
display: inline-flex;
|
||||
}
|
||||
}
|
||||
|
||||
.navbar-title {
|
||||
@@ -31,7 +37,29 @@ ion-navbar back-button.navbar-item {
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 0 0 2px;
|
||||
|
||||
transform: translateZ(0px);
|
||||
}
|
||||
|
||||
.navbar-inner-title {
|
||||
width: 100%;
|
||||
padding: 0 15px;
|
||||
}
|
||||
|
||||
ion-title {
|
||||
display: block;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.navbar-item {
|
||||
transform: translateZ(0px);
|
||||
|
||||
display: none;
|
||||
&.show-navbar-item {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.navbar-primary-item {
|
||||
@@ -42,27 +70,7 @@ ion-navbar back-button.navbar-item {
|
||||
order: map-get($navbar-order, 'secondary');
|
||||
}
|
||||
|
||||
ion-title {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
|
||||
// used to notify JS when the title has been rendered
|
||||
animation-duration: 1ms;
|
||||
animation-name: nodeInserted;
|
||||
}
|
||||
|
||||
.navbar-inner-title {
|
||||
width: 100%;
|
||||
padding: 0 15px;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.navbar .button {
|
||||
background: transparent;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.navbar-title-hide {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
@@ -20,71 +20,76 @@ export class SwipeHandle {
|
||||
@Parent() pane: Pane,
|
||||
elementRef: ElementRef
|
||||
) {
|
||||
if (!viewCtrl) return;
|
||||
if (!viewCtrl || !pane) return;
|
||||
|
||||
this.viewCtrl = viewCtrl;
|
||||
const self = this;
|
||||
|
||||
let gesture = new Gesture(elementRef.domElement);
|
||||
self.pane = pane;
|
||||
self.viewCtrl = viewCtrl;
|
||||
|
||||
let gesture = self.gesture = new Gesture(elementRef.domElement);
|
||||
gesture.listen();
|
||||
|
||||
gesture.on('panend', onDragEnd);
|
||||
gesture.on('panleft', onDragHorizontal);
|
||||
gesture.on('panright', onDragHorizontal);
|
||||
function dragHorizontal(ev) {
|
||||
self.onDragHorizontal(ev);
|
||||
}
|
||||
|
||||
let startX = null;
|
||||
let swipeableAreaWidth = null;
|
||||
gesture.on('panend', ev => { self.onDragEnd(ev); });
|
||||
gesture.on('panleft', dragHorizontal);
|
||||
gesture.on('panright', dragHorizontal);
|
||||
|
||||
function onDragEnd(ev) {
|
||||
self.startX = null;
|
||||
self.width = null;
|
||||
}
|
||||
|
||||
onDragEnd(ev) {
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
|
||||
// TODO: POLISH THESE NUMBERS WITH GOOD MATHIFICATION
|
||||
let progress = (ev.gesture.center.x - this.startX) / this.width;
|
||||
let completeSwipeBack = (progress > 0.5);
|
||||
let playbackRate = 4;
|
||||
|
||||
if (completeSwipeBack) {
|
||||
// complete swipe back
|
||||
if (progress > 0.9) {
|
||||
playbackRate = 1;
|
||||
} else if (progress > 0.8) {
|
||||
playbackRate = 2;
|
||||
} else if (progress > 0.7) {
|
||||
playbackRate = 3;
|
||||
}
|
||||
|
||||
} else {
|
||||
// cancel swipe back
|
||||
if (progress < 0.1) {
|
||||
playbackRate = 1;
|
||||
} else if (progress < 0.2) {
|
||||
playbackRate = 2;
|
||||
} else if (progress < 0.3) {
|
||||
playbackRate = 3;
|
||||
}
|
||||
}
|
||||
|
||||
this.viewCtrl.swipeBackEnd(completeSwipeBack, progress, playbackRate);
|
||||
|
||||
this.startX = null;
|
||||
}
|
||||
|
||||
onDragHorizontal(ev) {
|
||||
if (this.startX === null) {
|
||||
// starting drag
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
|
||||
// TODO: POLISH THESE NUMBERS WITH GOOD MATHIFICATION
|
||||
this.startX = ev.gesture.center.x;
|
||||
this.width = this.pane.width() - this.startX;
|
||||
|
||||
let progress = (ev.gesture.center.x - startX) / swipeableAreaWidth;
|
||||
let completeSwipeBack = (progress > 0.5);
|
||||
let playbackRate = 4;
|
||||
|
||||
if (completeSwipeBack) {
|
||||
// complete swipe back
|
||||
if (progress > 0.9) {
|
||||
playbackRate = 1;
|
||||
} else if (progress > 0.8) {
|
||||
playbackRate = 2;
|
||||
} else if (progress > 0.7) {
|
||||
playbackRate = 3;
|
||||
}
|
||||
|
||||
} else {
|
||||
// cancel swipe back
|
||||
if (progress < 0.1) {
|
||||
playbackRate = 1;
|
||||
} else if (progress < 0.2) {
|
||||
playbackRate = 2;
|
||||
} else if (progress < 0.3) {
|
||||
playbackRate = 3;
|
||||
}
|
||||
}
|
||||
|
||||
viewCtrl.swipeBackEnd(completeSwipeBack, progress, playbackRate);
|
||||
|
||||
startX = null;
|
||||
}
|
||||
|
||||
function onDragHorizontal(ev) {
|
||||
if (startX === null) {
|
||||
// starting drag
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
|
||||
startX = ev.gesture.center.x;
|
||||
swipeableAreaWidth = pane.width() - startX;
|
||||
|
||||
viewCtrl.swipeBackStart();
|
||||
}
|
||||
|
||||
viewCtrl.swipeBackProgress( (ev.gesture.center.x - startX) / swipeableAreaWidth );
|
||||
this.viewCtrl.swipeBackStart();
|
||||
}
|
||||
|
||||
this.viewCtrl.swipeBackProgress( (ev.gesture.center.x - this.startX) / this.width );
|
||||
}
|
||||
|
||||
showHandle() {
|
||||
|
||||
@@ -19,6 +19,9 @@ import {ThirdPage} from './third-page';
|
||||
<p>
|
||||
<button class="button" (click)="push()">Push (Go to 3rd)</button>
|
||||
</p>
|
||||
<p>
|
||||
Random: {{ val }}
|
||||
</p>
|
||||
<div class="green"><f></f><f></f><f></f><f></f><f></f><f></f><f></f><f></f><f></f><f></f><f></f><f></f><f></f><f></f><f></f><f></f><f></f><f></f><f></f><f></f></div>
|
||||
</ion-content>
|
||||
`,
|
||||
@@ -31,6 +34,7 @@ export class SecondPage {
|
||||
) {
|
||||
this.nav = nav;
|
||||
this.params = params;
|
||||
this.val = Math.round(Math.random() * 8999) + 1000;
|
||||
|
||||
console.log('Second page params:', params);
|
||||
}
|
||||
|
||||
@@ -38,13 +38,9 @@ ion-toolbar {
|
||||
order: map-get($toolbar-order, 'secondary');
|
||||
}
|
||||
|
||||
ion-title {
|
||||
ion-toolbar ion-title {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
|
||||
// used to notify JS when the title has been rendered
|
||||
animation-duration: 1ms;
|
||||
animation-name: nodeInserted;
|
||||
}
|
||||
|
||||
.toolbar-inner-title {
|
||||
|
||||
@@ -132,42 +132,35 @@ export class ViewController {
|
||||
enteringItem.willEnter();
|
||||
leavingItem.willLeave();
|
||||
|
||||
// set that the leaving item is stage to be leaving
|
||||
leavingItem.state = STAGED_LEAVING_STATE;
|
||||
|
||||
// set that the new item pushed on the stack is staged to be entering
|
||||
// setting staged state is important for the transition logic to find the correct item
|
||||
// set that the new item pushed on the stack is staged to be entering/leaving
|
||||
// staged state is important for the transition to find the correct item
|
||||
enteringItem.state = STAGED_ENTERING_STATE;
|
||||
leavingItem.state = STAGED_LEAVING_STATE;
|
||||
|
||||
// init the transition animation
|
||||
let transAnimation = Transition.create(this, opts);
|
||||
if (!opts.animate) {
|
||||
// force it to not animate the elements, just apply the "to" styles
|
||||
transAnimation.duration(0);
|
||||
}
|
||||
|
||||
// wait for the items to be fully staged
|
||||
transAnimation.stage(() => {
|
||||
// start the transition
|
||||
transAnimation.play().then(() => {
|
||||
|
||||
// update the state that the items are actively entering/leaving
|
||||
enteringItem.state = ACTIVELY_ENTERING_STATE;
|
||||
leavingItem.state = ACTIVELY_LEAVING_STATE;
|
||||
// transition has completed, update each item's state
|
||||
enteringItem.state = ACTIVE_STATE;
|
||||
leavingItem.state = CACHED_STATE;
|
||||
|
||||
// start the transition
|
||||
transAnimation.play().then(() => {
|
||||
// dispose any items that shouldn't stay around
|
||||
transAnimation.dispose();
|
||||
|
||||
// transition has completed, update each item's state
|
||||
enteringItem.state = ACTIVE_STATE;
|
||||
leavingItem.state = CACHED_STATE;
|
||||
enteringItem.didEnter();
|
||||
leavingItem.didLeave();
|
||||
|
||||
// dispose any items that shouldn't stay around
|
||||
transAnimation.dispose();
|
||||
|
||||
enteringItem.didEnter();
|
||||
leavingItem.didLeave();
|
||||
|
||||
// all done!
|
||||
this.transitionComplete();
|
||||
|
||||
callback();
|
||||
});
|
||||
// all done!
|
||||
this.transitionComplete();
|
||||
|
||||
callback();
|
||||
});
|
||||
|
||||
});
|
||||
@@ -206,53 +199,43 @@ export class ViewController {
|
||||
// wait for the new item to complete setup
|
||||
enteringItem.stage(() => {
|
||||
|
||||
// set that the leaving item is stage to be leaving
|
||||
leavingItem.state = STAGED_LEAVING_STATE;
|
||||
|
||||
// set that the new item pushed on the stack is staged to be entering
|
||||
// setting staged state is important for the transition logic to find the correct item
|
||||
// set that the new item pushed on the stack is staged to be entering/leaving
|
||||
// staged state is important for the transition to find the correct item
|
||||
enteringItem.state = STAGED_ENTERING_STATE;
|
||||
leavingItem.state = STAGED_LEAVING_STATE;
|
||||
|
||||
// init the transition animation
|
||||
this.sbTransition = Transition.create(this, opts);
|
||||
this.sbTransition.easing('linear');
|
||||
this.sbTransition.stage();
|
||||
|
||||
// wait for the items to be fully staged
|
||||
this.sbTransition.stage(() => {
|
||||
let swipeBackPromise = new Promise(res => { this.sbResolve = res; });
|
||||
|
||||
// update the state that the items are actively entering/leaving
|
||||
enteringItem.state = ACTIVELY_ENTERING_STATE;
|
||||
leavingItem.state = ACTIVELY_LEAVING_STATE;
|
||||
swipeBackPromise.then((completeSwipeBack) => {
|
||||
console.log('completeSwipeBack', completeSwipeBack)
|
||||
if (completeSwipeBack) {
|
||||
// swipe back has completed, update each item's state
|
||||
enteringItem.state = ACTIVE_STATE;
|
||||
leavingItem.state = CACHED_STATE;
|
||||
|
||||
let swipeBackPromise = new Promise(res => { this.sbResolve = res; });
|
||||
enteringItem.didEnter();
|
||||
leavingItem.didLeave();
|
||||
|
||||
swipeBackPromise.then((completeSwipeBack) => {
|
||||
} else {
|
||||
// cancelled the swipe back, return items to original state
|
||||
leavingItem.state = ACTIVE_STATE;
|
||||
enteringItem.state = CACHED_STATE;
|
||||
|
||||
if (completeSwipeBack) {
|
||||
// swipe back has completed, update each item's state
|
||||
enteringItem.state = ACTIVE_STATE;
|
||||
leavingItem.state = CACHED_STATE;
|
||||
leavingItem.willEnter();
|
||||
leavingItem.didEnter();
|
||||
enteringItem.didLeave();
|
||||
|
||||
enteringItem.didEnter();
|
||||
leavingItem.didLeave();
|
||||
leavingItem.shouldDestroy = false;
|
||||
enteringItem.shouldDestroy = false;
|
||||
}
|
||||
|
||||
} else {
|
||||
// cancelled the swipe back, return items to original state
|
||||
leavingItem.state = ACTIVE_STATE;
|
||||
enteringItem.state = CACHED_STATE;
|
||||
|
||||
leavingItem.willEnter();
|
||||
leavingItem.didEnter();
|
||||
enteringItem.didLeave();
|
||||
|
||||
leavingItem.shouldDestroy = false;
|
||||
enteringItem.shouldDestroy = false;
|
||||
}
|
||||
|
||||
// all done!
|
||||
this.transitionComplete();
|
||||
|
||||
});
|
||||
// all done!
|
||||
this.transitionComplete();
|
||||
|
||||
});
|
||||
|
||||
@@ -260,6 +243,13 @@ export class ViewController {
|
||||
|
||||
}
|
||||
|
||||
swipeBackProgress(progress) {
|
||||
if (this.sbTransition) {
|
||||
ClickBlock(true, 4000);
|
||||
this.sbTransition.progress( Math.min(1, Math.max(0, progress)) );
|
||||
}
|
||||
}
|
||||
|
||||
swipeBackEnd(completeSwipeBack, progress, playbackRate) {
|
||||
// to reverse the animation use a negative playbackRate
|
||||
if (this.sbTransition && this.sbActive) {
|
||||
@@ -285,13 +275,6 @@ export class ViewController {
|
||||
}
|
||||
}
|
||||
|
||||
swipeBackProgress(progress) {
|
||||
if (this.sbTransition) {
|
||||
ClickBlock(true, 4000);
|
||||
this.sbTransition.progress( Math.min(1, Math.max(0, progress)) );
|
||||
}
|
||||
}
|
||||
|
||||
swipeBackEnabled() {
|
||||
if (this.items.length > 1) {
|
||||
let activeItem = this.getActive();
|
||||
@@ -332,9 +315,7 @@ export class ViewController {
|
||||
let state;
|
||||
for (let i = 0, ii = this.items.length; i < ii; i++) {
|
||||
state = this.items[i].state;
|
||||
if (state === ACTIVELY_ENTERING_STATE ||
|
||||
state === ACTIVELY_LEAVING_STATE ||
|
||||
state === STAGED_ENTERING_STATE ||
|
||||
if (state === STAGED_ENTERING_STATE ||
|
||||
state === STAGED_LEAVING_STATE) {
|
||||
return true;
|
||||
}
|
||||
@@ -460,7 +441,5 @@ const ACTIVE_STATE = 1;
|
||||
const CACHED_STATE = 2;
|
||||
const STAGED_ENTERING_STATE = 3;
|
||||
const STAGED_LEAVING_STATE = 4;
|
||||
const ACTIVELY_ENTERING_STATE = 5;
|
||||
const ACTIVELY_LEAVING_STATE = 6;
|
||||
|
||||
let itemIds = -1;
|
||||
|
||||
@@ -15,15 +15,13 @@ export class ViewItem {
|
||||
this.params = new NavParams(params);
|
||||
this.instance = null;
|
||||
this.state = 0;
|
||||
|
||||
this._titleEle = undefined;
|
||||
this._backBtn = undefined;
|
||||
this.disposals = [];
|
||||
|
||||
// if it's possible to go back from this nav item
|
||||
this.enableBack = false;
|
||||
|
||||
this.protos = {};
|
||||
this._nbItms = [];
|
||||
}
|
||||
|
||||
addProtoViewRef(name, protoViewRef) {
|
||||
@@ -92,10 +90,10 @@ export class ViewItem {
|
||||
// add a navbar view if the pane has a navbar container, and the
|
||||
// item's instance has a navbar protoview to go to inside of it
|
||||
if (navbarViewContainer && navbarProtoView) {
|
||||
this.navbarView = navbarViewContainer.create(navbarProtoView, -1, context, injector);
|
||||
let navbarView = navbarViewContainer.create(navbarProtoView, -1, context, injector);
|
||||
|
||||
this.disposals.push(() => {
|
||||
navbarViewContainer.remove( navbarViewContainer.indexOf(this.navbarView) );
|
||||
navbarViewContainer.remove( navbarViewContainer.indexOf(navbarView) );
|
||||
});
|
||||
}
|
||||
|
||||
@@ -199,44 +197,31 @@ export class ViewItem {
|
||||
}
|
||||
|
||||
navbarElement() {
|
||||
let navbarView = this.navbarView;
|
||||
if (navbarView && navbarView._view) {
|
||||
return navbarView._view.render._view.rootNodes[0];
|
||||
if (arguments.length) {
|
||||
this._nbEle = arguments[0];
|
||||
}
|
||||
}
|
||||
|
||||
contentElement() {
|
||||
return this.viewEle.querySelector('ion-content');
|
||||
return this._nbEle;
|
||||
}
|
||||
|
||||
titleElement() {
|
||||
if (this._titleEle === undefined) {
|
||||
let navbarElement = this.navbarElement();
|
||||
if (navbarElement) {
|
||||
let titleEle = navbarElement.querySelector('ion-title');
|
||||
if (titleEle) {
|
||||
this._titleEle = titleEle;
|
||||
return this._titleEle;
|
||||
}
|
||||
}
|
||||
this._titleEle = null;
|
||||
if (arguments.length) {
|
||||
this._ttEle = arguments[0];
|
||||
}
|
||||
return this._titleEle;
|
||||
return this._ttEle;
|
||||
}
|
||||
|
||||
backButtonElement() {
|
||||
if (this._backBtn === undefined) {
|
||||
let navbarElement = this.navbarElement();
|
||||
if (navbarElement) {
|
||||
let backBtn = navbarElement.querySelector('back-button');
|
||||
if (backBtn) {
|
||||
this._backBtn = backBtn;
|
||||
return this._backBtn;
|
||||
}
|
||||
}
|
||||
this._backBtn = null;
|
||||
if (arguments.length) {
|
||||
this._bbEle = arguments[0];
|
||||
}
|
||||
return this._backBtn;
|
||||
return this._bbEle;
|
||||
}
|
||||
|
||||
navbarItemElements() {
|
||||
if (arguments.length) {
|
||||
this._nbItms.push(arguments[0]);
|
||||
}
|
||||
return this._nbItms;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -9,4 +9,6 @@ ion-view {
|
||||
flex-direction: column;
|
||||
|
||||
background-color: white;
|
||||
|
||||
transform: translateZ(0px);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import {Transition} from './transition';
|
||||
import {Animation} from '../animations/animation';
|
||||
|
||||
|
||||
const DURATION = 500;
|
||||
const DURATION = 1000;
|
||||
const EASING = 'cubic-bezier(0.36,0.66,0.04,1)';
|
||||
|
||||
const OPACITY = 'opacity';
|
||||
@@ -19,77 +19,63 @@ class IOSTransition extends Transition {
|
||||
constructor(nav, opts) {
|
||||
super(nav, opts);
|
||||
|
||||
const self = this;
|
||||
|
||||
// global duration and easing for all child animations
|
||||
this.duration(DURATION);
|
||||
this.easing(EASING);
|
||||
self.duration(DURATION);
|
||||
self.easing(EASING);
|
||||
|
||||
// entering item moves to center
|
||||
this.enteringView
|
||||
self.enteringView
|
||||
.to(TRANSLATEX, CENTER)
|
||||
.to(OPACITY, 1);
|
||||
|
||||
this.enteringTitle
|
||||
.from(OPACITY, 0)
|
||||
.to(OPACITY, 1)
|
||||
self.enteringTitle
|
||||
.fadeIn()
|
||||
.to(TRANSLATEX, CENTER);
|
||||
|
||||
// if the back button should show, then fade it in
|
||||
if (this.entering.enableBack) {
|
||||
let enteringBackButton = new Animation(this.entering.backButtonElement())
|
||||
enteringBackButton
|
||||
.from(OPACITY, 0)
|
||||
.to(OPACITY, 1);
|
||||
this.add(enteringBackButton);
|
||||
}
|
||||
|
||||
// leaving view moves off screen
|
||||
this.leavingView
|
||||
self.leavingView
|
||||
.from(TRANSLATEX, CENTER)
|
||||
.from(OPACITY, 1);
|
||||
|
||||
this.leavingTitle
|
||||
self.leavingTitle
|
||||
.from(TRANSLATEX, CENTER)
|
||||
.from(OPACITY, 1);
|
||||
|
||||
let leavingBackButton = new Animation(this.leaving.backButtonElement());
|
||||
leavingBackButton
|
||||
.from(OPACITY, 1)
|
||||
.to(OPACITY, 0);
|
||||
this.add(leavingBackButton);
|
||||
|
||||
// set properties depending on direction
|
||||
if (opts.direction === 'back') {
|
||||
// back direction
|
||||
this.enteringView
|
||||
self.enteringView
|
||||
.from(TRANSLATEX, OFF_LEFT)
|
||||
.from(OPACITY, OFF_OPACITY)
|
||||
.to(OPACITY, 1);
|
||||
|
||||
this.enteringTitle
|
||||
self.enteringTitle
|
||||
.from(TRANSLATEX, OFF_LEFT);
|
||||
|
||||
this.leavingView
|
||||
self.leavingView
|
||||
.to(TRANSLATEX, OFF_RIGHT)
|
||||
.to(OPACITY, 1);
|
||||
|
||||
this.leavingTitle
|
||||
self.leavingTitle
|
||||
.to(TRANSLATEX, OFF_RIGHT)
|
||||
.to(OPACITY, 0);
|
||||
|
||||
} else {
|
||||
// forward direction
|
||||
this.enteringView
|
||||
self.enteringView
|
||||
.from(TRANSLATEX, OFF_RIGHT)
|
||||
.from(OPACITY, 1);
|
||||
|
||||
this.enteringTitle
|
||||
self.enteringTitle
|
||||
.from(TRANSLATEX, OFF_RIGHT);
|
||||
|
||||
this.leavingView
|
||||
self.leavingView
|
||||
.to(TRANSLATEX, OFF_LEFT)
|
||||
.to(OPACITY, OFF_OPACITY);
|
||||
|
||||
this.leavingTitle
|
||||
self.leavingTitle
|
||||
.to(TRANSLATEX, OFF_LEFT)
|
||||
.to(OPACITY, 0);
|
||||
}
|
||||
|
||||
@@ -1,67 +1,93 @@
|
||||
import {Animation} from '../animations/animation';
|
||||
import {raf} from '../util/dom';
|
||||
|
||||
const SHOW_NAVBAR_CSS = 'show-navbar';
|
||||
const SHOW_VIEW_CSS = 'show-view';
|
||||
const SHOW_BACK_BUTTON = 'show-back-button';
|
||||
const SHOW_NAVBAR_ITEM = 'show-navbar-item';
|
||||
|
||||
let TransitionRegistry = {};
|
||||
|
||||
let registry = {};
|
||||
|
||||
export class Transition extends Animation {
|
||||
|
||||
constructor(nav, opts) {
|
||||
super();
|
||||
|
||||
const self = this;
|
||||
|
||||
// get the entering and leaving items
|
||||
let enteringItem = this.entering = nav.getStagedEnteringItem();
|
||||
let leavingItem = this.leaving = nav.getStagedLeavingItem();
|
||||
let enteringItem = self.entering = nav.getStagedEnteringItem();
|
||||
let leavingItem = self.leaving = nav.getStagedLeavingItem();
|
||||
|
||||
// create animation for the entering item's "ion-view" element
|
||||
this.enteringView = new Animation(enteringItem.viewElement());
|
||||
this.enteringView.beforePlay.addClass(SHOW_VIEW_CSS);
|
||||
this.add(this.enteringView);
|
||||
self.enteringView = new Animation(enteringItem.viewElement());
|
||||
self.enteringView.before.addClass(SHOW_VIEW_CSS);
|
||||
self.add(self.enteringView);
|
||||
|
||||
// create animation for the entering item's "ion-navbar" element
|
||||
if (opts.navbar !== false) {
|
||||
this.enteringNavbar = new Animation(enteringItem.navbarElement());
|
||||
this.enteringNavbar.beforePlay.addClass(SHOW_NAVBAR_CSS);
|
||||
let enteringNavbar = self.enteringNavbar = new Animation(enteringItem.navbarElement());
|
||||
enteringNavbar.before.addClass(SHOW_NAVBAR_CSS);
|
||||
|
||||
if (enteringItem.enableBack) {
|
||||
// only animate in the back button if the entering view has it enabled
|
||||
let enteringBackButton = self.enteringBackButton = new Animation(enteringItem.backButtonElement());
|
||||
enteringBackButton
|
||||
.before.addClass(SHOW_BACK_BUTTON)
|
||||
.fadeIn();
|
||||
enteringNavbar.add(enteringBackButton);
|
||||
}
|
||||
|
||||
// create animation for the entering item's "ion-title" element
|
||||
this.enteringTitle = new Animation(enteringItem.titleElement());
|
||||
this.enteringNavbar.add(this.enteringTitle);
|
||||
this.add(this.enteringNavbar);
|
||||
self.enteringTitle = new Animation(enteringItem.titleElement());
|
||||
enteringNavbar.add(self.enteringTitle);
|
||||
self.add(enteringNavbar);
|
||||
|
||||
self.enteringNavbarItems = new Animation(enteringItem.navbarItemElements())
|
||||
self.enteringNavbarItems
|
||||
.before.addClass(SHOW_NAVBAR_ITEM)
|
||||
.fadeIn();
|
||||
enteringNavbar.add(self.enteringNavbarItems);
|
||||
}
|
||||
|
||||
if (leavingItem) {
|
||||
// create animation for the entering item's "ion-view" element
|
||||
this.leavingView = new Animation(leavingItem.viewElement());
|
||||
this.leavingView.afterFinish.removeClass(SHOW_VIEW_CSS);
|
||||
self.leavingView = new Animation(leavingItem.viewElement());
|
||||
self.leavingView.after.removeClass(SHOW_VIEW_CSS);
|
||||
|
||||
// create animation for the entering item's "ion-navbar" element
|
||||
this.leavingNavbar = new Animation(leavingItem.navbarElement());
|
||||
this.leavingNavbar.afterFinish.removeClass(SHOW_NAVBAR_CSS);
|
||||
let leavingNavbar = self.leavingNavbar = new Animation(leavingItem.navbarElement());
|
||||
leavingNavbar.after.removeClass(SHOW_NAVBAR_CSS);
|
||||
|
||||
let leavingBackButton = self.leavingBackButton = new Animation(leavingItem.backButtonElement());
|
||||
leavingBackButton
|
||||
.after.removeClass(SHOW_BACK_BUTTON)
|
||||
.fadeOut();
|
||||
leavingNavbar.add(leavingBackButton);
|
||||
|
||||
// create animation for the leaving item's "ion-title" element
|
||||
this.leavingTitle = new Animation(leavingItem.titleElement());
|
||||
this.leavingNavbar.add(this.leavingTitle);
|
||||
self.leavingTitle = new Animation(leavingItem.titleElement());
|
||||
leavingNavbar.add(self.leavingTitle);
|
||||
|
||||
this.add(this.leavingView, this.leavingNavbar);
|
||||
self.leavingNavbarItems = new Animation(leavingItem.navbarItemElements())
|
||||
self.leavingNavbarItems
|
||||
.after.removeClass(SHOW_NAVBAR_ITEM)
|
||||
.fadeOut();
|
||||
leavingNavbar.add(self.leavingNavbarItems);
|
||||
|
||||
self.add(self.leavingView, leavingNavbar);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
stage(callback) {
|
||||
raf(callback);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
STATIC CLASSES
|
||||
*/
|
||||
static create(nav, opts = {}) {
|
||||
let name = opts.animation || 'ios';
|
||||
const name = opts.animation || 'ios';
|
||||
|
||||
let TransitionClass = registry[name];
|
||||
let TransitionClass = TransitionRegistry[name];
|
||||
if (!TransitionClass) {
|
||||
// transition wasn't found, default to a 'none' transition
|
||||
// which doesn't animate anything, just shows and hides
|
||||
@@ -72,7 +98,7 @@ export class Transition extends Animation {
|
||||
}
|
||||
|
||||
static register(name, TransitionClass) {
|
||||
registry[name] = TransitionClass;
|
||||
TransitionRegistry[name] = TransitionClass;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -13,6 +13,31 @@
|
||||
<script src="https://jspm.io/system@0.16.js"></script>
|
||||
-->
|
||||
|
||||
<style>
|
||||
/* hack to create tall scrollable areas for testing using <f></f> */
|
||||
f {
|
||||
display: block;
|
||||
margin: 15px auto;
|
||||
max-width: 150px;
|
||||
height: 150px;
|
||||
background: blue;
|
||||
}
|
||||
f:last-of-type {
|
||||
background: red;
|
||||
}
|
||||
ion-tab:nth-of-type(2) f,
|
||||
.green f {
|
||||
background: green;
|
||||
max-width: 250px;
|
||||
height: 100px;
|
||||
}
|
||||
ion-tab:nth-of-type(3) f,
|
||||
.yellow f {
|
||||
background: yellow;
|
||||
width: 100px;
|
||||
height: 50px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
2
scripts/vendor/web-animations-js/inter-component-web-animations-next-lite.js
vendored
Normal file
2
scripts/vendor/web-animations-js/inter-component-web-animations-next-lite.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
scripts/vendor/web-animations-js/inter-component-web-animations-next-lite.js.map
vendored
Normal file
1
scripts/vendor/web-animations-js/inter-component-web-animations-next-lite.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
2
scripts/vendor/web-animations-js/inter-component-web-animations-next-liteweb-animations-1.js
vendored
Normal file
2
scripts/vendor/web-animations-js/inter-component-web-animations-next-liteweb-animations-1.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
scripts/vendor/web-animations-js/inter-component-web-animations-next.js
vendored
Normal file
2
scripts/vendor/web-animations-js/inter-component-web-animations-next.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
scripts/vendor/web-animations-js/inter-component-web-animations-next.js.map
vendored
Normal file
1
scripts/vendor/web-animations-js/inter-component-web-animations-next.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
3
scripts/vendor/web-animations-js/inter-component-web-animations-nextweb-animations-1.js
vendored
Normal file
3
scripts/vendor/web-animations-js/inter-component-web-animations-nextweb-animations-1.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
scripts/vendor/web-animations-js/inter-component-web-animations-nextweb-animations-1.js.map
vendored
Normal file
1
scripts/vendor/web-animations-js/inter-component-web-animations-nextweb-animations-1.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
15
scripts/vendor/web-animations-js/inter-guarded-web-animations-next-lite-web-animations-1.js
vendored
Normal file
15
scripts/vendor/web-animations-js/inter-guarded-web-animations-next-lite-web-animations-1.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
16
scripts/vendor/web-animations-js/inter-guarded-web-animations-next-web-animations-1.js
vendored
Normal file
16
scripts/vendor/web-animations-js/inter-guarded-web-animations-next-web-animations-1.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
scripts/vendor/web-animations-js/inter-guarded-web-animations-next-web-animations-1.js.map
vendored
Normal file
1
scripts/vendor/web-animations-js/inter-guarded-web-animations-next-web-animations-1.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
3
scripts/vendor/web-animations-js/inter-raw-web-animations.js
vendored
Normal file
3
scripts/vendor/web-animations-js/inter-raw-web-animations.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
scripts/vendor/web-animations-js/inter-raw-web-animations.js.map
vendored
Normal file
1
scripts/vendor/web-animations-js/inter-raw-web-animations.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
2
scripts/vendor/web-animations-js/inter-web-animations-next-lite-preamble.js
vendored
Normal file
2
scripts/vendor/web-animations-js/inter-web-animations-next-lite-preamble.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
scripts/vendor/web-animations-js/inter-web-animations-next-lite-preamble.js.map
vendored
Normal file
1
scripts/vendor/web-animations-js/inter-web-animations-next-lite-preamble.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
19
scripts/vendor/web-animations-js/inter-web-animations-next-lite.js
vendored
Normal file
19
scripts/vendor/web-animations-js/inter-web-animations-next-lite.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
scripts/vendor/web-animations-js/inter-web-animations-next-lite.js.map
vendored
Normal file
1
scripts/vendor/web-animations-js/inter-web-animations-next-lite.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
2
scripts/vendor/web-animations-js/inter-web-animations-next-preamble.js
vendored
Normal file
2
scripts/vendor/web-animations-js/inter-web-animations-next-preamble.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
scripts/vendor/web-animations-js/inter-web-animations-next-preamble.js.map
vendored
Normal file
1
scripts/vendor/web-animations-js/inter-web-animations-next-preamble.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
20
scripts/vendor/web-animations-js/inter-web-animations-next.js
vendored
Normal file
20
scripts/vendor/web-animations-js/inter-web-animations-next.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
scripts/vendor/web-animations-js/inter-web-animations-next.js.map
vendored
Normal file
1
scripts/vendor/web-animations-js/inter-web-animations-next.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
16
scripts/vendor/web-animations-js/inter-web-animations.js
vendored
Normal file
16
scripts/vendor/web-animations-js/inter-web-animations.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
scripts/vendor/web-animations-js/inter-web-animations.js.map
vendored
Normal file
1
scripts/vendor/web-animations-js/inter-web-animations.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -186,11 +186,14 @@
|
||||
if ((finished || this._idle) && !this._finishedFlag) {
|
||||
var event = new AnimationEvent(this, this._currentTime, baseTime);
|
||||
var handlers = this._finishHandlers.concat(this.onfinish ? [this.onfinish] : []);
|
||||
setTimeout(function() {
|
||||
handlers.forEach(function(handler) {
|
||||
handler.call(event.target, event);
|
||||
});
|
||||
}, 0);
|
||||
// setTimeout(function() {
|
||||
// handlers.forEach(function(handler) {
|
||||
// handler.call(event.target, event);
|
||||
// });
|
||||
// }, 0);
|
||||
handlers.forEach(function(handler) {
|
||||
handler.call(event.target, event);
|
||||
});
|
||||
}
|
||||
this._finishedFlag = finished;
|
||||
},
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user