-
Notifications
You must be signed in to change notification settings - Fork 11
/
angular-menu-slideout.js
99 lines (83 loc) · 4.4 KB
/
angular-menu-slideout.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
angular.module('MenuSlideout', ['ngTouch'])
.directive('menuSlideout', ['$swipe', '$document', '$rootScope', function ($swipe, $document, $rootScope) {
return {
restrict: 'A',
link: function (scope, $elem, attrs) {
var startCoords, dir, endCoords, lastCoords,
// how far horizontally do I need to move
// before we do anything?
tolerance = 10,
// just keeping trying of if we met the tolerance
toleranceMet = false,
// if we slide this far in a particular
// direction, we ignore the direction
slideTolerance = 100,
// NYI until Angular allows config of the tolerances
moveYBufferRadius = 30,
// we toggle transitionClass cuz we don't want to
// transition while we're actually dragging
transitionClass = 'menu-slideout-transition',
openClass = 'menu-slideout-open',
isSlidingClass = 'menu-slideout-is-sliding',
// TODO: make the menu open all but X pixels of window
// var menuWidth = $document[0].width - 74;
// angular.element(document).find('head').append('<style type="text/css">@charset "UTF-8";.slider.open{-webkit-transform: translate3d(' + menuWidth + 'px, 0, 0);</style>');
menuWidth = 230,
// adapted from http://davidwalsh.name/vendor-prefix
prefix = (function () {
var styles = window.getComputedStyle(document.documentElement, ''),
pre = (Array.prototype.slice
.call(styles)
.join('')
.match(/-(moz|webkit|ms)-/) || (styles.OLink === '' && ['', 'o'])
)[1];
return '-' + pre + '-';
})();
$swipe.bind($elem, {
start: function (coords, event) {
toleranceMet = false;
startCoords = angular.copy(lastCoords = coords);
},
end: function (coords, event) {
endCoords = coords;
$elem.removeAttr('style').addClass(transitionClass).removeClass(isSlidingClass);
if(!toleranceMet) return;
// if we slide more than slideTolerance pixels
// in a particular direction, then we override dir
if(coords.x - startCoords.x > slideTolerance) dir = 'right';
if(coords.x - startCoords.x < (-1 * slideTolerance)) dir = 'left';
if(dir == 'right') $elem.addClass(openClass);
else $elem.removeClass(openClass);
$rootScope.$broadcast('slideMenuToggled', dir == 'right');
},
move: function (coords, event) {
// set a tolerance before we kick in sliding
// (Angular does this to an extent, also, I believe)
if(!toleranceMet && Math.abs(startCoords.x - coords.x) < tolerance) return;
dir = lastCoords.x < coords.x ? 'right' : 'left';
$elem.removeClass(transitionClass).addClass(isSlidingClass);
// restrict x to be between 0 and menuWidth
var x = coords.x - startCoords.x + ($elem.hasClass(openClass) ? menuWidth : 0);
x = Math.max(0, Math.min(menuWidth, x));
// translate3d is WAY more performant than left
// thanks to GPU acceleration (especially
// noticeable on slower, mobile devices)
var props = {};
props[prefix + 'transform'] = 'translate3d(' + x + 'px, 0, 0)';
$elem.css(props);
lastCoords = coords;
toleranceMet = true;
},
cancel: function (coords, event) {
$elem.addClass(transitionClass).removeClass(isSlidingClass);
$elem.removeAttr('style');
}
}, {
moveYBufferRadius: moveYBufferRadius
});
$rootScope.$on('toggleSlideMenu', function(event, isOpen) {
$elem.toggleClass(openClass, isOpen);
});
}
};
}]);