mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-02-04 13:16:08 +08:00
swipe back and the seven dwarfs
This commit is contained in:
@@ -239,15 +239,33 @@ export class Animation {
|
||||
this._hasFinished = true;
|
||||
|
||||
var i, j, ele;
|
||||
for (i = 0; i < this._el.length; i++) {
|
||||
ele = this._el[i];
|
||||
|
||||
for (j = 0; j < this._afterAddCls.length; j++) {
|
||||
ele.classList.add(this._afterAddCls[j]);
|
||||
if (this.playbackRate() < 0) {
|
||||
// reverse direction
|
||||
for (i = 0; i < this._el.length; i++) {
|
||||
ele = this._el[i];
|
||||
|
||||
for (j = 0; j < this._beforeAddCls.length; j++) {
|
||||
ele.classList.remove(this._beforeAddCls[j]);
|
||||
}
|
||||
|
||||
for (j = 0; j < this._beforeRmvCls.length; j++) {
|
||||
ele.classList.add(this._beforeRmvCls[j]);
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < this._afterRmvCls.length; j++) {
|
||||
ele.classList.remove(this._afterRmvCls[j]);
|
||||
} else {
|
||||
// normal direction
|
||||
for (i = 0; i < this._el.length; i++) {
|
||||
ele = this._el[i];
|
||||
|
||||
for (j = 0; j < this._afterAddCls.length; j++) {
|
||||
ele.classList.add(this._afterAddCls[j]);
|
||||
}
|
||||
|
||||
for (j = 0; j < this._afterRmvCls.length; j++) {
|
||||
ele.classList.remove(this._afterRmvCls[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -293,8 +311,7 @@ class Animate {
|
||||
this.player = ele.animate([fromEffect, toEffect], {
|
||||
duration: duration,
|
||||
easing: easing,
|
||||
playbackRate: playbackRate || 1,
|
||||
fill: 'both'
|
||||
playbackRate: playbackRate || 1
|
||||
});
|
||||
|
||||
this.promise = new Promise(resolve => {
|
||||
|
||||
@@ -21,47 +21,51 @@ export class SwipeHandle {
|
||||
gesture.on('panleft', onDragHorizontal);
|
||||
gesture.on('panright', onDragHorizontal);
|
||||
|
||||
let navWidth = 0;
|
||||
let startX = null;
|
||||
let swipeableAreaWidth = null;
|
||||
|
||||
function onDragEnd(ev) {
|
||||
// TODO: POLISH THESE NUMBERS WITH GOOD MATHIFICATION
|
||||
|
||||
let progress = ev.gesture.center.x / navWidth;
|
||||
let progress = (ev.gesture.center.x - startX) / swipeableAreaWidth;
|
||||
let completeSwipeBack = (progress > 0.5);
|
||||
let playbackRate = 4;
|
||||
|
||||
if (completeSwipeBack) {
|
||||
// complete swipe back
|
||||
if (progress > 0.7) {
|
||||
playbackRate = 3;
|
||||
if (progress > 0.9) {
|
||||
playbackRate = 1;
|
||||
} else if (progress > 0.8) {
|
||||
playbackRate = 2;
|
||||
} else if (progress > 0.9) {
|
||||
playbackRate = 1;
|
||||
} else if (progress > 0.7) {
|
||||
playbackRate = 3;
|
||||
}
|
||||
|
||||
} else {
|
||||
// cancel swipe back
|
||||
if (progress < 0.3) {
|
||||
playbackRate = 3;
|
||||
if (progress < 0.1) {
|
||||
playbackRate = 1;
|
||||
} else if (progress < 0.2) {
|
||||
playbackRate = 2;
|
||||
} else if (progress < 0.1) {
|
||||
playbackRate = 1;
|
||||
} else if (progress < 0.3) {
|
||||
playbackRate = 3;
|
||||
}
|
||||
}
|
||||
|
||||
nav.swipeBackEnd(completeSwipeBack, progress, playbackRate);
|
||||
navWidth = 0;
|
||||
|
||||
startX = null;
|
||||
}
|
||||
|
||||
function onDragHorizontal(ev) {
|
||||
if (navWidth === 0) {
|
||||
navWidth = nav.width();
|
||||
if (startX === null) {
|
||||
startX = ev.gesture.center.x;
|
||||
swipeableAreaWidth = nav.width() - startX;
|
||||
|
||||
nav.swipeBackStart();
|
||||
}
|
||||
|
||||
nav.swipeBackProgress( ev.gesture.center.x / navWidth );
|
||||
nav.swipeBackProgress( (ev.gesture.center.x - startX) / swipeableAreaWidth );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ export class NavBase {
|
||||
this.injector = injector;
|
||||
this.items = [];
|
||||
this.navCtrl = new NavController(this);
|
||||
this.swipeBackTransition = null;
|
||||
this.sbTransition = null;
|
||||
}
|
||||
|
||||
set initial(Class) {
|
||||
@@ -156,7 +156,7 @@ export class NavBase {
|
||||
return;
|
||||
}
|
||||
|
||||
this.swipeBackResolve = null;
|
||||
this.sbResolve = null;
|
||||
|
||||
// default the direction to "back"
|
||||
let opts = {
|
||||
@@ -187,26 +187,33 @@ export class NavBase {
|
||||
enteringItem.state = STAGED_ENTERING_STATE;
|
||||
|
||||
// init the transition animation
|
||||
this.swipeBackTransition = Transition.create(this, opts);
|
||||
this.swipeBackTransition.easing('linear');
|
||||
this.sbTransition = Transition.create(this, opts);
|
||||
this.sbTransition.easing('linear');
|
||||
|
||||
// wait for the items to be fully staged
|
||||
this.swipeBackTransition.stage().then(() => {
|
||||
this.sbTransition.stage().then(() => {
|
||||
|
||||
// update the state that the items are actively entering/leaving
|
||||
enteringItem.state = ACTIVELY_ENTERING_STATE;
|
||||
leavingItem.state = ACTIVELY_LEAVING_STATE;
|
||||
|
||||
let swipeBackPromise = new Promise(res => { this.swipeBackResolve = res; });
|
||||
let swipeBackPromise = new Promise(res => { this.sbResolve = res; });
|
||||
|
||||
swipeBackPromise.then(() => {
|
||||
swipeBackPromise.then((completeSwipeBack) => {
|
||||
|
||||
// transition has completed, update each item's state
|
||||
enteringItem.state = ACTIVE_STATE;
|
||||
leavingItem.state = CACHED_STATE;
|
||||
if (completeSwipeBack) {
|
||||
// swipe back has completed, update each item's state
|
||||
enteringItem.state = ACTIVE_STATE;
|
||||
leavingItem.state = CACHED_STATE;
|
||||
|
||||
// destroy any items that shouldn't stay around
|
||||
this.cleanup();
|
||||
// destroy any items that shouldn't stay around
|
||||
this.cleanup();
|
||||
|
||||
} else {
|
||||
// cancelled the swipe back, return items to original state
|
||||
leavingItem.state = ACTIVE_STATE;
|
||||
enteringItem.state = CACHED_STATE;
|
||||
}
|
||||
|
||||
// allow clicks again
|
||||
ClickBlock(false);
|
||||
@@ -220,42 +227,38 @@ export class NavBase {
|
||||
}
|
||||
|
||||
swipeBackEnd(completeSwipeBack, progress, playbackRate) {
|
||||
console.log('swipeBackEnd, completeSwipeBack: ', completeSwipeBack, ' progress:', progress, ' playbackRate:', playbackRate);
|
||||
// to reverse the animation use a negative playbackRate
|
||||
if (!completeSwipeBack) playbackRate = playbackRate * -1;
|
||||
|
||||
this.swipeBackTransition.playbackRate(playbackRate);
|
||||
this.sbTransition.playbackRate(playbackRate);
|
||||
|
||||
this.swipeBackTransition.play().then(() => {
|
||||
this.swipeBackResolve && this.swipeBackResolve();
|
||||
|
||||
if (this.swipeBackTransition) {
|
||||
this.swipeBackTransition.dispose();
|
||||
}
|
||||
|
||||
this.swipeBackResolve = this.swipeBackTransition = null;
|
||||
this.sbTransition.play().then(() => {
|
||||
this.sbResolve && this.sbResolve(completeSwipeBack);
|
||||
this.sbTransition && this.sbTransition.dispose();
|
||||
this.sbResolve = this.sbTransition = null;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
swipeBackProgress(progress) {
|
||||
if (this.swipeBackTransition) {
|
||||
if (this.sbTransition) {
|
||||
ClickBlock(true, 4000);
|
||||
this.swipeBackTransition.progress( Math.min(1, Math.max(0, progress)) );
|
||||
this.sbTransition.progress( Math.min(1, Math.max(0, progress)) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
cleanup() {
|
||||
for (let i = 0, ii = this.items.length; i < ii; i++) {
|
||||
let item = this.items[i];
|
||||
this.items.forEach((item) => {
|
||||
|
||||
if (item && item.shouldDestroy) {
|
||||
this.remove(item);
|
||||
i = 0;
|
||||
ii = this.items.length;
|
||||
|
||||
util.dom.raf(() => {
|
||||
item.destroy();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
isTransitioning() {
|
||||
|
||||
@@ -76,7 +76,6 @@ class IOSTransition extends Animation {
|
||||
// leaving view moves off screen
|
||||
// when completed, set leavingItem to display: none
|
||||
leavingContent
|
||||
.beforePlay.addClass(SHOW_NAV_ITEM_CSS)
|
||||
.afterFinish.removeClass(SHOW_NAV_ITEM_CSS)
|
||||
.from(TRANSFORM, CENTER)
|
||||
.from(OPACITY, 1);
|
||||
|
||||
Reference in New Issue
Block a user