From 5392dbac13d3a0003fc27f84678969b7720acea8 Mon Sep 17 00:00:00 2001 From: Adam Bradley Date: Wed, 10 Dec 2014 17:41:25 -0600 Subject: [PATCH] refactor(transition): update android transitions --- js/angular/controller/navBarController.js | 4 +- js/angular/controller/navViewController.js | 14 ----- js/angular/controller/viewController.js | 1 + js/angular/service/ionicConfig.js | 51 ++++++++++------ js/angular/service/viewSwitcher.js | 29 +++------ scss/_bar.scss | 1 - scss/_transitions.scss | 70 +++++++++------------- 7 files changed, 72 insertions(+), 98 deletions(-) diff --git a/js/angular/controller/navBarController.js b/js/angular/controller/navBarController.js index fa117354e7..f6763833d3 100644 --- a/js/angular/controller/navBarController.js +++ b/js/angular/controller/navBarController.js @@ -244,14 +244,14 @@ function($scope, $element, $attrs, $compile, $timeout, $ionicNavBarDelegate, $io self.transition = function(enteringHeaderBar, leavingHeaderBar, viewData) { var enteringHeaderBarCtrl = enteringHeaderBar.controller(); - var transitionFn = $ionicConfig.transitions.navBar[viewData.transition]; + var transitionFn = $ionicConfig.transitions.navBar[viewData.navBarTransition] || $ionicConfig.transitions.navBar.none; var transitionId = viewData.transitionId; enteringHeaderBarCtrl.beforeEnter(viewData); var navBarTransition = transitionFn(enteringHeaderBar, leavingHeaderBar, viewData.direction, viewData.shouldAnimate && self.isInitialized); - ionic.DomUtil.cachedAttr($element, 'nav-bar-transition', viewData.transition); + ionic.DomUtil.cachedAttr($element, 'nav-bar-transition', viewData.navBarTransition); ionic.DomUtil.cachedAttr($element, 'nav-bar-direction', viewData.direction); if (navBarTransition.shouldAnimate) { diff --git a/js/angular/controller/navViewController.js b/js/angular/controller/navViewController.js index 35feccabf6..e3234645d8 100644 --- a/js/angular/controller/navViewController.js +++ b/js/angular/controller/navViewController.js @@ -16,7 +16,6 @@ function($scope, $element, $attrs, $compile, $controller, $ionicNavBarDelegate, var DATA_NO_CACHE = '$noCache'; var VIEW_STATUS_ACTIVE = 'active'; var VIEW_STATUS_CACHED = 'cached'; - var HISTORY_AFTER_ROOT = 'after-root'; var self = this; var direction; @@ -134,7 +133,6 @@ function($scope, $element, $attrs, $compile, $controller, $ionicNavBarDelegate, self.transitionEnd = function() { var viewElements = $element.children(); var x, l, viewElement; - var isHistoryRoot; for (x = 0, l = viewElements.length; x < l; x++) { viewElement = viewElements.eq(x); @@ -142,7 +140,6 @@ function($scope, $element, $attrs, $compile, $controller, $ionicNavBarDelegate, if (viewElement.data(DATA_ELE_IDENTIFIER) === activeEleId) { // this is the active element navViewAttr(viewElement, VIEW_STATUS_ACTIVE); - isHistoryRoot = $ionicViewSwitcher.isHistoryRoot(viewElement); } else if (navViewAttr(viewElement) === 'leaving' || navViewAttr(viewElement) === VIEW_STATUS_ACTIVE || navViewAttr(viewElement) === VIEW_STATUS_CACHED) { // this is a leaving element or was the former active element, or is an cached element @@ -155,17 +152,6 @@ function($scope, $element, $attrs, $compile, $controller, $ionicNavBarDelegate, } } } - - if (isHistoryRoot) { - viewElements = $element.children(); - for (x = 0, l = viewElements.length; x < l; x++) { - viewElement = viewElements.eq(x); - - if ($ionicViewSwitcher.isHistoryRoot(viewElement) && navViewAttr(viewElement) !== VIEW_STATUS_ACTIVE) { - $ionicViewSwitcher.historyCursorAttr(viewElement, HISTORY_AFTER_ROOT); - } - } - } }; diff --git a/js/angular/controller/viewController.js b/js/angular/controller/viewController.js index ceec5af86a..8f17abbb87 100644 --- a/js/angular/controller/viewController.js +++ b/js/angular/controller/viewController.js @@ -55,6 +55,7 @@ function($scope, $element, $attrs, $compile, $rootScope, $ionicViewSwitcher) { title: viewTitle, direction: transData.direction, transition: transData.transition, + navBarTransition: transData.navBarTransition, transitionId: transData.transitionId, shouldAnimate: transData.shouldAnimate, enableBack: transData.enableBack, diff --git a/js/angular/service/ionicConfig.js b/js/angular/service/ionicConfig.js index 2366eeae33..d564f56f61 100644 --- a/js/angular/service/ionicConfig.js +++ b/js/angular/service/ionicConfig.js @@ -211,7 +211,8 @@ IonicModule navBar: { alignTitle: PLATFORM, positionPrimaryButtons: PLATFORM, - positionSecondaryButtons: PLATFORM + positionSecondaryButtons: PLATFORM, + transition: PLATFORM }, backButton: { icon: PLATFORM, @@ -247,7 +248,8 @@ IonicModule navBar: { alignTitle: 'center', positionPrimaryButtons: 'left', - positionSecondaryButtons: 'right' + positionSecondaryButtons: 'right', + transition: 'view' }, backButton: { @@ -294,7 +296,7 @@ IonicModule }, backButton: { - icon: 'ion-android-arrow-back', + icon: 'ion-arrow-left-c', text: false, previousTitleText: false }, @@ -405,30 +407,27 @@ IonicModule provider.transitions.views.android = function(enteringEle, leavingEle, direction, shouldAnimate) { shouldAnimate = shouldAnimate && (direction == 'forward' || direction == 'back'); - function setStyles(ele, opacity, y) { + function setStyles(ele, x) { var css = {}; css[ionic.CSS.TRANSITION_DURATION] = shouldAnimate ? '' : 0; - css.opacity = opacity; - css[ionic.CSS.TRANSFORM] = 'translate3d(0,' + y + 'px,0)'; + css[ionic.CSS.TRANSFORM] = 'translate3d(' + x + '%,0,0)'; ionic.DomUtil.cachedStyles(ele, css); } - var startX = Math.max(window.innerHeight, screen.height) * 0.15; - return { run: function(step) { if (direction == 'forward') { - setStyles(enteringEle, step, (1 - step) * startX); - setStyles(leavingEle, 1, 0); + setStyles(enteringEle, (1 - step) * 99); // starting at 98% prevents a flicker + setStyles(leavingEle, step * -100); } else if (direction == 'back') { - setStyles(enteringEle, 1, 0); - setStyles(leavingEle, (1 - step), step * startX); + setStyles(enteringEle, (1 - step) * -100); + setStyles(leavingEle, step * 100); } else { // swap, enter, exit - setStyles(enteringEle, 1, 0); - setStyles(leavingEle, 0, 0); + setStyles(enteringEle, 0); + setStyles(leavingEle, 0); } }, shouldAnimate: shouldAnimate @@ -436,9 +435,27 @@ IonicModule }; provider.transitions.navBar.android = function(enteringHeaderBar, leavingHeaderBar, direction, shouldAnimate) { - return provider.transitions.views.android(enteringHeaderBar.containerEle(), - leavingHeaderBar && leavingHeaderBar.containerEle(), - direction, shouldAnimate); + shouldAnimate = shouldAnimate && (direction == 'forward' || direction == 'back'); + + function setStyles(ctrl, opacity) { + if (!ctrl) return; + var css = {}; + css.opacity = opacity === 1 ? '' : opacity; + + ctrl.setCss('buttons-left', css); + ctrl.setCss('buttons-right', css); + ctrl.setCss('back-button', css); + ctrl.setCss('back-text', css); + ctrl.setCss('title', css); + } + + return { + run: function(step) { + setStyles(enteringHeaderBar.controller(), step); + setStyles(leavingHeaderBar && leavingHeaderBar.controller(), 1 - step); + }, + shouldAnimate: true + }; }; diff --git a/js/angular/service/viewSwitcher.js b/js/angular/service/viewSwitcher.js index f4566c6167..b49bcd5841 100644 --- a/js/angular/service/viewSwitcher.js +++ b/js/angular/service/viewSwitcher.js @@ -21,8 +21,6 @@ function($timeout, $document, $q, $ionicClickBlock, $ionicConfig, $ionicNavBarDe var DATA_FALLBACK_TIMER = '$fallbackTimer'; var NAV_VIEW_ATTR = 'nav-view'; var HISTORY_CURSOR_ATTR = 'history-cursor'; - var HISTORY_ROOT = 'root'; - var HISTORY_AFTER_ROOT = 'after-root'; var VIEW_STATUS_ACTIVE = 'active'; var VIEW_STATUS_CACHED = 'cached'; var VIEW_STATUS_STAGED = 'stage'; @@ -55,13 +53,15 @@ function($timeout, $document, $q, $ionicClickBlock, $ionicConfig, $ionicNavBarDe // 6) fallback value var state = viewState(viewLocals); - var transition = nextTransition || cachedAttr(enteringEle, 'view-transition') || state.viewTransition || $ionicConfig.views.transition() || 'ios'; + var viewTransition = nextTransition || cachedAttr(enteringEle, 'view-transition') || state.viewTransition || $ionicConfig.views.transition() || 'ios'; + var navBarTransition = $ionicConfig.navBar.transition(); direction = nextDirection || cachedAttr(enteringEle, 'view-direction') || state.viewDirection || direction || 'none'; return extend(getViewData(view), { - transition: transition, + transition: viewTransition, + navBarTransition: navBarTransition === 'view' ? viewTransition : navBarTransition, direction: direction, - shouldAnimate: (transition !== 'none' && direction !== 'none') + shouldAnimate: (viewTransition !== 'none' && direction !== 'none') }); } @@ -84,10 +84,6 @@ function($timeout, $document, $q, $ionicClickBlock, $ionicConfig, $ionicNavBarDe } } - function historyCursorAttr(ele, value) { - cachedAttr(ele, HISTORY_CURSOR_ATTR, value); - } - function destroyViewEle(ele) { // we found an element that should be removed // destroy its scope, then remove the element @@ -177,11 +173,9 @@ function($timeout, $document, $q, $ionicClickBlock, $ionicConfig, $ionicNavBarDe navViewAttr(enteringEle, VIEW_STATUS_STAGED); var enteringData = getTransitionData(viewLocals, enteringEle, registerData.direction, enteringView); - var transitionFn = $ionicConfig.transitions.views[enteringData.transition]; + var transitionFn = $ionicConfig.transitions.views[enteringData.transition] || $ionicConfig.transitions.views.none; transitionFn(enteringEle, null, enteringData.direction, true).run(0); - historyCursorAttr(enteringEle, registerData.isHistoryRoot ? HISTORY_ROOT : HISTORY_AFTER_ROOT); - // if the current state has cache:false // or the element has cache-view="false" attribute if (viewState(viewLocals).cache === false || viewState(viewLocals).cache === 'false' || enteringEle.attr('cache-view') == 'false') { @@ -221,7 +215,7 @@ function($timeout, $document, $q, $ionicClickBlock, $ionicConfig, $ionicNavBarDe switcher.emit('before', enteringData, leavingData); // 1) get the transition ready and see if it'll animate - var transitionFn = $ionicConfig.transitions.views[enteringData.transition]; + var transitionFn = $ionicConfig.transitions.views[enteringData.transition] || $ionicConfig.transitions.views.none; var viewTransition = transitionFn(enteringEle, leavingEle, enteringData.direction, enteringData.shouldAnimate); if (viewTransition.shouldAnimate) { @@ -234,10 +228,6 @@ function($timeout, $document, $q, $ionicClickBlock, $ionicConfig, $ionicNavBarDe // 3) stage entering element, opacity 0, no transition duration navViewAttr(enteringEle, VIEW_STATUS_STAGED); - if (enteringData.direction == 'swap') { - historyCursorAttr(enteringEle, HISTORY_ROOT); - } - // 4) place the elements in the correct step to begin viewTransition.run(0); @@ -405,12 +395,7 @@ function($timeout, $document, $q, $ionicClickBlock, $ionicConfig, $ionicNavBarDe navViewAttr(viewEle, isActiveAttr ? VIEW_STATUS_ACTIVE : VIEW_STATUS_CACHED); }, - isHistoryRoot: function(viewElement) { - return cachedAttr(viewElement, HISTORY_CURSOR_ATTR) === HISTORY_ROOT; - }, - getTransitionData: getTransitionData, - historyCursorAttr: historyCursorAttr, navViewAttr: navViewAttr, destroyViewEle: destroyViewEle diff --git a/scss/_bar.scss b/scss/_bar.scss index 5554ebecb7..e84b804800 100644 --- a/scss/_bar.scss +++ b/scss/_bar.scss @@ -211,7 +211,6 @@ padding: 0; white-space: nowrap; font-weight: 400; - @include transition-duration(0); } &.back-button.active, diff --git a/scss/_transitions.scss b/scss/_transitions.scss index 458ee7cbc0..91b1012a9e 100644 --- a/scss/_transitions.scss +++ b/scss/_transitions.scss @@ -68,6 +68,9 @@ $ios-transition-container-bg-color: #000 !default; } } + .back-button { + @include transition-duration(0); + } } @@ -75,25 +78,18 @@ $ios-transition-container-bg-color: #000 !default; // Android View Transitions // ------------------------------- -$android-transition-duration-entering: 300ms !default; -$android-transition-duration-leaving: 200ms !default; -$android-transition-timing-entering: cubic-bezier(0.4, 0.6, 0.2, 1) !default; -$android-transition-timing-leaving: cubic-bezier(0.4, 0, 1, 1) !default; +$android-transition-duration: 200ms !default; +$android-transition-timing-function: cubic-bezier(0.4, 0.6, 0.2, 1) !default; [nav-view-transition="android"] { [nav-view="entering"], [nav-view="leaving"] { - @include transition-duration( $android-transition-duration-entering ); - @include transition-timing-function( $android-transition-timing-entering ); - -webkit-transition-property: opacity, -webkit-transform; - transition-property: opacity, transform; - } - - [nav-view="leaving"] { - @include transition-duration( $android-transition-duration-leaving ); - @include transition-timing-function( $android-transition-timing-leaving ); + @include transition-duration( $android-transition-duration ); + @include transition-timing-function( $android-transition-timing-function ); + -webkit-transition-property: -webkit-transform; + transition-property: transform; } [nav-view="active"], @@ -107,18 +103,6 @@ $android-transition-timing-leaving: cubic-bezier(0.4, 0, 1, 1) !default z-index: $z-index-view-below; } - .tabs-top > .view-container > [history-cursor="after-root"] { - z-index: $z-index-tabs + 1; - } - - [history-cursor="after-root"] > .has-tabs-top { - top: $bar-height; - } - - .tabs-top.tabs-striped > .view-container { - position: static; - } - } @@ -128,27 +112,29 @@ $android-transition-timing-leaving: cubic-bezier(0.4, 0, 1, 1) !default [nav-bar-transition="android"] { - [nav-bar="entering"], - [nav-bar="leaving"] { - @include transition-duration( $android-transition-duration-entering ); - @include transition-timing-function( $android-transition-timing-entering ); - -webkit-transition-property: opacity, -webkit-transform; - transition-property: opacity, transform; - } - - [nav-bar="leaving"] { - @include transition-duration( $android-transition-duration-leaving ); - @include transition-timing-function( $android-transition-timing-leaving ); - } - - [nav-bar="cached"] { - display: none; + .title, + .buttons { + @include transition-duration( $android-transition-duration ); + @include transition-timing-function( $android-transition-timing-function ); + -webkit-transition-property: opacity; + transition-property: opacity; } [nav-bar="active"], - &[nav-bar-direction="forward"] [nav-bar="entering"], - &[nav-bar-direction="back"] [nav-bar="leaving"] { + [nav-bar="entering"] { z-index: $z-index-bar-above; + + .bar { + background: transparent; + } + } + + [nav-bar="cached"] { + display: block; + + .header-item { + display: none; + } } }