Skip to content

Instantly share code, notes, and snippets.

@TheDarkCode
Created February 6, 2016 04:02
Show Gist options
  • Save TheDarkCode/4359285248dc2ba11cd5 to your computer and use it in GitHub Desktop.
Save TheDarkCode/4359285248dc2ba11cd5 to your computer and use it in GitHub Desktop.
ion-spaced-menu
<html ng-app="ionicApp">
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title>Side Menus</title>
<link href="//code.ionicframework.com/nightly/css/ionic.css" rel="stylesheet">
<script src="//code.ionicframework.com/nightly/js/ionic.bundle.js"></script>
</head>
<body ng-controller="MainCtrl">
<ion-nav-view></ion-nav-view>
<script id="templates/event-menu.html" type="text/ng-template">
<ion-side-menus enable-menu-with-back-views="true" drag-content="true">
<ion-side-menu-content>
<ion-nav-bar class="bar-positive">
<ion-nav-back-button>
</ion-nav-back-button>
<ion-nav-buttons side="left">
<button class="button button-icon button-clear ion-navicon" menu-toggle="left">
</button>
</ion-nav-buttons>
</ion-nav-bar>
<ion-nav-view name="menuContent"></ion-nav-view>
</ion-side-menu-content>
<ion-side-menu side="left">
<ion-content class="menu-screen">
<!-- Close Button -->
<button class="button button-icon" menu-close style="position: absolute; right: 15px; top: 5px; font-size:40px; z-index:1; background: transparent;">
<i class="icon ion-ios-close-empty"></i>
</button>
<ul class="list" style="padding-top:55px;">
<!-- Note each link has the 'menu-close' attribute so the menu auto closes when clicking on one of these links -->
<a nav-clear href="#/event/check-in" class="item" menu-close>Check-in</a>
<a nav-clear href="#/event/attendees" class="item" menu-close>Attendees</a>
</ul>
</ion-content>
</ion-side-menu>
<ion-side-menu side="right">
<ion-content class="menu-screen">
<!-- Close Button -->
<button class="button button-icon" menu-close style="position: absolute; right: 15px; top: 5px; font-size:40px; z-index:1; background: transparent;">
<i class="icon ion-ios-close-empty"></i>
</button>
<ul class="list" style="padding-top:55px;">
<!-- Note each link has the 'menu-close' attribute so the menu auto closes when clicking on one of these links -->
<a nav-clear href="#/event/check-in" class="item" menu-close>Check-in</a>
<a nav-clear href="#/event/attendees" class="item" menu-close>Attendees</a>
</ul>
</ion-content>
</ion-side-menu>
</ion-side-menus>
</script>
<script id="templates/home.html" type="text/ng-template">
<ion-view view-title="Welcome">
<ion-content class="padding text-center">
<h2>ion-spaced-menu demo</h2>
<a href="https://github.com/TheDarkCode/ion-spaced-menu"><h4>https://github.com/TheDarkCode/ion-spaced-menu</h6></a>
<p>Swipe to the right to reveal the left menu.</p>
<p>(On desktop click and drag from left to right)</p>
</ion-content>
</ion-view>
</script>
<script id="templates/check-in.html" type="text/ng-template">
<ion-view view-title="Event Check-in">
<ion-content>
<form class="list" ng-show="showForm">
<div class="item item-divider">
Attendee Info
</div>
<label class="item item-input">
<input type="text" placeholder="First Name" ng-model="attendee.firstname">
</label>
<label class="item item-input">
<input type="text" placeholder="Last Name" ng-model="attendee.lastname">
</label>
<div class="item item-divider">
Shirt Size
</div>
<ion-radio ng-repeat="shirtSize in shirtSizes"
ng-value="shirtSize.value"
ng-model="attendee.shirtSize">
{{ shirtSize.text }}
</ion-radio>
<div class="item item-divider">
Lunch
</div>
<ion-toggle ng-model="attendee.vegetarian">
Vegetarian
</ion-toggle>
<div class="padding">
<button class="button button-block" ng-click="submit()">Checkin</button>
</div>
</form>
<div ng-hide="showForm">
<pre ng-bind="attendee | json"></pre>
<a href="#/event/attendees">View attendees</a>
</div>
</ion-content>
</ion-view>
</script>
<script id="templates/attendees.html" type="text/ng-template">
<ion-view view-title="Event Attendees">
<ion-content>
<div class="list">
<ion-toggle ng-repeat="attendee in attendees | orderBy:'firstname' | orderBy:'lastname'"
ng-model="attendee.arrived"
ng-change="arrivedChange(attendee)">
{{ attendee.firstname }}
{{ attendee.lastname }}
</ion-toggle>
<div class="item item-divider">
Activity
</div>
<div class="item" ng-repeat="msg in activity">
{{ msg }}
</div>
</div>
</ion-content>
</ion-view>
</script>
</body>
</html>
var app = angular.module('ionicApp', ['ionic', 'ion-spaced-menu'])
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('eventmenu', {
url: "/event",
abstract: true,
templateUrl: "templates/event-menu.html"
})
.state('eventmenu.home', {
url: "/home",
views: {
'menuContent' :{
templateUrl: "templates/home.html"
}
}
})
.state('eventmenu.checkin', {
url: "/check-in",
views: {
'menuContent' :{
templateUrl: "templates/check-in.html",
controller: "CheckinCtrl"
}
}
})
.state('eventmenu.attendees', {
url: "/attendees",
views: {
'menuContent' :{
templateUrl: "templates/attendees.html",
controller: "AttendeesCtrl"
}
}
})
$urlRouterProvider.otherwise("/event/home");
})
.controller('MainCtrl', function($scope, $ionicSideMenuDelegate) {
$scope.attendees = [
{ firstname: 'Nicolas', lastname: 'Cage' },
{ firstname: 'Jean-Claude', lastname: 'Van Damme' },
{ firstname: 'Keanu', lastname: 'Reeves' },
{ firstname: 'Steven', lastname: 'Seagal' }
];
$scope.toggleLeft = function() {
$ionicSideMenuDelegate.toggleLeft();
};
})
.controller('CheckinCtrl', function($scope) {
$scope.showForm = true;
$scope.shirtSizes = [
{ text: 'Large', value: 'L' },
{ text: 'Medium', value: 'M' },
{ text: 'Small', value: 'S' }
];
$scope.attendee = {};
$scope.submit = function() {
if(!$scope.attendee.firstname) {
alert('Info required');
return;
}
$scope.showForm = false;
$scope.attendees.push($scope.attendee);
};
})
.controller('AttendeesCtrl', function($scope) {
$scope.activity = [];
$scope.arrivedChange = function(attendee) {
var msg = attendee.firstname + ' ' + attendee.lastname;
msg += (!attendee.arrived ? ' has arrived, ' : ' just left, ');
msg += new Date().getMilliseconds();
$scope.activity.push(msg);
if($scope.activity.length > 3) {
$scope.activity.splice(0, 1);
}
};
});
var extend = angular.extend,
forEach = angular.forEach,
isDefined = angular.isDefined,
isNumber = angular.isNumber,
isString = angular.isString,
jqLite = angular.element,
PLATFORM_BACK_BUTTON_PRIORITY_VIEW = 100,
PLATFORM_BACK_BUTTON_PRIORITY_SIDE_MENU = 150,
PLATFORM_BACK_BUTTON_PRIORITY_MODAL = 200,
PLATFORM_BACK_BUTTON_PRIORITY_ACTION_SHEET = 300,
PLATFORM_BACK_BUTTON_PRIORITY_POPUP = 400,
PLATFORM_BACK_BUTTON_PRIORITY_LOADING = 500;
angular.module('ion-spaced-menu', [])
.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, isMenu) {
var xTransform = content.offsetX + amount - 30;
if (isMenu) {
if (xTransform < 0)
xTransform += 30;
var percentage = xTransform / 225,
scale;
if ((percentage * 0.7) <= 0) {
scale = 1;
//remove class active
var className = document.querySelector('.menu.menu-left').className;
document.querySelector('.menu.menu-left').className = className.replace(/ active/g, '')
var rightClassName = document.querySelector('.menu.menu-right').className;
document.querySelector('.menu.menu-right').className = rightClassName.replace(/ inactive/g, '');
} else {
scale = .7;
//add class active
if (document.querySelector('.menu.menu-left').className.indexOf('active') < 0)
document.querySelector('.menu.menu-left').className += ' active'
if (document.querySelector('.menu.menu-right').className.indexOf('inactive') < 0)
document.querySelector('.menu.menu-right').className += ' inactive'
}
$element[0].style[ionic.CSS.TRANSFORM] = 'translate3d(' + xTransform + 'px,0,0) scale(' + scale + ')';
} else
$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);
});
}
}
};
}
])
.controller('$ionicSideMenus', [
'$scope',
'$attrs',
'$ionicSideMenuDelegate',
'$ionicPlatform',
'$ionicBody',
'$ionicHistory',
function($scope, $attrs, $ionicSideMenuDelegate, $ionicPlatform, $ionicBody, $ionicHistory) {
var self = this;
var rightShowing, leftShowing, isDragging;
var startX, lastX, offsetX, isAsideExposed;
var enableMenuWithBackViews = true;
self.$scope = $scope;
self.initialize = function(options) {
self.left = options.left;
self.right = options.right;
self.setContent(options.content);
self.dragThresholdX = options.dragThresholdX || 10;
$ionicHistory.registerHistory(self.$scope);
};
/**
* Set the content view controller if not passed in the constructor options.
*
* @param {object} content
*/
self.setContent = function(content) {
if (content) {
self.content = content;
self.content.onDrag = function(e) {
self._handleDrag(e);
};
self.content.endDrag = function(e) {
self._endDrag(e);
};
}
};
self.isOpenLeft = function() {
return self.getOpenAmount() > 0;
};
self.isOpenRight = function() {
return self.getOpenAmount() < 0;
};
/**
* Toggle the left menu to open 100%
*/
self.toggleLeft = function(shouldOpen) {
if (isAsideExposed || !self.left.isEnabled) return;
var openAmount = self.getOpenAmount();
if (arguments.length === 0) {
shouldOpen = openAmount <= 0;
}
self.content.enableAnimation();
if (!shouldOpen) {
self.openPercentage(0);
} else {
self.openPercentage(100);
}
};
/**
* Toggle the right menu to open 100%
*/
self.toggleRight = function(shouldOpen) {
if (isAsideExposed || !self.right.isEnabled) return;
var openAmount = self.getOpenAmount();
if (arguments.length === 0) {
shouldOpen = openAmount >= 0;
}
self.content.enableAnimation();
if (!shouldOpen) {
self.openPercentage(0);
} else {
self.openPercentage(-100);
}
};
self.toggle = function(side) {
if (side == 'right') {
self.toggleRight();
} else {
self.toggleLeft();
}
};
/**
* Close all menus.
*/
self.close = function() {
self.openPercentage(0);
};
/**
* @return {float} The amount the side menu is open, either positive or negative for left (positive), or right (negative)
*/
self.getOpenAmount = function() {
return self.content && self.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.
*/
self.getOpenRatio = function() {
var amount = self.getOpenAmount();
if (amount >= 0) {
return amount / self.left.width;
}
return amount / self.right.width;
};
self.isOpen = function() {
return self.getOpenAmount() !== 0;
};
/**
* @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.
*/
self.getOpenPercentage = function() {
return self.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.
*/
self.openPercentage = function(percentage) {
var p = percentage / 100;
if (self.left && percentage >= 0) {
self.openAmount(self.left.width * p);
} else if (self.right && percentage < 0) {
var maxRight = self.right.width;
self.openAmount(self.right.width * p);
}
// add the CSS class "menu-open" if the percentage does not
// equal 0, otherwise remove the class from the body element
$ionicBody.enableClass((percentage !== 0), 'menu-open');
};
/**
* 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).
*/
self.openAmount = function(amount) {
var maxLeft = self.left && self.left.width || 0;
var maxRight = self.right && self.right.width || 0;
// Check if we can move to that side, depending if the left/right panel is enabled
if (!(self.left && self.left.isEnabled) && amount > 0) {
self.content.setTranslateX(0);
return;
}
if (!(self.right && self.right.isEnabled) && amount < 0) {
self.content.setTranslateX(0);
return;
}
if (leftShowing && amount > maxLeft) {
self.content.setTranslateX(maxLeft, 'menu');
return;
}
if (rightShowing && amount < -maxRight) {
self.content.setTranslateX(-maxRight, 'menu');
return;
}
self.content.setTranslateX(amount, 'menu');
if (amount >= 0) {
leftShowing = true;
rightShowing = false;
if (amount > 0) {
// Push the z-index of the right menu down
self.right && self.right.pushDown && self.right.pushDown();
// Bring the z-index of the left menu up
self.left && self.left.bringUp && self.left.bringUp();
}
} else {
rightShowing = true;
leftShowing = false;
// Bring the z-index of the right menu up
self.right && self.right.bringUp && self.right.bringUp();
// Push the z-index of the left menu down
self.left && self.left.pushDown && self.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
*/
self.snapToRest = function(e) {
// We want to animate at the end of this
self.content.enableAnimation();
isDragging = false;
// Check how much the panel is open after the drag, and
// what the drag velocity is
var ratio = self.getOpenRatio();
if (ratio === 0) {
// Just to be safe
self.openPercentage(0);
return;
}
var velocityThreshold = 0.3;
var velocityX = e.gesture.velocityX;
var direction = e.gesture.direction;
// Going right, less than half, too slow (snap back)
if (ratio > 0 && ratio < 0.5 && direction == 'right' && velocityX < velocityThreshold) {
self.openPercentage(0);
}
// Going left, more than half, too slow (snap back)
else if (ratio > 0.5 && direction == 'left' && velocityX < velocityThreshold) {
self.openPercentage(100);
}
// Going left, less than half, too slow (snap back)
else if (ratio < 0 && ratio > -0.5 && direction == 'left' && velocityX < velocityThreshold) {
self.openPercentage(0);
}
// Going right, more than half, too slow (snap back)
else if (ratio < 0.5 && direction == 'right' && velocityX < velocityThreshold) {
self.openPercentage(-100);
}
// Going right, more than half, or quickly (snap open)
else if (direction == 'right' && ratio >= 0 && (ratio >= 0.5 || velocityX > velocityThreshold)) {
self.openPercentage(100);
}
// Going left, more than half, or quickly (span open)
else if (direction == 'left' && ratio <= 0 && (ratio <= -0.5 || velocityX > velocityThreshold)) {
self.openPercentage(-100);
}
// Snap back for safety
else {
self.openPercentage(0);
}
};
self.enableMenuWithBackViews = function(val) {
if (arguments.length) {
enableMenuWithBackViews = !!val;
}
return enableMenuWithBackViews;
};
self.isAsideExposed = function() {
return !!isAsideExposed;
};
self.exposeAside = function(shouldExposeAside) {
if (!(self.left && self.left.isEnabled) && !(self.right && self.right.isEnabled)) return;
self.close();
isAsideExposed = shouldExposeAside;
if (self.left && self.left.isEnabled) {
// set the left marget width if it should be exposed
// otherwise set false so there's no left margin
self.content.setMarginLeft(isAsideExposed ? self.left.width : 0);
} else if (self.right && self.right.isEnabled) {
self.content.setMarginRight(isAsideExposed ? self.right.width : 0);
}
self.$scope.$emit('$ionicExposeAside', isAsideExposed);
};
self.activeAsideResizing = function(isResizing) {
$ionicBody.enableClass(isResizing, 'aside-resizing');
};
// End a drag with the given event
self._endDrag = function(e) {
if (isAsideExposed) return;
if (isDragging) {
self.snapToRest(e);
}
startX = null;
lastX = null;
offsetX = null;
};
// Handle a drag event
self._handleDrag = function(e) {
if (isAsideExposed) return;
// If we don't have start coords, grab and store them
if (!startX) {
startX = e.gesture.touches[0].pageX;
lastX = startX;
} else {
// Grab the current tap coords
lastX = e.gesture.touches[0].pageX;
}
// Calculate difference from the tap points
if (!isDragging && Math.abs(lastX - startX) > self.dragThresholdX) {
// if the difference is greater than threshold, start dragging using the current
// point as the starting point
startX = lastX;
isDragging = true;
// Initialize dragging
self.content.disableAnimation();
offsetX = self.getOpenAmount();
}
if (isDragging) {
self.openAmount(offsetX + (lastX - startX));
}
};
self.canDragContent = function(canDrag) {
if (arguments.length) {
$scope.dragContent = !!canDrag;
}
return $scope.dragContent;
};
self.edgeThreshold = 25;
self.edgeThresholdEnabled = false;
self.edgeDragThreshold = function(value) {
if (arguments.length) {
if (angular.isNumber(value) && value > 0) {
self.edgeThreshold = value;
self.edgeThresholdEnabled = true;
} else {
self.edgeThresholdEnabled = !!value;
}
}
return self.edgeThresholdEnabled;
};
self.isDraggableTarget = function(e) {
//Only restrict edge when sidemenu is closed and restriction is enabled
var shouldOnlyAllowEdgeDrag = self.edgeThresholdEnabled && !self.isOpen();
var startX = e.gesture.startEvent && e.gesture.startEvent.center &&
e.gesture.startEvent.center.pageX;
var dragIsWithinBounds = !shouldOnlyAllowEdgeDrag ||
startX <= self.edgeThreshold ||
startX >= self.content.element.offsetWidth - self.edgeThreshold;
var backView = $ionicHistory.backView();
var menuEnabled = enableMenuWithBackViews ? true : !backView;
if (!menuEnabled) {
var currentView = $ionicHistory.currentView() || {};
return backView.historyId !== currentView.historyId;
}
return ($scope.dragContent || self.isOpen()) &&
dragIsWithinBounds &&
!e.gesture.srcEvent.defaultPrevented &&
menuEnabled &&
!e.target.tagName.match(/input|textarea|select|object|embed/i) &&
!e.target.isContentEditable &&
!(e.target.dataset ? e.target.dataset.preventScroll : e.target.getAttribute('data-prevent-scroll') == 'true');
};
$scope.sideMenuContentTranslateX = 0;
var deregisterBackButtonAction = angular.noop;
var closeSideMenu = angular.bind(self, self.close);
$scope.$watch(function() {
return self.getOpenAmount() !== 0;
}, function(isOpen) {
deregisterBackButtonAction();
if (isOpen) {
deregisterBackButtonAction = $ionicPlatform.registerBackButtonAction(
closeSideMenu,
PLATFORM_BACK_BUTTON_PRIORITY_SIDE_MENU
);
}
});
var deregisterInstance = $ionicSideMenuDelegate._registerInstance(
self, $attrs.delegateHandle,
function() {
return $ionicHistory.isActiveScope($scope);
}
);
$scope.$on('$destroy', function() {
deregisterInstance();
deregisterBackButtonAction();
self.$scope = null;
if (self.content) {
self.content.element = null;
self.content = null;
}
});
self.initialize({
left: {
width: 275
},
right: {
width: 275
}
});
}
]);
body {
cursor: url('http://ionicframework.com/img/finger.png'), auto;
}
.inactive {
cursor: pointer;
-webkit-transform: translate3d(160px, 0px, 0px) scale(0.5);
-moz-transform: translate3d(160px, 0px, 0px) scale(0.5);
-ms-transform: translate3d(160px, 0px, 0px) scale(0.5);
transform: translate3d(160px, 0px, 0px) scale(0.5);
}
/* All Menus */
.menu {
-webkit-transition: all 300ms ease-in-out;
-moz-transition: all 300ms ease-in-out;
-ms-transition: all 300ms ease-in-out;
-o-transition: all 300ms ease-in-out;
transition: all 300ms ease-in-out;
-webkit-backface-visibility: hidden;
}
/* Left Menu */
.menu.menu-left {
-webkit-transition: all 400ms ease-in-out;
-moz-transition: all 400ms ease-in-out;
-ms-transition: all 400ms ease-in-out;
-o-transition: all 400ms ease-in-out;
transition: all 400ms ease-in-out;
-webkit-backface-visibility: hidden;
display:inherit;
left: -1000px;
transform: scale(0);
/* Adjust if you use different margins on menu-left. */
min-height:90%;
max-height:90%;
}
.menu.menu-left .list {
transition: all 300ms ease-in-out;
transform: scale(.2);
}
/* When Left Menu Open */
.menu.menu-left.active {
-webkit-transition: all 200ms ease-in-out;
-moz-transition: all 200ms ease-in-out;
-ms-transition: all 200ms ease-in-out;
-o-transition: all 200ms ease-in-out;
transition: all 200ms ease-in-out;
-webkit-backface-visibility: hidden;
display:inherit;
transform: scale(1);
/*
Adjust how far from top the menu appears.
For small menus, you might want to think about adjusting this.
*/
top: 0px;
left: 30px;
z-index: 999 !important;
/* Adjust if you use different height for menu. */
margin-top:5%;
margin-top:calc(5vh);
margin-bottom:5%;
/* 0px 0px is for 360-degree box shadow. Default 100px spread. */
box-shadow: 0px 0px 100px rgba(0,0,0,0.2);
border-radius: 10px;
}
@media screen and (min-width:420px) {
.menu.menu-left {
min-width:380px;
}
}
@media screen and (min-width:1200px) {
.menu.menu-left {
min-width:500px;
}
}
.menu-screen, .menu-screen.pane {
background: transparent;
/*-webkit-backdrop-filter: blur(5px);
backdrop-filter: blur(5px); */
}
.menu-left.active {
background: rgba(255,255,255,0.8);
}
.menu.menu-left.active .list {
transform: scale(1);
}
.menu.menu-left.active .list :hover {
transform: scale(1.03);
}
/* Scroll Override for Windows */
.menu-screen.scroll-content.overflow-scroll {
transition: all 250ms ease-in-out;
-ms-overflow-style: none !important;
}
.menu-screen.scroll-content.overflow-scroll::-webkit-scrollbar {
width: 0 !important;
}
/* Right Menu */
.menu-right {
/* 0px 0px is for 360-degree box shadow. Default 100px spread. */
background: rgba(255,255,255,0.5);
}
.menu.menu-right {
transition: all 300ms ease-in-out;
}
.menu.menu-right .list {
transition: all 300ms ease-in-out;
}
/* When Right Menu Open */
.menu.menu-right.active {
display:inherit;
}
.menu.menu-right.active .list {
transform: scale(1);
}
/* .menu.menu-right.active {
right: 40px;
} */
/* Fix menu-right draw error when opening and closing menu-left */
.menu.menu-right.inactive {
opacity:0;
transition: all 0ms ease-in-out;
}
/* Side Menu Background */
.pane.view {
background: #cccccc;
/*background: url(YOUR_IMAGE) no-repeat center;
background-size: cover;
backdrop-filter: blur(10px);*/
}
/* Add shadow around main view container for when menu-left is active. */
.view-container .pane {
/* 0px 0px is for 360-degree box shadow. Default 100px spread. */
box-shadow: 0px 0px 100px rgba(0,0,0,0.2);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment