From 4ee22dd8189ace99cbcb31e5a86c53e60fee00c8 Mon Sep 17 00:00:00 2001 From: Adam Bradley Date: Thu, 13 Nov 2014 16:08:09 -0600 Subject: [PATCH] refactor($ionicConfig): separate transition JS --- js/angular/controller/navBarController.js | 7 +- js/angular/service/ionicConfig.js | 289 +++++++++----------- js/angular/service/viewSwitcher.js | 4 +- test/unit/angular/directive/navView.unit.js | 1 - 4 files changed, 140 insertions(+), 161 deletions(-) diff --git a/js/angular/controller/navBarController.js b/js/angular/controller/navBarController.js index 9858c28594..2e00cd245c 100644 --- a/js/angular/controller/navBarController.js +++ b/js/angular/controller/navBarController.js @@ -21,7 +21,6 @@ function($scope, $element, $attrs, $compile, $timeout, $ionicNavBarDelegate, $io var headerBars = []; var navElementHtml = {}; var isVisible = true; - var navBarConfig = $ionicConfig.navBar; var queuedTransitionStart, queuedTransitionEnd, latestTransitionId; $element.parent().data(DATA_NAV_BAR_CTRL, self); @@ -146,8 +145,8 @@ function($scope, $element, $attrs, $compile, $timeout, $ionicNavBarDelegate, $io if (!btnsEle) return; var appendToRight = (buttonType == 'rightButtons') || - (buttonType == SECONDARY_BUTTONS && navBarConfig.positionSecondaryButtons() != 'left') || - (buttonType == PRIMARY_BUTTONS && navBarConfig.positionPrimaryButtons() == 'right'); + (buttonType == SECONDARY_BUTTONS && $ionicConfig.navBar.positionSecondaryButtons() != 'left') || + (buttonType == PRIMARY_BUTTONS && $ionicConfig.navBar.positionPrimaryButtons() == 'right'); if (appendToRight) { // right side @@ -230,7 +229,7 @@ function($scope, $element, $attrs, $compile, $timeout, $ionicNavBarDelegate, $io self.transition = function(enteringHeaderBar, leavingHeaderBar, viewData) { var enteringHeaderBarCtrl = enteringHeaderBar.controller(); - var transitionFn = navBarConfig.transitionFn(); + var transitionFn = $ionicConfig.transitions.navBar[$ionicConfig.navBar.transition()]; var transitionId = viewData.transitionId; enteringHeaderBarCtrl.beforeEnter(viewData); diff --git a/js/angular/service/ionicConfig.js b/js/angular/service/ionicConfig.js index ca485bbea7..0ea97cdcc3 100644 --- a/js/angular/service/ionicConfig.js +++ b/js/angular/service/ionicConfig.js @@ -188,95 +188,14 @@ IonicModule views: { maxCache: 10, forwardCache: false, - transition: 'ios', - - transitionFn: function(enteringEle, leavingEle, direction, shouldAnimate) { - shouldAnimate = shouldAnimate && (direction == 'forward' || direction == 'back'); - - function setStyles(ele, opacity, x) { - var css = {}; - css[ionic.CSS.TRANSITION_DURATION] = shouldAnimate ? '' : 0; - css.opacity = opacity; - css[ionic.CSS.TRANSFORM] = 'translate3d(' + x + '%,0,0)'; - ionic.DomUtil.cachedStyles(ele, css); - } - - return { - run: function(step) { - if (direction == 'forward') { - setStyles(enteringEle, 1, (1 - step) * 99); // starting at 98% prevents a flicker - setStyles(leavingEle, (1 - 0.1 * step), step * -33); - - } else if (direction == 'back') { - setStyles(enteringEle, (1 - 0.1 * (1 - step)), (1 - step) * -33); - setStyles(leavingEle, 1, step * 100); - - } else { - // swap, enter, exit - setStyles(enteringEle, 1, 0); - setStyles(leavingEle, 0, 0); - } - }, - shouldAnimate: shouldAnimate - }; - } + transition: 'ios' }, navBar: { alignTitle: 'center', positionPrimaryButtons: 'left', positionSecondaryButtons: 'right', - transition: 'ios', - - transitionFn: function(enteringHeaderBar, leavingHeaderBar, direction, shouldAnimate) { - - shouldAnimate = shouldAnimate && (direction == 'forward' || direction == 'back'); - - function setStyles(ctrl, opacity, titleX, backTextX) { - var css = {}; - css[ionic.CSS.TRANSITION_DURATION] = shouldAnimate ? '' : 0; - css.opacity = opacity; - - ctrl.setCss('buttons-left', css); - ctrl.setCss('buttons-right', css); - ctrl.setCss('back-button', css); - - css[ionic.CSS.TRANSFORM] = 'translate3d(' + backTextX + 'px,0,0)'; - ctrl.setCss('back-text', css); - - css[ionic.CSS.TRANSFORM] = 'translate3d(' + titleX + 'px,0,0)'; - ctrl.setCss('title', css); - } - - function enter(ctrlA, ctrlB, step) { - if (!ctrlA) return; - var titleX = (ctrlA.titleTextX() + ctrlA.titleWidth()) * (1 - step); - var backTextX = (ctrlB && (ctrlB.titleTextX() - ctrlA.backButtonTextLeft()) * (1 - step)) || 0; - setStyles(ctrlA, step, titleX, backTextX); - } - - function leave(ctrlA, ctrlB, step) { - if (!ctrlA) return; - var titleX = (-(ctrlA.titleTextX() - ctrlB.backButtonTextLeft()) - (ctrlA.titleLeftRight())) * step; - setStyles(ctrlA, 1 - step, titleX, 0); - } - - return { - run: function(step) { - var enteringHeaderCtrl = enteringHeaderBar.controller(); - var leavingHeaderCtrl = leavingHeaderBar && leavingHeaderBar.controller(); - if (direction == 'back') { - leave(enteringHeaderCtrl, leavingHeaderCtrl, 1 - step); - enter(leavingHeaderCtrl, enteringHeaderCtrl, 1 - step); - } else { - enter(enteringHeaderCtrl, leavingHeaderCtrl, step); - leave(leavingHeaderCtrl, enteringHeaderCtrl, step); - } - }, - shouldAnimate: shouldAnimate - }; - } - + transition: 'ios' }, backButton: { @@ -309,83 +228,14 @@ IonicModule setPlatformConfig('android', { views: { - transition: 'android', - - transitionFn: function(enteringEle, leavingEle, direction, shouldAnimate) { - shouldAnimate = shouldAnimate && (direction == 'forward' || direction == 'back'); - - function setStyles(ele, opacity, y) { - var css = {}; - css[ionic.CSS.TRANSITION_DURATION] = shouldAnimate ? '' : 0; - css.opacity = opacity; - css[ionic.CSS.TRANSFORM] = 'translate3d(0,' + y + 'px,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); - - } else if (direction == 'back') { - setStyles(enteringEle, 1, 0); - setStyles(leavingEle, (1 - step), step * startX); - - } else { - // swap, enter, exit - setStyles(enteringEle, 1, 0); - setStyles(leavingEle, 0, 0); - } - }, - shouldAnimate: shouldAnimate - }; - } + transition: 'android' }, navBar: { alignTitle: 'left', positionPrimaryButtons: 'right', positionSecondaryButtons: 'right', - transition: 'android', - - transitionFn: function(enteringHeaderBar, leavingHeaderBar, direction, shouldAnimate) { - shouldAnimate = shouldAnimate && (direction == 'forward' || direction == 'back'); - - function setStyles(ele, opacity, y) { - var css = {}; - css[ionic.CSS.TRANSITION_DURATION] = shouldAnimate ? '' : 0; - css.opacity = opacity; - css[ionic.CSS.TRANSFORM] = 'translate3d(0,' + y + 'px,0)'; - ionic.DomUtil.cachedStyles(ele, css); - } - - var startX = Math.max(window.innerHeight, screen.height) * 0.15; - - return { - run: function(step) { - var enteringEle = enteringHeaderBar.containerEle(); - var leavingEle = leavingHeaderBar && leavingHeaderBar.containerEle(); - - if (direction == 'forward') { - setStyles(enteringEle, step, (1 - step) * startX, 10); - setStyles(leavingEle, 1, 0, 9); - - } else if (direction == 'back') { - setStyles(enteringEle, 1, 0, 9); - setStyles(leavingEle, (1 - step), step * startX, 10); - - } else { - // swap, enter, exit - setStyles(enteringEle, 1, 0, 9); - setStyles(leavingEle, 0, 0, 10); - } - }, - shouldAnimate: shouldAnimate - }; - } + transition: 'android' }, backButton: { @@ -402,6 +252,137 @@ IonicModule }); + provider.transitions = { + views: {}, + navBar: {} + }; + + + // iOS Transitions + // ----------------------- + provider.transitions.views.ios = function(enteringEle, leavingEle, direction, shouldAnimate) { + shouldAnimate = shouldAnimate && (direction == 'forward' || direction == 'back'); + + function setStyles(ele, opacity, x) { + var css = {}; + css[ionic.CSS.TRANSITION_DURATION] = shouldAnimate ? '' : 0; + css.opacity = opacity; + css[ionic.CSS.TRANSFORM] = 'translate3d(' + x + '%,0,0)'; + ionic.DomUtil.cachedStyles(ele, css); + } + + return { + run: function(step) { + if (direction == 'forward') { + setStyles(enteringEle, 1, (1 - step) * 99); // starting at 98% prevents a flicker + setStyles(leavingEle, (1 - 0.1 * step), step * -33); + + } else if (direction == 'back') { + setStyles(enteringEle, (1 - 0.1 * (1 - step)), (1 - step) * -33); + setStyles(leavingEle, 1, step * 100); + + } else { + // swap, enter, exit + setStyles(enteringEle, 1, 0); + setStyles(leavingEle, 0, 0); + } + }, + shouldAnimate: shouldAnimate + }; + }; + + provider.transitions.navBar.ios = function(enteringHeaderBar, leavingHeaderBar, direction, shouldAnimate) { + shouldAnimate = shouldAnimate && (direction == 'forward' || direction == 'back'); + + function setStyles(ctrl, opacity, titleX, backTextX) { + var css = {}; + css[ionic.CSS.TRANSITION_DURATION] = shouldAnimate ? '' : 0; + css.opacity = opacity; + + ctrl.setCss('buttons-left', css); + ctrl.setCss('buttons-right', css); + ctrl.setCss('back-button', css); + + css[ionic.CSS.TRANSFORM] = 'translate3d(' + backTextX + 'px,0,0)'; + ctrl.setCss('back-text', css); + + css[ionic.CSS.TRANSFORM] = 'translate3d(' + titleX + 'px,0,0)'; + ctrl.setCss('title', css); + } + + function enter(ctrlA, ctrlB, step) { + if (!ctrlA) return; + var titleX = (ctrlA.titleTextX() + ctrlA.titleWidth()) * (1 - step); + var backTextX = (ctrlB && (ctrlB.titleTextX() - ctrlA.backButtonTextLeft()) * (1 - step)) || 0; + setStyles(ctrlA, step, titleX, backTextX); + } + + function leave(ctrlA, ctrlB, step) { + if (!ctrlA) return; + var titleX = (-(ctrlA.titleTextX() - ctrlB.backButtonTextLeft()) - (ctrlA.titleLeftRight())) * step; + setStyles(ctrlA, 1 - step, titleX, 0); + } + + return { + run: function(step) { + var enteringHeaderCtrl = enteringHeaderBar.controller(); + var leavingHeaderCtrl = leavingHeaderBar && leavingHeaderBar.controller(); + if (direction == 'back') { + leave(enteringHeaderCtrl, leavingHeaderCtrl, 1 - step); + enter(leavingHeaderCtrl, enteringHeaderCtrl, 1 - step); + } else { + enter(enteringHeaderCtrl, leavingHeaderCtrl, step); + leave(leavingHeaderCtrl, enteringHeaderCtrl, step); + } + }, + shouldAnimate: shouldAnimate + }; + }; + + + // Android Transitions + // ----------------------- + + provider.transitions.views.android = function(enteringEle, leavingEle, direction, shouldAnimate) { + shouldAnimate = shouldAnimate && (direction == 'forward' || direction == 'back'); + + function setStyles(ele, opacity, y) { + var css = {}; + css[ionic.CSS.TRANSITION_DURATION] = shouldAnimate ? '' : 0; + css.opacity = opacity; + css[ionic.CSS.TRANSFORM] = 'translate3d(0,' + y + 'px,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); + + } else if (direction == 'back') { + setStyles(enteringEle, 1, 0); + setStyles(leavingEle, (1 - step), step * startX); + + } else { + // swap, enter, exit + setStyles(enteringEle, 1, 0); + setStyles(leavingEle, 0, 0); + } + }, + shouldAnimate: shouldAnimate + }; + }; + + provider.transitions.navBar.android = function(enteringHeaderBar, leavingHeaderBar, direction, shouldAnimate) { + return provider.transitions.views.android(enteringHeaderBar.containerEle(), + leavingHeaderBar && leavingHeaderBar.containerEle(), + direction, shouldAnimate); + }; + + // private: used to set platform configs function setPlatformConfig(platformName, platformConfigs) { configProperties.platform[platformName] = platformConfigs; diff --git a/js/angular/service/viewSwitcher.js b/js/angular/service/viewSwitcher.js index 914aeb5303..01439853d4 100644 --- a/js/angular/service/viewSwitcher.js +++ b/js/angular/service/viewSwitcher.js @@ -70,7 +70,7 @@ function($timeout, $compile, $controller, $document, $ionicClickBlock, $ionicCon var state = viewState(viewLocals); enteringView = enteringView || {}; - var transition = nextTransition || ionic.DomUtil.cachedAttr(enteringEle, 'view-transition') || state.viewTransition || $ionicConfig.views.transition() || 'none'; + var transition = nextTransition || ionic.DomUtil.cachedAttr(enteringEle, 'view-transition') || state.viewTransition || $ionicConfig.views.transition() || 'ios'; direction = nextDirection || ionic.DomUtil.cachedAttr(enteringEle, 'view-direction') || state.viewDirection || direction || 'none'; var shouldAnimate = (transition !== 'none' && direction !== 'none'); @@ -208,7 +208,7 @@ function($timeout, $compile, $controller, $document, $ionicClickBlock, $ionicCon switcher.emit('before', transData); // 1) get the transition ready and see if it'll animate - var transitionFn = $ionicConfig.views.transitionFn(); + var transitionFn = $ionicConfig.transitions.views[$ionicConfig.views.transition()]; var viewTransition = transitionFn(enteringEle, leavingEle, direction, transData.shouldAnimate); if (viewTransition.shouldAnimate) { diff --git a/test/unit/angular/directive/navView.unit.js b/test/unit/angular/directive/navView.unit.js index b7425d8fec..3c4d4ce56d 100644 --- a/test/unit/angular/directive/navView.unit.js +++ b/test/unit/angular/directive/navView.unit.js @@ -138,7 +138,6 @@ describe('Ionic nav-view', function() { elem = angular.element('
'); ionic.Platform.setPlatform('ios'); - $ionicConfig.views.transition('none'); $ionicConfig.views.maxCache(30); $ionicConfig.views.forwardCache(false); ionic.requestAnimationFrame = function(cb){cb()};