mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
209 lines
7.5 KiB
JavaScript
209 lines
7.5 KiB
JavaScript
/**
|
|
* @ngdoc directive
|
|
* @name ionSideMenuContent
|
|
* @module ionic
|
|
* @restrict E
|
|
* @parent ionic.directive:ionSideMenus
|
|
*
|
|
* @description
|
|
* A container for the main visible content, sibling to one or more
|
|
* {@link ionic.directive:ionSideMenu} directives.
|
|
*
|
|
* @usage
|
|
* ```html
|
|
* <ion-side-menu-content
|
|
* edge-drag-threshold="true"
|
|
* drag-content="true">
|
|
* </ion-side-menu-content>
|
|
* ```
|
|
* For a complete side menu example, see the
|
|
* {@link ionic.directive:ionSideMenus} documentation.
|
|
*
|
|
* @param {boolean=} drag-content Whether the content can be dragged. Default true.
|
|
* @param {boolean|number=} edge-drag-threshold Whether the content drag can only start if it is below a certain threshold distance from the edge of the screen. Default false. Accepts three types of values:
|
|
* - If a non-zero number is given, that many pixels is used as the maximum allowed distance from the edge that starts dragging the side menu.
|
|
* - If true is given, the default number of pixels (25) is used as the maximum allowed distance.
|
|
* - If false or 0 is given, the edge drag threshold is disabled, and dragging from anywhere on the content is allowed.
|
|
*
|
|
*/
|
|
IonicModule
|
|
.directive('ionSideMenuContent', [
|
|
'$timeout',
|
|
'$ionicGesture',
|
|
'$window',
|
|
function($timeout, $ionicGesture, $window) {
|
|
|
|
return {
|
|
restrict: 'EA', //DEPRECATED 'A'
|
|
require: '^ionSideMenus',
|
|
scope: true,
|
|
compile: function(element, attr) {
|
|
element.addClass('menu-content pane');
|
|
|
|
return { pre: prelink };
|
|
function prelink($scope, $element, $attr, sideMenuCtrl) {
|
|
var startCoord = null;
|
|
var primaryScrollAxis = null;
|
|
|
|
if (isDefined(attr.dragContent)) {
|
|
$scope.$watch(attr.dragContent, function(value) {
|
|
sideMenuCtrl.canDragContent(value);
|
|
});
|
|
} else {
|
|
sideMenuCtrl.canDragContent(true);
|
|
}
|
|
|
|
if (isDefined(attr.edgeDragThreshold)) {
|
|
$scope.$watch(attr.edgeDragThreshold, function(value) {
|
|
sideMenuCtrl.edgeDragThreshold(value);
|
|
});
|
|
}
|
|
|
|
// Listen for taps on the content to close the menu
|
|
function onContentTap(gestureEvt) {
|
|
if (sideMenuCtrl.getOpenAmount() !== 0) {
|
|
sideMenuCtrl.close();
|
|
gestureEvt.gesture.srcEvent.preventDefault();
|
|
startCoord = null;
|
|
primaryScrollAxis = null;
|
|
} else if (!startCoord) {
|
|
startCoord = ionic.tap.pointerCoord(gestureEvt.gesture.srcEvent);
|
|
}
|
|
}
|
|
|
|
function onDragX(e) {
|
|
if (!sideMenuCtrl.isDraggableTarget(e)) return;
|
|
|
|
if (getPrimaryScrollAxis(e) == 'x') {
|
|
sideMenuCtrl._handleDrag(e);
|
|
e.gesture.srcEvent.preventDefault();
|
|
}
|
|
}
|
|
|
|
function onDragY(e) {
|
|
if (getPrimaryScrollAxis(e) == 'x') {
|
|
e.gesture.srcEvent.preventDefault();
|
|
}
|
|
}
|
|
|
|
function onDragRelease(e) {
|
|
sideMenuCtrl._endDrag(e);
|
|
startCoord = null;
|
|
primaryScrollAxis = null;
|
|
}
|
|
|
|
function getPrimaryScrollAxis(gestureEvt) {
|
|
// gets whether the user is primarily scrolling on the X or Y
|
|
// If a majority of the drag has been on the Y since the start of
|
|
// the drag, but the X has moved a little bit, it's still a Y drag
|
|
|
|
if (primaryScrollAxis) {
|
|
// we already figured out which way they're scrolling
|
|
return primaryScrollAxis;
|
|
}
|
|
|
|
if (gestureEvt && gestureEvt.gesture) {
|
|
|
|
if (!startCoord) {
|
|
// get the starting point
|
|
startCoord = ionic.tap.pointerCoord(gestureEvt.gesture.srcEvent);
|
|
|
|
} else {
|
|
// we already have a starting point, figure out which direction they're going
|
|
var endCoord = ionic.tap.pointerCoord(gestureEvt.gesture.srcEvent);
|
|
|
|
var xDistance = Math.abs(endCoord.x - startCoord.x);
|
|
var yDistance = Math.abs(endCoord.y - startCoord.y);
|
|
|
|
var scrollAxis = (xDistance < yDistance ? 'y' : 'x');
|
|
|
|
if (Math.max(xDistance, yDistance) > 30) {
|
|
// ok, we pretty much know which way they're going
|
|
// let's lock it in
|
|
primaryScrollAxis = scrollAxis;
|
|
}
|
|
|
|
return scrollAxis;
|
|
}
|
|
}
|
|
return 'y';
|
|
}
|
|
|
|
var content = {
|
|
element: element[0],
|
|
onDrag: function(e) {},
|
|
endDrag: function(e) {},
|
|
getTranslateX: function() {
|
|
return $scope.sideMenuContentTranslateX || 0;
|
|
},
|
|
setTranslateX: ionic.animationFrameThrottle(function(amount) {
|
|
var xTransform = content.offsetX + amount;
|
|
$element[0].style[ionic.CSS.TRANSFORM] = 'translate3d(' + xTransform + 'px,0,0)';
|
|
$timeout(function() {
|
|
$scope.sideMenuContentTranslateX = amount;
|
|
});
|
|
}),
|
|
setMarginLeft: ionic.animationFrameThrottle(function(amount) {
|
|
if (amount) {
|
|
amount = parseInt(amount, 10);
|
|
$element[0].style[ionic.CSS.TRANSFORM] = 'translate3d(' + amount + 'px,0,0)';
|
|
$element[0].style.width = ($window.innerWidth - amount) + 'px';
|
|
content.offsetX = amount;
|
|
} else {
|
|
$element[0].style[ionic.CSS.TRANSFORM] = 'translate3d(0,0,0)';
|
|
$element[0].style.width = '';
|
|
content.offsetX = 0;
|
|
}
|
|
}),
|
|
setMarginRight: ionic.animationFrameThrottle(function(amount) {
|
|
if (amount) {
|
|
amount = parseInt(amount, 10);
|
|
$element[0].style.width = ($window.innerWidth - amount) + 'px';
|
|
content.offsetX = amount;
|
|
} else {
|
|
$element[0].style.width = '';
|
|
content.offsetX = 0;
|
|
}
|
|
// reset incase left gets grabby
|
|
$element[0].style[ionic.CSS.TRANSFORM] = 'translate3d(0,0,0)';
|
|
}),
|
|
enableAnimation: function() {
|
|
$scope.animationEnabled = true;
|
|
$element[0].classList.add('menu-animated');
|
|
},
|
|
disableAnimation: function() {
|
|
$scope.animationEnabled = false;
|
|
$element[0].classList.remove('menu-animated');
|
|
},
|
|
offsetX: 0
|
|
};
|
|
|
|
sideMenuCtrl.setContent(content);
|
|
|
|
// add gesture handlers
|
|
var gestureOpts = { stop_browser_behavior: false };
|
|
var contentTapGesture = $ionicGesture.on('tap', onContentTap, $element, gestureOpts);
|
|
var dragRightGesture = $ionicGesture.on('dragright', onDragX, $element, gestureOpts);
|
|
var dragLeftGesture = $ionicGesture.on('dragleft', onDragX, $element, gestureOpts);
|
|
var dragUpGesture = $ionicGesture.on('dragup', onDragY, $element, gestureOpts);
|
|
var dragDownGesture = $ionicGesture.on('dragdown', onDragY, $element, gestureOpts);
|
|
var releaseGesture = $ionicGesture.on('release', onDragRelease, $element, gestureOpts);
|
|
|
|
// Cleanup
|
|
$scope.$on('$destroy', function() {
|
|
if (content) {
|
|
content.element = null;
|
|
content = null;
|
|
}
|
|
$ionicGesture.off(dragLeftGesture, 'dragleft', onDragX);
|
|
$ionicGesture.off(dragRightGesture, 'dragright', onDragX);
|
|
$ionicGesture.off(dragUpGesture, 'dragup', onDragY);
|
|
$ionicGesture.off(dragDownGesture, 'dragdown', onDragY);
|
|
$ionicGesture.off(releaseGesture, 'release', onDragRelease);
|
|
$ionicGesture.off(contentTapGesture, 'tap', onContentTap);
|
|
});
|
|
}
|
|
}
|
|
};
|
|
}]);
|