UNPKG

ionic-angular

Version:

[![Circle CI](https://circleci.com/gh/driftyco/ionic.svg?style=svg)](https://circleci.com/gh/driftyco/ionic)

244 lines (216 loc) 9.16 kB
/** * @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() {}, endDrag: function() {}, setCanScroll: function(canScroll) { var c = $element[0].querySelector('.scroll'); if (!c) { return; } var content = angular.element(c.parentElement); if (!content) { return; } // freeze our scroll container if we have one var scrollScope = content.scope(); scrollScope.scrollCtrl && scrollScope.scrollCtrl.freezeScrollShut(!canScroll); }, 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)'; }), setMarginLeftAndRight: ionic.animationFrameThrottle(function(amountLeft, amountRight) { amountLeft = amountLeft && parseInt(amountLeft, 10) || 0; amountRight = amountRight && parseInt(amountRight, 10) || 0; var amount = amountLeft + amountRight; if (amount > 0) { $element[0].style[ionic.CSS.TRANSFORM] = 'translate3d(' + amountLeft + 'px,0,0)'; $element[0].style.width = ($window.innerWidth - amount) + 'px'; content.offsetX = amountLeft; } else { $element[0].style[ionic.CSS.TRANSFORM] = 'translate3d(0,0,0)'; $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 }; gestureOpts.prevent_default_directions = ['left', 'right']; 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); }); } } }; }]);