mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-19 11:41:20 +08:00
transition improvements
This commit is contained in:
@ -1,6 +1,6 @@
|
|||||||
import {CSS} from '../util/dom';
|
import {CSS, raf} from '../util/dom';
|
||||||
|
|
||||||
const RENDER_DELAY = 36;
|
const RENDER_DELAY = 32;
|
||||||
let AnimationRegistry = {};
|
let AnimationRegistry = {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -17,10 +17,11 @@ let AnimationRegistry = {};
|
|||||||
8) Run from/to animation on elements
|
8) Run from/to animation on elements
|
||||||
9) Animations finish async
|
9) Animations finish async
|
||||||
10) Set inline styles w/ the "to" effects on elements
|
10) Set inline styles w/ the "to" effects on elements
|
||||||
11) Add after classes to elements
|
11) Call onFinish()
|
||||||
12) Remove after classes from elements
|
12) Wait one rAF
|
||||||
13) Call onFinish()
|
13) Add after classes to elements
|
||||||
14) Resolve play()'s promise
|
14) Remove after classes from elements
|
||||||
|
15) Resolve play()'s promise
|
||||||
**/
|
**/
|
||||||
|
|
||||||
export class Animation {
|
export class Animation {
|
||||||
@ -209,7 +210,10 @@ export class Animation {
|
|||||||
children[i]._onFinish();
|
children[i]._onFinish();
|
||||||
}
|
}
|
||||||
self._onFinish();
|
self._onFinish();
|
||||||
resolve();
|
raf(() => {
|
||||||
|
self._onAfter();
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -291,42 +295,47 @@ export class Animation {
|
|||||||
|
|
||||||
_onFinish() {
|
_onFinish() {
|
||||||
// after the animations have finished
|
// after the animations have finished
|
||||||
const self = this;
|
if (!this._isFinished) {
|
||||||
|
this._isFinished = true;
|
||||||
|
this.onFinish && this.onFinish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_onAfter() {
|
||||||
|
// one requestAnimationFrame after onFinish happened
|
||||||
let i, j, ele;
|
let i, j, ele;
|
||||||
|
|
||||||
if (!self._isFinished) {
|
for (i = 0; i < this._children.length; i++) {
|
||||||
self._isFinished = true;
|
this._children[i]._onAfter();
|
||||||
|
}
|
||||||
|
|
||||||
if (self.playbackRate() < 0) {
|
if (this.playbackRate() < 0) {
|
||||||
// reverse direction
|
// reverse direction
|
||||||
for (i = 0; i < self._el.length; i++) {
|
for (i = 0; i < this._el.length; i++) {
|
||||||
ele = self._el[i];
|
ele = this._el[i];
|
||||||
|
|
||||||
for (j = 0; j < self._bfAdd.length; j++) {
|
for (j = 0; j < this._bfAdd.length; j++) {
|
||||||
ele.classList.remove(self._bfAdd[j]);
|
ele.classList.remove(this._bfAdd[j]);
|
||||||
}
|
|
||||||
|
|
||||||
for (j = 0; j < self._bfRmv.length; j++) {
|
|
||||||
ele.classList.add(self._bfRmv[j]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
for (j = 0; j < this._bfRmv.length; j++) {
|
||||||
// normal direction
|
ele.classList.add(this._bfRmv[j]);
|
||||||
for (i = 0; i < self._el.length; i++) {
|
|
||||||
ele = self._el[i];
|
|
||||||
|
|
||||||
for (j = 0; j < self._afAdd.length; j++) {
|
|
||||||
ele.classList.add(self._afAdd[j]);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (j = 0; j < self._afRmv.length; j++) {
|
|
||||||
ele.classList.remove(self._afRmv[j]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.onFinish && self.onFinish();
|
} else {
|
||||||
|
// normal direction
|
||||||
|
for (i = 0; i < this._el.length; i++) {
|
||||||
|
ele = this._el[i];
|
||||||
|
|
||||||
|
for (j = 0; j < this._afAdd.length; j++) {
|
||||||
|
ele.classList.add(this._afAdd[j]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = 0; j < this._afRmv.length; j++) {
|
||||||
|
ele.classList.remove(this._afRmv[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,7 +85,9 @@ $content-padding: 10px !default;
|
|||||||
opacity: 0;
|
opacity: 0;
|
||||||
z-index: $z-index-click-block;
|
z-index: $z-index-click-block;
|
||||||
transform: translate3d(-9999px, 0px, 0px);
|
transform: translate3d(-9999px, 0px, 0px);
|
||||||
overflow: hidden;
|
|
||||||
|
//background: red;
|
||||||
|
//opacity: .3;
|
||||||
}
|
}
|
||||||
|
|
||||||
.click-block-active {
|
.click-block-active {
|
||||||
|
@ -72,10 +72,8 @@ export class Navbar {
|
|||||||
alignTitle() {
|
alignTitle() {
|
||||||
// called after the navbar/title has had a moment to
|
// called after the navbar/title has had a moment to
|
||||||
// finish rendering in their correct locations
|
// finish rendering in their correct locations
|
||||||
|
|
||||||
const navbarEle = this._ele;
|
const navbarEle = this._ele;
|
||||||
const innerTitleEle = this._innerTtEle || (this._innerTtEle = navbarEle.querySelector('.navbar-inner-title'));
|
const titleEle = this._ttEle || (this._ttEle = navbarEle.querySelector('ion-title'));
|
||||||
const titleEle = this._ttEle || (this._ttEle = innerTitleEle.querySelector('ion-title'));
|
|
||||||
|
|
||||||
// don't bother if there's no title element
|
// don't bother if there's no title element
|
||||||
if (!titleEle) return;
|
if (!titleEle) return;
|
||||||
@ -87,9 +85,8 @@ export class Navbar {
|
|||||||
if (titleStyle.textAlign !== 'center') return;
|
if (titleStyle.textAlign !== 'center') return;
|
||||||
|
|
||||||
// get all the dimensions
|
// get all the dimensions
|
||||||
const titleOffsetWidth = titleEle.offsetWidth;
|
|
||||||
const titleOffsetLeft = titleEle.offsetLeft;
|
const titleOffsetLeft = titleEle.offsetLeft;
|
||||||
const titleOffsetRight = navbarEle.offsetWidth - (titleOffsetLeft + titleOffsetWidth);
|
const titleOffsetRight = navbarEle.offsetWidth - (titleOffsetLeft + titleEle.offsetWidth);
|
||||||
|
|
||||||
let marginLeft = 0;
|
let marginLeft = 0;
|
||||||
let marginRight = 0;
|
let marginRight = 0;
|
||||||
@ -104,6 +101,7 @@ export class Navbar {
|
|||||||
|
|
||||||
if ((marginLeft || marginRight) && margin !== this._ttMargin) {
|
if ((marginLeft || marginRight) && margin !== this._ttMargin) {
|
||||||
// only do an update if it has to
|
// only do an update if it has to
|
||||||
|
const innerTitleEle = this._innerTtEle || (this._innerTtEle = navbarEle.querySelector('.navbar-inner-title'));
|
||||||
innerTitleEle.style.margin = this._ttMargin = margin;
|
innerTitleEle.style.margin = this._ttMargin = margin;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ ion-navbar {
|
|||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
order: $flex-order-toolbar-top;
|
order: $flex-order-toolbar-top;
|
||||||
|
|
||||||
transform: translate3d(0px, -9999px, 0px);
|
transform: translate3d(100%, 0px, 0px);
|
||||||
&.show-navbar {
|
&.show-navbar {
|
||||||
transform: translate3d(0px, 0px, 0px);
|
transform: translate3d(0px, 0px, 0px);
|
||||||
}
|
}
|
||||||
|
@ -122,8 +122,6 @@ export class ViewController {
|
|||||||
|
|
||||||
opts.animate = (opts.animation !== 'none');
|
opts.animate = (opts.animation !== 'none');
|
||||||
|
|
||||||
this.transitionStart(opts);
|
|
||||||
|
|
||||||
// wait for the new item to complete setup
|
// wait for the new item to complete setup
|
||||||
enteringItem.stage(() => {
|
enteringItem.stage(() => {
|
||||||
|
|
||||||
@ -144,6 +142,13 @@ export class ViewController {
|
|||||||
transAnimation.duration(0);
|
transAnimation.duration(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let duration = transAnimation.duration();
|
||||||
|
if (duration > 64) {
|
||||||
|
// block any clicks during the transition and provide a
|
||||||
|
// fallback to remove the clickblock if something goes wrong
|
||||||
|
ClickBlock(true, duration + 200);
|
||||||
|
}
|
||||||
|
|
||||||
// start the transition
|
// start the transition
|
||||||
transAnimation.play().then(() => {
|
transAnimation.play().then(() => {
|
||||||
|
|
||||||
@ -193,9 +198,6 @@ export class ViewController {
|
|||||||
enteringItem.shouldCache = false;
|
enteringItem.shouldCache = false;
|
||||||
enteringItem.willEnter();
|
enteringItem.willEnter();
|
||||||
|
|
||||||
// start the transition
|
|
||||||
this.transitionStart({ animate: true });
|
|
||||||
|
|
||||||
// wait for the new item to complete setup
|
// wait for the new item to complete setup
|
||||||
enteringItem.stage(() => {
|
enteringItem.stage(() => {
|
||||||
|
|
||||||
@ -283,13 +285,6 @@ export class ViewController {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
transitionStart(opts) {
|
|
||||||
if (opts.animate) {
|
|
||||||
// block possible clicks during transition
|
|
||||||
ClickBlock(true, 520);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
transitionComplete() {
|
transitionComplete() {
|
||||||
|
|
||||||
this.items.forEach((item) => {
|
this.items.forEach((item) => {
|
||||||
|
@ -63,11 +63,11 @@ class IOSTransition extends Transition {
|
|||||||
} else {
|
} else {
|
||||||
// forward direction
|
// forward direction
|
||||||
this.enteringView
|
this.enteringView
|
||||||
.from(TRANSLATEX, '99%')
|
.from(TRANSLATEX, OFF_RIGHT)
|
||||||
.from(OPACITY, 1);
|
.from(OPACITY, 1);
|
||||||
|
|
||||||
this.enteringTitle
|
this.enteringTitle
|
||||||
.from(TRANSLATEX, '97%');
|
.from(TRANSLATEX, OFF_RIGHT);
|
||||||
|
|
||||||
this.leavingView
|
this.leavingView
|
||||||
.to(TRANSLATEX, OFF_LEFT)
|
.to(TRANSLATEX, OFF_LEFT)
|
||||||
|
@ -1,15 +1,9 @@
|
|||||||
|
|
||||||
const CSS_CLICK_BLOCK = 'click-block-active';
|
const CSS_CLICK_BLOCK = 'click-block-active';
|
||||||
const DEFAULT_EXPIRE = 330;
|
const DEFAULT_EXPIRE = 330;
|
||||||
let cbEle, fallbackTimerId;
|
let cbEle, fallbackTimerId;
|
||||||
let isShowing = false;
|
let isShowing = false;
|
||||||
|
|
||||||
|
|
||||||
function preventClick(ev) {
|
|
||||||
ev.preventDefault();
|
|
||||||
ev.stopPropagation();
|
|
||||||
}
|
|
||||||
|
|
||||||
function show(expire) {
|
function show(expire) {
|
||||||
clearTimeout(fallbackTimerId);
|
clearTimeout(fallbackTimerId);
|
||||||
fallbackTimerId = setTimeout(hide, expire || DEFAULT_EXPIRE);
|
fallbackTimerId = setTimeout(hide, expire || DEFAULT_EXPIRE);
|
||||||
@ -23,10 +17,6 @@ function show(expire) {
|
|||||||
cbEle = document.createElement('div');
|
cbEle = document.createElement('div');
|
||||||
cbEle.className = 'click-block ' + CSS_CLICK_BLOCK;
|
cbEle.className = 'click-block ' + CSS_CLICK_BLOCK;
|
||||||
document.body.appendChild(cbEle);
|
document.body.appendChild(cbEle);
|
||||||
cbEle.addEventListener('touchstart', preventClick);
|
|
||||||
cbEle.addEventListener('mousedown', preventClick);
|
|
||||||
cbEle.addEventListener('pointerdown', preventClick);
|
|
||||||
cbEle.addEventListener('MSPointerDown', preventClick);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user