Side menu content scoping fix

This commit is contained in:
Max Lynch
2013-10-04 10:16:50 -05:00
parent 48c716af1e
commit 1212945df8
5 changed files with 147 additions and 104 deletions

56
dist/ionic-angular.js vendored
View File

@ -165,33 +165,6 @@ angular.module('ionic.ui.sideMenu', [])
bringUp: function() { bringUp: function() {
$scope.rightZIndex = 0; $scope.rightZIndex = 0;
} }
},
content: {
onDrag: function(e) {},
endDrag: function(e) {},
getTranslateX: function() {
/*
var r = /translate3d\((-?.+)px/;
var d = r.exec(this.el.style.webkitTransform);
if(d && d.length > 0) {
return parseFloat(d[1]);
}
*/
return $scope.contentTranslateX || 0;
},
setTranslateX: function(amount) {
$scope.contentTranslateX = amount;
$scope.$apply();
},
enableAnimation: function() {
//this.el.classList.add(this.animateClass);
$scope.animationEnabled = true;
},
disableAnimation: function() {
//this.el.classList.remove(this.animateClass);
$scope.animationEnabled = false;
}
} }
}); });
@ -204,7 +177,7 @@ angular.module('ionic.ui.sideMenu', [])
controller: 'SideMenuCtrl', controller: 'SideMenuCtrl',
replace: true, replace: true,
transclude: true, transclude: true,
template: '<div class="view"><div ng-transclude></div></div>', template: '<div class="view" ng-transclude></div>',
} }
}) })
@ -212,6 +185,7 @@ angular.module('ionic.ui.sideMenu', [])
return { return {
restrict: 'CA', restrict: 'CA',
require: '^sideMenuCtrl', require: '^sideMenuCtrl',
scope: true,
compile: function(element, attr, transclude) { compile: function(element, attr, transclude) {
return function($scope, $element, $attr, sideMenuCtrl) { return function($scope, $element, $attr, sideMenuCtrl) {
window.ionic.onGesture('drag', function(e) { window.ionic.onGesture('drag', function(e) {
@ -222,17 +196,27 @@ angular.module('ionic.ui.sideMenu', [])
sideMenuCtrl._endDrag(e); sideMenuCtrl._endDrag(e);
}, $element[0]); }, $element[0]);
$scope.$watch('contentTranslateX', function(value) { sideMenuCtrl.setContent({
$element[0].style.webkitTransform = 'translate3d(' + value + 'px, 0, 0)'; onDrag: function(e) {},
}); endDrag: function(e) {},
getTranslateX: function() {
$scope.$watch('animationEnabled', function(isAnimationEnabled) { return $scope.contentTranslateX || 0;
if(isAnimationEnabled) { },
setTranslateX: function(amount) {
$scope.contentTranslateX = amount;
$scope.$apply();
$element[0].style.webkitTransform = 'translate3d(' + amount + 'px, 0, 0)';
},
enableAnimation: function() {
//this.el.classList.add(this.animateClass);
$scope.animationEnabled = true;
$element[0].classList.add('menu-animated'); $element[0].classList.add('menu-animated');
} else { },
disableAnimation: function() {
//this.el.classList.remove(this.animateClass);
$scope.animationEnabled = false;
$element[0].classList.remove('menu-animated'); $element[0].classList.remove('menu-animated');
} }
}); });
}; };
} }

103
dist/ionic.js vendored
View File

@ -2341,16 +2341,44 @@ ionic.controllers.NavController.prototype = {
; ;
(function(ionic) { (function(ionic) {
/**
* The SideMenuController is a controller with a left and/or right menu that
* can be slid out and toggled. Seen on many an app.
*
* The right or left menu can be disabled or not used at all, if desired.
*/
ionic.controllers.SideMenuController = function(options) { ionic.controllers.SideMenuController = function(options) {
var self = this; var self = this;
self.left = options.left; this.left = options.left;
self.right = options.right; this.right = options.right;
self.content = options.content; this.content = options.content;
self._rightShowing = false; this._rightShowing = false;
self._leftShowing = false; this._leftShowing = false;
this._isDragging = false;
if(this.content) {
this.content.onDrag = function(e) {
self._handleDrag(e);
};
this.content.endDrag = function(e) {
self._endDrag(e);
};
}
};
ionic.controllers.SideMenuController.prototype = {
/**
* Set the content view controller if not passed in the constructor options.
*
* @param {object} content
*/
setContent: function(content) {
var self = this;
this.content = content;
this.content.onDrag = function(e) { this.content.onDrag = function(e) {
self._handleDrag(e); self._handleDrag(e);
@ -2359,20 +2387,11 @@ ionic.controllers.NavController.prototype = {
this.content.endDrag = function(e) { this.content.endDrag = function(e) {
self._endDrag(e); self._endDrag(e);
}; };
},
/* /**
// Bind release and drag listeners * Toggle the left menu to open 100%
window.ion.onGesture('release', function(e) {
self._endDrag(e);
}, self.center);
window.ion.onGesture('drag', function(e) {
self._handleDrag(e);
}, self.center);
*/ */
};
ionic.controllers.SideMenuController.prototype = {
toggleLeft: function() { toggleLeft: function() {
var openAmount = this.getOpenAmount(); var openAmount = this.getOpenAmount();
if(openAmount > 0) { if(openAmount > 0) {
@ -2381,6 +2400,10 @@ ionic.controllers.NavController.prototype = {
this.openPercentage(100); this.openPercentage(100);
} }
}, },
/**
* Toggle the right menu to open 100%
*/
toggleRight: function() { toggleRight: function() {
var openAmount = this.getOpenAmount(); var openAmount = this.getOpenAmount();
if(openAmount < 0) { if(openAmount < 0) {
@ -2389,9 +2412,20 @@ ionic.controllers.NavController.prototype = {
this.openPercentage(-100); this.openPercentage(-100);
} }
}, },
/**
* @return {float} The amount the side menu is open, either positive or negative for left (positive), or right (negative)
*/
getOpenAmount: function() { getOpenAmount: function() {
return this.content.getTranslateX() || 0; return this.content.getTranslateX() || 0;
}, },
/**
* @return {float} The ratio of open amount over menu width. For example, a
* menu of width 100 open 50 pixels would be open 50% or a ratio of 0.5. Value is negative
* for right menu.
*/
getOpenRatio: function() { getOpenRatio: function() {
var amount = this.getOpenAmount(); var amount = this.getOpenAmount();
if(amount >= 0) { if(amount >= 0) {
@ -2399,9 +2433,20 @@ ionic.controllers.NavController.prototype = {
} }
return amount / this.right.width; return amount / this.right.width;
}, },
/**
* @return {float} The percentage of open amount over menu width. For example, a
* menu of width 100 open 50 pixels would be open 50%. Value is negative
* for right menu.
*/
getOpenPercentage: function() { getOpenPercentage: function() {
return this.getOpenRatio() * 100; return this.getOpenRatio() * 100;
}, },
/**
* Open the menu with a given percentage amount.
* @param {float} percentage The percentage (positive or negative for left/right) to open the menu.
*/
openPercentage: function(percentage) { openPercentage: function(percentage) {
var p = percentage / 100; var p = percentage / 100;
var maxLeft = this.left.width; var maxLeft = this.left.width;
@ -2412,6 +2457,12 @@ ionic.controllers.NavController.prototype = {
this.openAmount(maxRight * p); this.openAmount(maxRight * p);
} }
}, },
/**
* Open the menu the given pixel amount.
* @param {float} amount the pixel amount to open the menu. Positive value for left menu,
* negative value for right menu (only one menu will be visible at a time).
*/
openAmount: function(amount) { openAmount: function(amount) {
var maxLeft = this.left.width; var maxLeft = this.left.width;
var maxRight = this.right.width; var maxRight = this.right.width;
@ -2445,6 +2496,14 @@ ionic.controllers.NavController.prototype = {
this.left.pushDown(); this.left.pushDown();
} }
}, },
/**
* Given an event object, find the final resting position of this side
* menu. For example, if the user "throws" the content to the right and
* releases the touch, the left menu should snap open (animated, of course).
*
* @param {Event} e the gesture event to use for snapping
*/
snapToRest: function(e) { snapToRest: function(e) {
// We want to animate at the end of this // We want to animate at the end of this
this.content.enableAnimation(); this.content.enableAnimation();
@ -2501,9 +2560,13 @@ ionic.controllers.NavController.prototype = {
this.openPercentage(0); this.openPercentage(0);
} }
}, },
// End a drag with the given event
_endDrag: function(e) { _endDrag: function(e) {
this.snapToRest(e); this.snapToRest(e);
}, },
// Initialize a drag with the given event
_initDrag: function(e) { _initDrag: function(e) {
this.content.disableAnimation(); this.content.disableAnimation();
this._isDragging = true; this._isDragging = true;
@ -2511,6 +2574,8 @@ ionic.controllers.NavController.prototype = {
this._offsetX = 0; this._offsetX = 0;
this._lastX = 0; this._lastX = 0;
}, },
// Handle a drag event
_handleDrag: function(e) { _handleDrag: function(e) {
if(!this._isDragging) { if(!this._isDragging) {
this._initDrag(e); this._initDrag(e);
@ -2520,7 +2585,7 @@ ionic.controllers.NavController.prototype = {
this._offsetX = this.getOpenAmount(); this._offsetX = this.getOpenAmount();
} }
//console.log('Dragging page', this._startX, this._lastX, this._offsetX, e);
var newX = this._offsetX + (this._lastX - this._startX); var newX = this._offsetX + (this._lastX - this._startX);
this.openAmount(newX); this.openAmount(newX);

View File

@ -2,8 +2,6 @@ angular.module('ionic.todo', [
'ionic.todo.services', 'ionic.todo.services',
'ionic.todo.controllers', 'ionic.todo.controllers',
'ionic.service',
'ionic.ui.nav', 'ionic.ui.nav',
'ionic.ui.sideMenu', 'ionic.ui.sideMenu',

View File

@ -17,6 +17,7 @@
this._leftShowing = false; this._leftShowing = false;
this._isDragging = false; this._isDragging = false;
if(this.content) {
this.content.onDrag = function(e) { this.content.onDrag = function(e) {
self._handleDrag(e); self._handleDrag(e);
}; };
@ -24,6 +25,7 @@
this.content.endDrag = function(e) { this.content.endDrag = function(e) {
self._endDrag(e); self._endDrag(e);
}; };
}
}; };
ionic.controllers.SideMenuController.prototype = { ionic.controllers.SideMenuController.prototype = {
@ -33,7 +35,17 @@
* @param {object} content * @param {object} content
*/ */
setContent: function(content) { setContent: function(content) {
var self = this;
this.content = content; this.content = content;
this.content.onDrag = function(e) {
self._handleDrag(e);
};
this.content.endDrag = function(e) {
self._endDrag(e);
};
}, },
/** /**

View File

@ -25,33 +25,6 @@ angular.module('ionic.ui.sideMenu', [])
bringUp: function() { bringUp: function() {
$scope.rightZIndex = 0; $scope.rightZIndex = 0;
} }
},
content: {
onDrag: function(e) {},
endDrag: function(e) {},
getTranslateX: function() {
/*
var r = /translate3d\((-?.+)px/;
var d = r.exec(this.el.style.webkitTransform);
if(d && d.length > 0) {
return parseFloat(d[1]);
}
*/
return $scope.contentTranslateX || 0;
},
setTranslateX: function(amount) {
$scope.contentTranslateX = amount;
$scope.$apply();
},
enableAnimation: function() {
//this.el.classList.add(this.animateClass);
$scope.animationEnabled = true;
},
disableAnimation: function() {
//this.el.classList.remove(this.animateClass);
$scope.animationEnabled = false;
}
} }
}); });
@ -64,7 +37,7 @@ angular.module('ionic.ui.sideMenu', [])
controller: 'SideMenuCtrl', controller: 'SideMenuCtrl',
replace: true, replace: true,
transclude: true, transclude: true,
template: '<div class="view"><div ng-transclude></div></div>', template: '<div class="view" ng-transclude></div>',
} }
}) })
@ -72,6 +45,7 @@ angular.module('ionic.ui.sideMenu', [])
return { return {
restrict: 'CA', restrict: 'CA',
require: '^sideMenuCtrl', require: '^sideMenuCtrl',
scope: true,
compile: function(element, attr, transclude) { compile: function(element, attr, transclude) {
return function($scope, $element, $attr, sideMenuCtrl) { return function($scope, $element, $attr, sideMenuCtrl) {
window.ionic.onGesture('drag', function(e) { window.ionic.onGesture('drag', function(e) {
@ -82,17 +56,27 @@ angular.module('ionic.ui.sideMenu', [])
sideMenuCtrl._endDrag(e); sideMenuCtrl._endDrag(e);
}, $element[0]); }, $element[0]);
$scope.$watch('contentTranslateX', function(value) { sideMenuCtrl.setContent({
$element[0].style.webkitTransform = 'translate3d(' + value + 'px, 0, 0)'; onDrag: function(e) {},
}); endDrag: function(e) {},
getTranslateX: function() {
$scope.$watch('animationEnabled', function(isAnimationEnabled) { return $scope.contentTranslateX || 0;
if(isAnimationEnabled) { },
setTranslateX: function(amount) {
$scope.contentTranslateX = amount;
$scope.$apply();
$element[0].style.webkitTransform = 'translate3d(' + amount + 'px, 0, 0)';
},
enableAnimation: function() {
//this.el.classList.add(this.animateClass);
$scope.animationEnabled = true;
$element[0].classList.add('menu-animated'); $element[0].classList.add('menu-animated');
} else { },
disableAnimation: function() {
//this.el.classList.remove(this.animateClass);
$scope.animationEnabled = false;
$element[0].classList.remove('menu-animated'); $element[0].classList.remove('menu-animated');
} }
}); });
}; };
} }