diff --git a/ionic/animations/animation.js b/ionic/animations/animation.js index c11fc5611b..e9567b2c39 100644 --- a/ionic/animations/animation.js +++ b/ionic/animations/animation.js @@ -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 = {}; /** @@ -17,10 +17,11 @@ let AnimationRegistry = {}; 8) Run from/to animation on elements 9) Animations finish async 10) Set inline styles w/ the "to" effects on elements - 11) Add after classes to elements - 12) Remove after classes from elements - 13) Call onFinish() - 14) Resolve play()'s promise + 11) Call onFinish() + 12) Wait one rAF + 13) Add after classes to elements + 14) Remove after classes from elements + 15) Resolve play()'s promise **/ export class Animation { @@ -209,7 +210,10 @@ export class Animation { children[i]._onFinish(); } self._onFinish(); - resolve(); + raf(() => { + self._onAfter(); + resolve(); + }); }); } @@ -291,42 +295,47 @@ export class Animation { _onFinish() { // 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; - if (!self._isFinished) { - self._isFinished = true; + for (i = 0; i < this._children.length; i++) { + this._children[i]._onAfter(); + } - if (self.playbackRate() < 0) { - // reverse direction - for (i = 0; i < self._el.length; i++) { - ele = self._el[i]; + if (this.playbackRate() < 0) { + // reverse direction + for (i = 0; i < this._el.length; i++) { + ele = this._el[i]; - for (j = 0; j < self._bfAdd.length; j++) { - ele.classList.remove(self._bfAdd[j]); - } - - for (j = 0; j < self._bfRmv.length; j++) { - ele.classList.add(self._bfRmv[j]); - } + for (j = 0; j < this._bfAdd.length; j++) { + ele.classList.remove(this._bfAdd[j]); } - } else { - // normal direction - 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]); - } + for (j = 0; j < this._bfRmv.length; j++) { + ele.classList.add(this._bfRmv[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]); + } + } } } diff --git a/ionic/components/app/util.scss b/ionic/components/app/util.scss index c8544fa6cb..4037c59871 100644 --- a/ionic/components/app/util.scss +++ b/ionic/components/app/util.scss @@ -85,7 +85,9 @@ $content-padding: 10px !default; opacity: 0; z-index: $z-index-click-block; transform: translate3d(-9999px, 0px, 0px); - overflow: hidden; + + //background: red; + //opacity: .3; } .click-block-active { diff --git a/ionic/components/nav-bar/nav-bar.js b/ionic/components/nav-bar/nav-bar.js index 5e425e904d..0906bb6b13 100644 --- a/ionic/components/nav-bar/nav-bar.js +++ b/ionic/components/nav-bar/nav-bar.js @@ -72,10 +72,8 @@ export class Navbar { alignTitle() { // called after the navbar/title has had a moment to // finish rendering in their correct locations - const navbarEle = this._ele; - const innerTitleEle = this._innerTtEle || (this._innerTtEle = navbarEle.querySelector('.navbar-inner-title')); - const titleEle = this._ttEle || (this._ttEle = innerTitleEle.querySelector('ion-title')); + const titleEle = this._ttEle || (this._ttEle = navbarEle.querySelector('ion-title')); // don't bother if there's no title element if (!titleEle) return; @@ -87,9 +85,8 @@ export class Navbar { if (titleStyle.textAlign !== 'center') return; // get all the dimensions - const titleOffsetWidth = titleEle.offsetWidth; const titleOffsetLeft = titleEle.offsetLeft; - const titleOffsetRight = navbarEle.offsetWidth - (titleOffsetLeft + titleOffsetWidth); + const titleOffsetRight = navbarEle.offsetWidth - (titleOffsetLeft + titleEle.offsetWidth); let marginLeft = 0; let marginRight = 0; @@ -104,6 +101,7 @@ export class Navbar { if ((marginLeft || marginRight) && margin !== this._ttMargin) { // 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; } } diff --git a/ionic/components/nav-bar/nav-bar.scss b/ionic/components/nav-bar/nav-bar.scss index b14f66ffe9..9ad65d54ff 100644 --- a/ionic/components/nav-bar/nav-bar.scss +++ b/ionic/components/nav-bar/nav-bar.scss @@ -22,7 +22,7 @@ ion-navbar { justify-content: space-between; order: $flex-order-toolbar-top; - transform: translate3d(0px, -9999px, 0px); + transform: translate3d(100%, 0px, 0px); &.show-navbar { transform: translate3d(0px, 0px, 0px); } diff --git a/ionic/components/view/view-controller.js b/ionic/components/view/view-controller.js index 18a293f70d..971df6e53d 100644 --- a/ionic/components/view/view-controller.js +++ b/ionic/components/view/view-controller.js @@ -122,8 +122,6 @@ export class ViewController { opts.animate = (opts.animation !== 'none'); - this.transitionStart(opts); - // wait for the new item to complete setup enteringItem.stage(() => { @@ -144,6 +142,13 @@ export class ViewController { 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 transAnimation.play().then(() => { @@ -193,9 +198,6 @@ export class ViewController { enteringItem.shouldCache = false; enteringItem.willEnter(); - // start the transition - this.transitionStart({ animate: true }); - // wait for the new item to complete setup enteringItem.stage(() => { @@ -283,13 +285,6 @@ export class ViewController { return false; } - transitionStart(opts) { - if (opts.animate) { - // block possible clicks during transition - ClickBlock(true, 520); - } - } - transitionComplete() { this.items.forEach((item) => { diff --git a/ionic/transitions/ios-transition.js b/ionic/transitions/ios-transition.js index f3219db822..ed9cbd2401 100644 --- a/ionic/transitions/ios-transition.js +++ b/ionic/transitions/ios-transition.js @@ -63,11 +63,11 @@ class IOSTransition extends Transition { } else { // forward direction this.enteringView - .from(TRANSLATEX, '99%') + .from(TRANSLATEX, OFF_RIGHT) .from(OPACITY, 1); this.enteringTitle - .from(TRANSLATEX, '97%'); + .from(TRANSLATEX, OFF_RIGHT); this.leavingView .to(TRANSLATEX, OFF_LEFT) diff --git a/ionic/util/click-block.js b/ionic/util/click-block.js index b2e03c9524..b8cd01f9fb 100644 --- a/ionic/util/click-block.js +++ b/ionic/util/click-block.js @@ -1,15 +1,9 @@ - const CSS_CLICK_BLOCK = 'click-block-active'; const DEFAULT_EXPIRE = 330; let cbEle, fallbackTimerId; let isShowing = false; -function preventClick(ev) { - ev.preventDefault(); - ev.stopPropagation(); -} - function show(expire) { clearTimeout(fallbackTimerId); fallbackTimerId = setTimeout(hide, expire || DEFAULT_EXPIRE); @@ -23,10 +17,6 @@ function show(expire) { cbEle = document.createElement('div'); cbEle.className = 'click-block ' + CSS_CLICK_BLOCK; document.body.appendChild(cbEle); - cbEle.addEventListener('touchstart', preventClick); - cbEle.addEventListener('mousedown', preventClick); - cbEle.addEventListener('pointerdown', preventClick); - cbEle.addEventListener('MSPointerDown', preventClick); } } }