refactor($ionicConfig): separate transition JS

This commit is contained in:
Adam Bradley
2014-11-13 16:08:09 -06:00
parent e3f51ca8d0
commit 4ee22dd818
4 changed files with 140 additions and 161 deletions

View File

@@ -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);

View File

@@ -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;

View File

@@ -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) {

View File

@@ -138,7 +138,6 @@ describe('Ionic nav-view', function() {
elem = angular.element('<div>');
ionic.Platform.setPlatform('ios');
$ionicConfig.views.transition('none');
$ionicConfig.views.maxCache(30);
$ionicConfig.views.forwardCache(false);
ionic.requestAnimationFrame = function(cb){cb()};