snap_js-rails 1.9.0 → 1.9.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e5548f3617ab2ef4ba522658414a778ba5ec393e
4
+ data.tar.gz: 2601f4884a12b27187b99176de1258383e090a5f
5
+ SHA512:
6
+ metadata.gz: a1f4af11493f64310b4bbb07610195fc536fc09fc5cf6d73ea109607ef01ad61a1de4d03ce391bba20f7b7b96eff23e0aa383955be2dcdcc4442671206bb09eb
7
+ data.tar.gz: 755198af75477feaa88cc45a32042834a010d6f3a0d2dc26c3aefbc2fa12f3cb6fc256f884b589b01c75636159cf00027b766a5441220aa7c4ef5b520b55f922
data/.gitignore CHANGED
@@ -1,17 +1,17 @@
1
- *.gem
2
- *.rbc
3
- .bundle
4
- .config
5
- .yardoc
6
- Gemfile.lock
7
- InstalledFiles
8
- _yardoc
9
- coverage
10
- doc/
11
- lib/bundler/man
12
- pkg
13
- rdoc
14
- spec/reports
15
- test/tmp
16
- test/version_tmp
17
- tmp
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
- source 'https://rubygems.org'
2
-
3
- # Specify your gem's dependencies in snap_js.gemspec
4
- gemspec
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in snap_js.gemspec
4
+ gemspec
@@ -1,22 +1,22 @@
1
- Copyright (c) 2013 Aaron Breckenridge
2
-
3
- MIT License
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining
6
- a copy of this software and associated documentation files (the
7
- "Software"), to deal in the Software without restriction, including
8
- without limitation the rights to use, copy, modify, merge, publish,
9
- distribute, sublicense, and/or sell copies of the Software, and to
10
- permit persons to whom the Software is furnished to do so, subject to
11
- the following conditions:
12
-
13
- The above copyright notice and this permission notice shall be
14
- included in all copies or substantial portions of the Software.
15
-
16
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1
+ Copyright (c) 2013 Aaron Breckenridge
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,51 +1,74 @@
1
- # snap_js-rails
2
-
3
- Add [Snap.js](https://github.com/jakiestfu/Snap.js) to your asset pipeline.
4
-
5
- ## Installation
6
-
7
- Add this line to your application's Gemfile:
8
-
9
- gem 'snap_js-rails'
10
-
11
- And then execute:
12
-
13
- $ bundle
14
-
15
- Or install it yourself as:
16
-
17
- $ gem install snap_js-rails
18
-
19
- ## Usage
20
-
21
- Add this line to your `application.js` file.
22
-
23
- //= require snap
24
-
25
- Then, either add this to `application.js` below the requires...
26
-
27
- $(function() {
28
- var snapper = new Snap({
29
- element: document.getElementById('content')
30
- });
31
- })
32
-
33
- ... or add it directly to your layout file (i.e. `application.html.erb`)
34
-
35
- <script type="text/javascript">
36
- var snapper = new Snap({
37
- element: document.getElementById('content')
38
- });
39
- </script>
40
-
41
- There's also an optional CSS stylesheet containing the barebones styles you'll need to get started (also from https://github.com/jakiestfu/Snap.js). To use it, add this to `application.css`:
42
-
43
- *= require snap
44
-
45
- ## Contributing
46
-
47
- 1. Fork it
48
- 2. Create your feature branch (`git checkout -b my-new-feature`)
49
- 3. Commit your changes (`git commit -am 'Add some feature'`)
50
- 4. Push to the branch (`git push origin my-new-feature`)
51
- 5. Create new Pull Request
1
+ # snap_js-rails
2
+
3
+ Add [Snap.js](https://github.com/jakiestfu/Snap.js) to your asset pipeline.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'snap_js-rails'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install snap_js-rails
18
+
19
+ ## Usage
20
+
21
+ Add this line to your `application.js` file.
22
+
23
+ //= require snap
24
+
25
+ Then, either add this to `application.js` below the requires...
26
+
27
+ $(function() {
28
+ var snapper = new Snap({
29
+ element: document.getElementById('content')
30
+ });
31
+ })
32
+
33
+ ... or add it directly to your layout file (i.e. `application.html.erb`)
34
+
35
+ <script type="text/javascript">
36
+ var snapper = new Snap({
37
+ element: document.getElementById('content')
38
+ });
39
+ </script>
40
+
41
+ There's also an optional CSS stylesheet containing the barebones styles you'll need to get started (also from https://github.com/jakiestfu/Snap.js). To use it, add this to `application.css`:
42
+
43
+ *= require snap
44
+
45
+ A barebones `application.html.erb` might look like this:
46
+
47
+ ...
48
+ <body>
49
+ <div class="snap-drawers" style="position: absolute">
50
+ <div class="snap-drawer snap-drawer-left">
51
+ <!-- Left Drawer Content -->
52
+ </div>
53
+ <div class="snap-drawer snap-drawer-right">
54
+ <!-- Right Drawer Content -->
55
+ </div>
56
+ </div>
57
+ <div id="content" class="snap-content">
58
+ <div id="toolbar">
59
+ <!-- Toolbar Content -->
60
+ </div>
61
+ <%= yield %>
62
+ </div>
63
+ </body>
64
+ ...
65
+
66
+ Refer to [Snap.js](https://github.com/jakiestfu/Snap.js) for more options.
67
+
68
+ ## Contributing
69
+
70
+ 1. Fork it
71
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
72
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
73
+ 4. Push to the branch (`git push origin my-new-feature`)
74
+ 5. Create new Pull Request
data/Rakefile CHANGED
@@ -1 +1 @@
1
- require "bundler/gem_tasks"
1
+ require "bundler/gem_tasks"
@@ -1 +1 @@
1
- require "snap_js-rails/engine"
1
+ require "snap_js-rails/engine"
@@ -1,8 +1,8 @@
1
- require 'rails'
2
-
3
- module SnapJs
4
- module Rails
5
- class Engine < ::Rails::Engine
6
- end
7
- end
8
- end
1
+ require 'rails'
2
+
3
+ module SnapJs
4
+ module Rails
5
+ class Engine < ::Rails::Engine
6
+ end
7
+ end
8
+ end
@@ -1,3 +1,3 @@
1
- module SnapJs
2
- VERSION = "1.9.0"
3
- end
1
+ module SnapJs
2
+ VERSION = "1.9.2"
3
+ end
@@ -1,25 +1,25 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'snap_js-rails/version'
5
-
6
- Gem::Specification.new do |spec|
7
- spec.name = "snap_js-rails"
8
- spec.version = SnapJs::VERSION
9
- spec.authors = ["Aaron Breckenridge"]
10
- spec.email = ["aaronbreckenridge@gmail.com"]
11
- spec.description = "This gem adds Snap.js to the Rails asset pipeline"
12
- spec.summary = "Add Snap.js to the Rails asset pipeline"
13
- spec.homepage = "https://github.com/breckenedge/snap_js-rails"
14
- spec.license = "MIT"
15
-
16
- spec.files = `git ls-files`.split($/)
17
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
- spec.require_paths = ["lib"]
20
-
21
- spec.add_dependency "railties", ">= 3.1"
22
-
23
- spec.add_development_dependency "bundler", "~> 1.3"
24
- spec.add_development_dependency "rake"
25
- end
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'snap_js-rails/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "snap_js-rails"
8
+ spec.version = SnapJs::VERSION
9
+ spec.authors = ["Aaron Breckenridge"]
10
+ spec.email = ["aaronbreckenridge@gmail.com"]
11
+ spec.description = "This gem adds Snap.js to the Rails asset pipeline"
12
+ spec.summary = "Add Snap.js to the Rails asset pipeline"
13
+ spec.homepage = "https://github.com/breckenedge/snap_js-rails"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "railties", ">= 3.1"
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.3"
24
+ spec.add_development_dependency "rake"
25
+ end
@@ -1,562 +1,568 @@
1
- /*
2
- * Snap.js
3
- *
4
- * Copyright 2013, Jacob Kelley - http://jakiestfu.com/
5
- * Released under the MIT Licence
6
- * http://opensource.org/licenses/MIT
7
- *
8
- * Github: http://github.com/jakiestfu/Snap.js/
9
- * Version: 1.9.0
10
- */
11
- /*jslint browser: true*/
12
- /*global define, module, ender*/
13
- (function(win, doc) {
14
- 'use strict';
15
- var Snap = Snap || function(userOpts) {
16
- var settings = {
17
- element: null,
18
- dragger: null,
19
- disable: 'none',
20
- addBodyClasses: true,
21
- hyperextensible: true,
22
- resistance: 0.5,
23
- flickThreshold: 50,
24
- transitionSpeed: 0.3,
25
- easing: 'ease',
26
- maxPosition: 266,
27
- minPosition: -266,
28
- tapToClose: true,
29
- touchToDrag: true,
30
- slideIntent: 40, // degrees
31
- minDragDistance: 5
32
- },
33
- cache = {
34
- simpleStates: {
35
- opening: null,
36
- towards: null,
37
- hyperExtending: null,
38
- halfway: null,
39
- flick: null,
40
- translation: {
41
- absolute: 0,
42
- relative: 0,
43
- sinceDirectionChange: 0,
44
- percentage: 0
45
- }
46
- }
47
- },
48
- eventList = {},
49
- utils = {
50
- hasTouch: (doc.ontouchstart === null),
51
- eventType: function(action) {
52
- var eventTypes = {
53
- down: (utils.hasTouch ? 'touchstart' : 'mousedown'),
54
- move: (utils.hasTouch ? 'touchmove' : 'mousemove'),
55
- up: (utils.hasTouch ? 'touchend' : 'mouseup'),
56
- out: (utils.hasTouch ? 'touchcancel' : 'mouseout')
57
- };
58
- return eventTypes[action];
59
- },
60
- page: function(t, e){
61
- return (utils.hasTouch && e.touches.length && e.touches[0]) ? e.touches[0]['page'+t] : e['page'+t];
62
- },
63
- klass: {
64
- has: function(el, name){
65
- return (el.className).indexOf(name) !== -1;
66
- },
67
- add: function(el, name){
68
- if(!utils.klass.has(el, name) && settings.addBodyClasses){
69
- el.className += " "+name;
70
- }
71
- },
72
- remove: function(el, name){
73
- if(settings.addBodyClasses){
74
- el.className = (el.className).replace(" "+name, "");
75
- }
76
- }
77
- },
78
- dispatchEvent: function(type) {
79
- if (typeof eventList[type] === 'function') {
80
- return eventList[type].call();
81
- }
82
- },
83
- vendor: function(){
84
- var tmp = doc.createElement("div"),
85
- prefixes = 'webkit Moz O ms'.split(' '),
86
- i;
87
- for (i in prefixes) {
88
- if (typeof tmp.style[prefixes[i] + 'Transition'] !== 'undefined') {
89
- return prefixes[i];
90
- }
91
- }
92
- },
93
- transitionCallback: function(){
94
- return (cache.vendor==='Moz' || cache.vendor==='ms') ? 'transitionend' : cache.vendor+'TransitionEnd';
95
- },
96
- canTransform: function(){
97
- return typeof settings.element.style[cache.vendor+'Transform'] !== 'undefined';
98
- },
99
- deepExtend: function(destination, source) {
100
- var property;
101
- for (property in source) {
102
- if (source[property] && source[property].constructor && source[property].constructor === Object) {
103
- destination[property] = destination[property] || {};
104
- utils.deepExtend(destination[property], source[property]);
105
- } else {
106
- destination[property] = source[property];
107
- }
108
- }
109
- return destination;
110
- },
111
- angleOfDrag: function(x, y) {
112
- var degrees, theta;
113
- // Calc Theta
114
- theta = Math.atan2(-(cache.startDragY - y), (cache.startDragX - x));
115
- if (theta < 0) {
116
- theta += 2 * Math.PI;
117
- }
118
- // Calc Degrees
119
- degrees = Math.floor(theta * (180 / Math.PI) - 180);
120
- if (degrees < 0 && degrees > -180) {
121
- degrees = 360 - Math.abs(degrees);
122
- }
123
- return Math.abs(degrees);
124
- },
125
- events: {
126
- addEvent: function addEvent(element, eventName, func) {
127
- if (element.addEventListener) {
128
- return element.addEventListener(eventName, func, false);
129
- } else if (element.attachEvent) {
130
- return element.attachEvent("on" + eventName, func);
131
- }
132
- },
133
- removeEvent: function addEvent(element, eventName, func) {
134
- if (element.addEventListener) {
135
- return element.removeEventListener(eventName, func, false);
136
- } else if (element.attachEvent) {
137
- return element.detachEvent("on" + eventName, func);
138
- }
139
- },
140
- prevent: function(e) {
141
- if (e.preventDefault) {
142
- e.preventDefault();
143
- } else {
144
- e.returnValue = false;
145
- }
146
- }
147
- },
148
- parentUntil: function(el, attr) {
149
- var isStr = typeof attr === 'string';
150
- while (el.parentNode) {
151
- if (isStr && el.getAttribute && el.getAttribute(attr)){
152
- return el;
153
- } else if(!isStr && el === attr){
154
- return el;
155
- }
156
- el = el.parentNode;
157
- }
158
- return null;
159
- }
160
- },
161
- action = {
162
- translate: {
163
- get: {
164
- matrix: function(index) {
165
-
166
- if( !utils.canTransform() ){
167
- return parseInt(settings.element.style.left, 10);
168
- } else {
169
- var matrix = win.getComputedStyle(settings.element)[cache.vendor+'Transform'].match(/\((.*)\)/),
170
- ieOffset = 8;
171
- if (matrix) {
172
- matrix = matrix[1].split(',');
173
- if(matrix.length===16){
174
- index+=ieOffset;
175
- }
176
- return parseInt(matrix[index], 10);
177
- }
178
- return 0;
179
- }
180
- }
181
- },
182
- easeCallback: function(){
183
- settings.element.style[cache.vendor+'Transition'] = '';
184
- cache.translation = action.translate.get.matrix(4);
185
- cache.easing = false;
186
- clearInterval(cache.animatingInterval);
187
-
188
- if(cache.easingTo===0){
189
- utils.klass.remove(doc.body, 'snapjs-right');
190
- utils.klass.remove(doc.body, 'snapjs-left');
191
- }
192
-
193
- utils.dispatchEvent('animated');
194
- utils.events.removeEvent(settings.element, utils.transitionCallback(), action.translate.easeCallback);
195
- },
196
- easeTo: function(n) {
197
-
198
- if( !utils.canTransform() ){
199
- cache.translation = n;
200
- action.translate.x(n);
201
- } else {
202
- cache.easing = true;
203
- cache.easingTo = n;
204
-
205
- settings.element.style[cache.vendor+'Transition'] = 'all ' + settings.transitionSpeed + 's ' + settings.easing;
206
-
207
- cache.animatingInterval = setInterval(function() {
208
- utils.dispatchEvent('animating');
209
- }, 1);
210
-
211
- utils.events.addEvent(settings.element, utils.transitionCallback(), action.translate.easeCallback);
212
- action.translate.x(n);
213
- }
214
- if(n===0){
215
- settings.element.style[cache.vendor+'Transform'] = '';
216
- }
217
- },
218
- x: function(n) {
219
- if( (settings.disable==='left' && n>0) ||
220
- (settings.disable==='right' && n<0)
221
- ){ return; }
222
-
223
- if( !settings.hyperextensible ){
224
- if( n===settings.maxPosition || n>settings.maxPosition ){
225
- n=settings.maxPosition;
226
- } else if( n===settings.minPosition || n<settings.minPosition ){
227
- n=settings.minPosition;
228
- }
229
- }
230
-
231
- n = parseInt(n, 10);
232
- if(isNaN(n)){
233
- n = 0;
234
- }
235
-
236
- if( utils.canTransform() ){
237
- var theTranslate = 'translate3d(' + n + 'px, 0,0)';
238
- settings.element.style[cache.vendor+'Transform'] = theTranslate;
239
- } else {
240
- settings.element.style.width = (win.innerWidth || doc.documentElement.clientWidth)+'px';
241
-
242
- settings.element.style.left = n+'px';
243
- settings.element.style.right = '';
244
- }
245
- }
246
- },
247
- drag: {
248
- listen: function() {
249
- cache.translation = 0;
250
- cache.easing = false;
251
- utils.events.addEvent(settings.element, utils.eventType('down'), action.drag.startDrag);
252
- utils.events.addEvent(settings.element, utils.eventType('move'), action.drag.dragging);
253
- utils.events.addEvent(settings.element, utils.eventType('up'), action.drag.endDrag);
254
- },
255
- stopListening: function() {
256
- utils.events.removeEvent(settings.element, utils.eventType('down'), action.drag.startDrag);
257
- utils.events.removeEvent(settings.element, utils.eventType('move'), action.drag.dragging);
258
- utils.events.removeEvent(settings.element, utils.eventType('up'), action.drag.endDrag);
259
- },
260
- startDrag: function(e) {
261
- // No drag on ignored elements
262
- var target = e.target ? e.target : e.srcElement,
263
- ignoreParent = utils.parentUntil(target, 'data-snap-ignore');
264
-
265
- if (ignoreParent) {
266
- utils.dispatchEvent('ignore');
267
- return;
268
- }
269
-
270
-
271
- if(settings.dragger){
272
- var dragParent = utils.parentUntil(target, settings.dragger);
273
-
274
- // Only use dragger if we're in a closed state
275
- if( !dragParent &&
276
- (cache.translation !== settings.minPosition &&
277
- cache.translation !== settings.maxPosition
278
- )){
279
- return;
280
- }
281
- }
282
-
283
- utils.dispatchEvent('start');
284
- settings.element.style[cache.vendor+'Transition'] = '';
285
- cache.isDragging = true;
286
- cache.hasIntent = null;
287
- cache.intentChecked = false;
288
- cache.startDragX = utils.page('X', e);
289
- cache.startDragY = utils.page('Y', e);
290
- cache.dragWatchers = {
291
- current: 0,
292
- last: 0,
293
- hold: 0,
294
- state: ''
295
- };
296
- cache.simpleStates = {
297
- opening: null,
298
- towards: null,
299
- hyperExtending: null,
300
- halfway: null,
301
- flick: null,
302
- translation: {
303
- absolute: 0,
304
- relative: 0,
305
- sinceDirectionChange: 0,
306
- percentage: 0
307
- }
308
- };
309
- },
310
- dragging: function(e) {
311
- if (cache.isDragging && settings.touchToDrag) {
312
-
313
- var thePageX = utils.page('X', e),
314
- thePageY = utils.page('Y', e),
315
- translated = cache.translation,
316
- absoluteTranslation = action.translate.get.matrix(4),
317
- whileDragX = thePageX - cache.startDragX,
318
- openingLeft = absoluteTranslation > 0,
319
- translateTo = whileDragX,
320
- diff;
321
-
322
- // Shown no intent already
323
- if((cache.intentChecked && !cache.hasIntent)){
324
- return;
325
- }
326
-
327
- if(settings.addBodyClasses){
328
- if((absoluteTranslation)>0){
329
- utils.klass.add(doc.body, 'snapjs-left');
330
- utils.klass.remove(doc.body, 'snapjs-right');
331
- } else if((absoluteTranslation)<0){
332
- utils.klass.add(doc.body, 'snapjs-right');
333
- utils.klass.remove(doc.body, 'snapjs-left');
334
- }
335
- }
336
-
337
- if (cache.hasIntent === false || cache.hasIntent === null) {
338
- var deg = utils.angleOfDrag(thePageX, thePageY),
339
- inRightRange = (deg >= 0 && deg <= settings.slideIntent) || (deg <= 360 && deg > (360 - settings.slideIntent)),
340
- inLeftRange = (deg >= 180 && deg <= (180 + settings.slideIntent)) || (deg <= 180 && deg >= (180 - settings.slideIntent));
341
- if (!inLeftRange && !inRightRange) {
342
- cache.hasIntent = false;
343
- } else {
344
- cache.hasIntent = true;
345
- }
346
- cache.intentChecked = true;
347
- }
348
-
349
- if (
350
- (settings.minDragDistance>=Math.abs(thePageX-cache.startDragX)) || // Has user met minimum drag distance?
351
- (cache.hasIntent === false)
352
- ) {
353
- return;
354
- }
355
-
356
- utils.events.prevent(e);
357
- utils.dispatchEvent('drag');
358
-
359
- cache.dragWatchers.current = thePageX;
360
- // Determine which direction we are going
361
- if (cache.dragWatchers.last > thePageX) {
362
- if (cache.dragWatchers.state !== 'left') {
363
- cache.dragWatchers.state = 'left';
364
- cache.dragWatchers.hold = thePageX;
365
- }
366
- cache.dragWatchers.last = thePageX;
367
- } else if (cache.dragWatchers.last < thePageX) {
368
- if (cache.dragWatchers.state !== 'right') {
369
- cache.dragWatchers.state = 'right';
370
- cache.dragWatchers.hold = thePageX;
371
- }
372
- cache.dragWatchers.last = thePageX;
373
- }
374
- if (openingLeft) {
375
- // Pulling too far to the right
376
- if (settings.maxPosition < absoluteTranslation) {
377
- diff = (absoluteTranslation - settings.maxPosition) * settings.resistance;
378
- translateTo = whileDragX - diff;
379
- }
380
- cache.simpleStates = {
381
- opening: 'left',
382
- towards: cache.dragWatchers.state,
383
- hyperExtending: settings.maxPosition < absoluteTranslation,
384
- halfway: absoluteTranslation > (settings.maxPosition / 2),
385
- flick: Math.abs(cache.dragWatchers.current - cache.dragWatchers.hold) > settings.flickThreshold,
386
- translation: {
387
- absolute: absoluteTranslation,
388
- relative: whileDragX,
389
- sinceDirectionChange: (cache.dragWatchers.current - cache.dragWatchers.hold),
390
- percentage: (absoluteTranslation/settings.maxPosition)*100
391
- }
392
- };
393
- } else {
394
- // Pulling too far to the left
395
- if (settings.minPosition > absoluteTranslation) {
396
- diff = (absoluteTranslation - settings.minPosition) * settings.resistance;
397
- translateTo = whileDragX - diff;
398
- }
399
- cache.simpleStates = {
400
- opening: 'right',
401
- towards: cache.dragWatchers.state,
402
- hyperExtending: settings.minPosition > absoluteTranslation,
403
- halfway: absoluteTranslation < (settings.minPosition / 2),
404
- flick: Math.abs(cache.dragWatchers.current - cache.dragWatchers.hold) > settings.flickThreshold,
405
- translation: {
406
- absolute: absoluteTranslation,
407
- relative: whileDragX,
408
- sinceDirectionChange: (cache.dragWatchers.current - cache.dragWatchers.hold),
409
- percentage: (absoluteTranslation/settings.minPosition)*100
410
- }
411
- };
412
- }
413
- action.translate.x(translateTo + translated);
414
- }
415
- },
416
- endDrag: function(e) {
417
- if (cache.isDragging) {
418
- utils.dispatchEvent('end');
419
- var translated = action.translate.get.matrix(4);
420
-
421
- // Tap Close
422
- if (cache.dragWatchers.current === 0 && translated !== 0 && settings.tapToClose) {
423
- utils.events.prevent(e);
424
- action.translate.easeTo(0);
425
- cache.isDragging = false;
426
- cache.startDragX = 0;
427
- return;
428
- }
429
-
430
- // Revealing Left
431
- if (cache.simpleStates.opening === 'left') {
432
- // Halfway, Flicking, or Too Far Out
433
- if ((cache.simpleStates.halfway || cache.simpleStates.hyperExtending || cache.simpleStates.flick)) {
434
- if (cache.simpleStates.flick && cache.simpleStates.towards === 'left') { // Flicking Closed
435
- action.translate.easeTo(0);
436
- } else if (
437
- (cache.simpleStates.flick && cache.simpleStates.towards === 'right') || // Flicking Open OR
438
- (cache.simpleStates.halfway || cache.simpleStates.hyperExtending) // At least halfway open OR hyperextending
439
- ) {
440
- action.translate.easeTo(settings.maxPosition); // Open Left
441
- }
442
- } else {
443
- action.translate.easeTo(0); // Close Left
444
- }
445
- // Revealing Right
446
- } else if (cache.simpleStates.opening === 'right') {
447
- // Halfway, Flicking, or Too Far Out
448
- if ((cache.simpleStates.halfway || cache.simpleStates.hyperExtending || cache.simpleStates.flick)) {
449
- if (cache.simpleStates.flick && cache.simpleStates.towards === 'right') { // Flicking Closed
450
- action.translate.easeTo(0);
451
- } else if (
452
- (cache.simpleStates.flick && cache.simpleStates.towards === 'left') || // Flicking Open OR
453
- (cache.simpleStates.halfway || cache.simpleStates.hyperExtending) // At least halfway open OR hyperextending
454
- ) {
455
- action.translate.easeTo(settings.minPosition); // Open Right
456
- }
457
- } else {
458
- action.translate.easeTo(0); // Close Right
459
- }
460
- }
461
- cache.isDragging = false;
462
- cache.startDragX = utils.page('X', e);
463
- }
464
- }
465
- }
466
- },
467
- init = function(opts) {
468
- if (opts.element) {
469
- utils.deepExtend(settings, opts);
470
- cache.vendor = utils.vendor();
471
- action.drag.listen();
472
- }
473
- };
474
- /*
475
- * Public
476
- */
477
- this.open = function(side) {
478
-
479
- utils.klass.remove(doc.body, 'snapjs-expand-left');
480
- utils.klass.remove(doc.body, 'snapjs-expand-right');
481
-
482
- if (side === 'left') {
483
- cache.simpleStates.opening = 'left';
484
- cache.simpleStates.towards = 'right';
485
- utils.klass.add(doc.body, 'snapjs-left');
486
- utils.klass.remove(doc.body, 'snapjs-right');
487
- action.translate.easeTo(settings.maxPosition);
488
- } else if (side === 'right') {
489
- cache.simpleStates.opening = 'right';
490
- cache.simpleStates.towards = 'left';
491
- utils.klass.remove(doc.body, 'snapjs-left');
492
- utils.klass.add(doc.body, 'snapjs-right');
493
- action.translate.easeTo(settings.minPosition);
494
- }
495
- };
496
- this.close = function() {
497
- action.translate.easeTo(0);
498
- };
499
- this.expand = function(side){
500
- var to = win.innerWidth || doc.documentElement.clientWidth;
501
-
502
- if(side==='left'){
503
- utils.klass.add(doc.body, 'snapjs-expand-left');
504
- utils.klass.remove(doc.body, 'snapjs-expand-right');
505
- } else {
506
- utils.klass.add(doc.body, 'snapjs-expand-right');
507
- utils.klass.remove(doc.body, 'snapjs-expand-left');
508
- to *= -1;
509
- }
510
- action.translate.easeTo(to);
511
- };
512
-
513
- this.on = function(evt, fn) {
514
- eventList[evt] = fn;
515
- return this;
516
- };
517
- this.off = function(evt) {
518
- if (eventList[evt]) {
519
- eventList[evt] = false;
520
- }
521
- };
522
-
523
- this.enable = function() {
524
- action.drag.listen();
525
- };
526
- this.disable = function() {
527
- action.drag.stopListening();
528
- };
529
-
530
- this.settings = function(opts){
531
- utils.deepExtend(settings, opts);
532
- };
533
-
534
- this.state = function() {
535
- var state,
536
- fromLeft = action.translate.get.matrix(4);
537
- if (fromLeft === settings.maxPosition) {
538
- state = 'left';
539
- } else if (fromLeft === settings.minPosition) {
540
- state = 'right';
541
- } else {
542
- state = 'closed';
543
- }
544
- return {
545
- state: state,
546
- info: cache.simpleStates
547
- };
548
- };
549
- init(userOpts);
550
- };
551
- if ((typeof module !== 'undefined') && module.exports) {
552
- module.exports = Snap;
553
- }
554
- if (typeof ender === 'undefined') {
555
- this.Snap = Snap;
556
- }
557
- if ((typeof define === "function") && define.amd) {
558
- define("snap", [], function() {
559
- return Snap;
560
- });
561
- }
1
+ /*
2
+ * Snap.js
3
+ *
4
+ * Copyright 2013, Jacob Kelley - http://jakiestfu.com/
5
+ * Released under the MIT Licence
6
+ * http://opensource.org/licenses/MIT
7
+ *
8
+ * Github: http://github.com/jakiestfu/Snap.js/
9
+ * Version: 1.9.2
10
+ */
11
+ /*jslint browser: true*/
12
+ /*global define, module, ender*/
13
+ (function(win, doc) {
14
+ 'use strict';
15
+ var Snap = Snap || function(userOpts) {
16
+ var settings = {
17
+ element: null,
18
+ dragger: null,
19
+ disable: 'none',
20
+ addBodyClasses: true,
21
+ hyperextensible: true,
22
+ resistance: 0.5,
23
+ flickThreshold: 50,
24
+ transitionSpeed: 0.3,
25
+ easing: 'ease',
26
+ maxPosition: 266,
27
+ minPosition: -266,
28
+ tapToClose: true,
29
+ touchToDrag: true,
30
+ slideIntent: 40, // degrees
31
+ minDragDistance: 5
32
+ },
33
+ cache = {
34
+ simpleStates: {
35
+ opening: null,
36
+ towards: null,
37
+ hyperExtending: null,
38
+ halfway: null,
39
+ flick: null,
40
+ translation: {
41
+ absolute: 0,
42
+ relative: 0,
43
+ sinceDirectionChange: 0,
44
+ percentage: 0
45
+ }
46
+ }
47
+ },
48
+ eventList = {},
49
+ utils = {
50
+ hasTouch: (doc.ontouchstart === null),
51
+ eventType: function(action) {
52
+ var eventTypes = {
53
+ down: (utils.hasTouch ? 'touchstart' : 'mousedown'),
54
+ move: (utils.hasTouch ? 'touchmove' : 'mousemove'),
55
+ up: (utils.hasTouch ? 'touchend' : 'mouseup'),
56
+ out: (utils.hasTouch ? 'touchcancel' : 'mouseout')
57
+ };
58
+ return eventTypes[action];
59
+ },
60
+ page: function(t, e){
61
+ return (utils.hasTouch && e.touches.length && e.touches[0]) ? e.touches[0]['page'+t] : e['page'+t];
62
+ },
63
+ klass: {
64
+ has: function(el, name){
65
+ return (el.className).indexOf(name) !== -1;
66
+ },
67
+ add: function(el, name){
68
+ if(!utils.klass.has(el, name) && settings.addBodyClasses){
69
+ el.className += " "+name;
70
+ }
71
+ },
72
+ remove: function(el, name){
73
+ if(settings.addBodyClasses){
74
+ el.className = (el.className).replace(name, "").replace(/^\s+|\s+$/g, '');
75
+ }
76
+ }
77
+ },
78
+ dispatchEvent: function(type) {
79
+ if (typeof eventList[type] === 'function') {
80
+ return eventList[type].call();
81
+ }
82
+ },
83
+ vendor: function(){
84
+ var tmp = doc.createElement("div"),
85
+ prefixes = 'webkit Moz O ms'.split(' '),
86
+ i;
87
+ for (i in prefixes) {
88
+ if (typeof tmp.style[prefixes[i] + 'Transition'] !== 'undefined') {
89
+ return prefixes[i];
90
+ }
91
+ }
92
+ },
93
+ transitionCallback: function(){
94
+ return (cache.vendor==='Moz' || cache.vendor==='ms') ? 'transitionend' : cache.vendor+'TransitionEnd';
95
+ },
96
+ canTransform: function(){
97
+ return typeof settings.element.style[cache.vendor+'Transform'] !== 'undefined';
98
+ },
99
+ deepExtend: function(destination, source) {
100
+ var property;
101
+ for (property in source) {
102
+ if (source[property] && source[property].constructor && source[property].constructor === Object) {
103
+ destination[property] = destination[property] || {};
104
+ utils.deepExtend(destination[property], source[property]);
105
+ } else {
106
+ destination[property] = source[property];
107
+ }
108
+ }
109
+ return destination;
110
+ },
111
+ angleOfDrag: function(x, y) {
112
+ var degrees, theta;
113
+ // Calc Theta
114
+ theta = Math.atan2(-(cache.startDragY - y), (cache.startDragX - x));
115
+ if (theta < 0) {
116
+ theta += 2 * Math.PI;
117
+ }
118
+ // Calc Degrees
119
+ degrees = Math.floor(theta * (180 / Math.PI) - 180);
120
+ if (degrees < 0 && degrees > -180) {
121
+ degrees = 360 - Math.abs(degrees);
122
+ }
123
+ return Math.abs(degrees);
124
+ },
125
+ events: {
126
+ addEvent: function addEvent(element, eventName, func) {
127
+ if (element.addEventListener) {
128
+ return element.addEventListener(eventName, func, false);
129
+ } else if (element.attachEvent) {
130
+ return element.attachEvent("on" + eventName, func);
131
+ }
132
+ },
133
+ removeEvent: function addEvent(element, eventName, func) {
134
+ if (element.addEventListener) {
135
+ return element.removeEventListener(eventName, func, false);
136
+ } else if (element.attachEvent) {
137
+ return element.detachEvent("on" + eventName, func);
138
+ }
139
+ },
140
+ prevent: function(e) {
141
+ if (e.preventDefault) {
142
+ e.preventDefault();
143
+ } else {
144
+ e.returnValue = false;
145
+ }
146
+ }
147
+ },
148
+ parentUntil: function(el, attr) {
149
+ var isStr = typeof attr === 'string';
150
+ while (el.parentNode) {
151
+ if (isStr && el.getAttribute && el.getAttribute(attr)){
152
+ return el;
153
+ } else if(!isStr && el === attr){
154
+ return el;
155
+ }
156
+ el = el.parentNode;
157
+ }
158
+ return null;
159
+ }
160
+ },
161
+ action = {
162
+ translate: {
163
+ get: {
164
+ matrix: function(index) {
165
+
166
+ if( !utils.canTransform() ){
167
+ return parseInt(settings.element.style.left, 10);
168
+ } else {
169
+ var matrix = win.getComputedStyle(settings.element)[cache.vendor+'Transform'].match(/\((.*)\)/),
170
+ ieOffset = 8;
171
+ if (matrix) {
172
+ matrix = matrix[1].split(',');
173
+ if(matrix.length===16){
174
+ index+=ieOffset;
175
+ }
176
+ return parseInt(matrix[index], 10);
177
+ }
178
+ return 0;
179
+ }
180
+ }
181
+ },
182
+ easeCallback: function(){
183
+ settings.element.style[cache.vendor+'Transition'] = '';
184
+ cache.translation = action.translate.get.matrix(4);
185
+ cache.easing = false;
186
+ clearInterval(cache.animatingInterval);
187
+
188
+ if(cache.easingTo===0){
189
+ utils.klass.remove(doc.body, 'snapjs-right');
190
+ utils.klass.remove(doc.body, 'snapjs-left');
191
+ }
192
+
193
+ utils.dispatchEvent('animated');
194
+ utils.events.removeEvent(settings.element, utils.transitionCallback(), action.translate.easeCallback);
195
+ },
196
+ easeTo: function(n) {
197
+
198
+ if( !utils.canTransform() ){
199
+ cache.translation = n;
200
+ action.translate.x(n);
201
+ } else {
202
+ cache.easing = true;
203
+ cache.easingTo = n;
204
+
205
+ settings.element.style[cache.vendor+'Transition'] = 'all ' + settings.transitionSpeed + 's ' + settings.easing;
206
+
207
+ cache.animatingInterval = setInterval(function() {
208
+ utils.dispatchEvent('animating');
209
+ }, 1);
210
+
211
+ utils.events.addEvent(settings.element, utils.transitionCallback(), action.translate.easeCallback);
212
+ action.translate.x(n);
213
+ }
214
+ if(n===0){
215
+ settings.element.style[cache.vendor+'Transform'] = '';
216
+ }
217
+ },
218
+ x: function(n) {
219
+ if( (settings.disable==='left' && n>0) ||
220
+ (settings.disable==='right' && n<0)
221
+ ){ return; }
222
+
223
+ if( !settings.hyperextensible ){
224
+ if( n===settings.maxPosition || n>settings.maxPosition ){
225
+ n=settings.maxPosition;
226
+ } else if( n===settings.minPosition || n<settings.minPosition ){
227
+ n=settings.minPosition;
228
+ }
229
+ }
230
+
231
+ n = parseInt(n, 10);
232
+ if(isNaN(n)){
233
+ n = 0;
234
+ }
235
+
236
+ if( utils.canTransform() ){
237
+ var theTranslate = 'translate3d(' + n + 'px, 0,0)';
238
+ settings.element.style[cache.vendor+'Transform'] = theTranslate;
239
+ } else {
240
+ settings.element.style.width = (win.innerWidth || doc.documentElement.clientWidth)+'px';
241
+
242
+ settings.element.style.left = n+'px';
243
+ settings.element.style.right = '';
244
+ }
245
+ }
246
+ },
247
+ drag: {
248
+ listen: function() {
249
+ cache.translation = 0;
250
+ cache.easing = false;
251
+ utils.events.addEvent(settings.element, utils.eventType('down'), action.drag.startDrag);
252
+ utils.events.addEvent(settings.element, utils.eventType('move'), action.drag.dragging);
253
+ utils.events.addEvent(settings.element, utils.eventType('up'), action.drag.endDrag);
254
+ },
255
+ stopListening: function() {
256
+ utils.events.removeEvent(settings.element, utils.eventType('down'), action.drag.startDrag);
257
+ utils.events.removeEvent(settings.element, utils.eventType('move'), action.drag.dragging);
258
+ utils.events.removeEvent(settings.element, utils.eventType('up'), action.drag.endDrag);
259
+ },
260
+ startDrag: function(e) {
261
+ // No drag on ignored elements
262
+ var target = e.target ? e.target : e.srcElement,
263
+ ignoreParent = utils.parentUntil(target, 'data-snap-ignore');
264
+
265
+ if (ignoreParent) {
266
+ utils.dispatchEvent('ignore');
267
+ return;
268
+ }
269
+
270
+
271
+ if(settings.dragger){
272
+ var dragParent = utils.parentUntil(target, settings.dragger);
273
+
274
+ // Only use dragger if we're in a closed state
275
+ if( !dragParent &&
276
+ (cache.translation !== settings.minPosition &&
277
+ cache.translation !== settings.maxPosition
278
+ )){
279
+ return;
280
+ }
281
+ }
282
+
283
+ utils.dispatchEvent('start');
284
+ settings.element.style[cache.vendor+'Transition'] = '';
285
+ cache.isDragging = true;
286
+ cache.hasIntent = null;
287
+ cache.intentChecked = false;
288
+ cache.startDragX = utils.page('X', e);
289
+ cache.startDragY = utils.page('Y', e);
290
+ cache.dragWatchers = {
291
+ current: 0,
292
+ last: 0,
293
+ hold: 0,
294
+ state: ''
295
+ };
296
+ cache.simpleStates = {
297
+ opening: null,
298
+ towards: null,
299
+ hyperExtending: null,
300
+ halfway: null,
301
+ flick: null,
302
+ translation: {
303
+ absolute: 0,
304
+ relative: 0,
305
+ sinceDirectionChange: 0,
306
+ percentage: 0
307
+ }
308
+ };
309
+ },
310
+ dragging: function(e) {
311
+ if (cache.isDragging && settings.touchToDrag) {
312
+
313
+ var thePageX = utils.page('X', e),
314
+ thePageY = utils.page('Y', e),
315
+ translated = cache.translation,
316
+ absoluteTranslation = action.translate.get.matrix(4),
317
+ whileDragX = thePageX - cache.startDragX,
318
+ openingLeft = absoluteTranslation > 0,
319
+ translateTo = whileDragX,
320
+ diff;
321
+
322
+ // Shown no intent already
323
+ if((cache.intentChecked && !cache.hasIntent)){
324
+ return;
325
+ }
326
+
327
+ if(settings.addBodyClasses){
328
+ if((absoluteTranslation)>0){
329
+ utils.klass.add(doc.body, 'snapjs-left');
330
+ utils.klass.remove(doc.body, 'snapjs-right');
331
+ } else if((absoluteTranslation)<0){
332
+ utils.klass.add(doc.body, 'snapjs-right');
333
+ utils.klass.remove(doc.body, 'snapjs-left');
334
+ }
335
+ }
336
+
337
+ if (cache.hasIntent === false || cache.hasIntent === null) {
338
+ var deg = utils.angleOfDrag(thePageX, thePageY),
339
+ inRightRange = (deg >= 0 && deg <= settings.slideIntent) || (deg <= 360 && deg > (360 - settings.slideIntent)),
340
+ inLeftRange = (deg >= 180 && deg <= (180 + settings.slideIntent)) || (deg <= 180 && deg >= (180 - settings.slideIntent));
341
+ if (!inLeftRange && !inRightRange) {
342
+ cache.hasIntent = false;
343
+ } else {
344
+ cache.hasIntent = true;
345
+ }
346
+ cache.intentChecked = true;
347
+ }
348
+
349
+ if (
350
+ (settings.minDragDistance>=Math.abs(thePageX-cache.startDragX)) || // Has user met minimum drag distance?
351
+ (cache.hasIntent === false)
352
+ ) {
353
+ return;
354
+ }
355
+
356
+ utils.events.prevent(e);
357
+ utils.dispatchEvent('drag');
358
+
359
+ cache.dragWatchers.current = thePageX;
360
+ // Determine which direction we are going
361
+ if (cache.dragWatchers.last > thePageX) {
362
+ if (cache.dragWatchers.state !== 'left') {
363
+ cache.dragWatchers.state = 'left';
364
+ cache.dragWatchers.hold = thePageX;
365
+ }
366
+ cache.dragWatchers.last = thePageX;
367
+ } else if (cache.dragWatchers.last < thePageX) {
368
+ if (cache.dragWatchers.state !== 'right') {
369
+ cache.dragWatchers.state = 'right';
370
+ cache.dragWatchers.hold = thePageX;
371
+ }
372
+ cache.dragWatchers.last = thePageX;
373
+ }
374
+ if (openingLeft) {
375
+ // Pulling too far to the right
376
+ if (settings.maxPosition < absoluteTranslation) {
377
+ diff = (absoluteTranslation - settings.maxPosition) * settings.resistance;
378
+ translateTo = whileDragX - diff;
379
+ }
380
+ cache.simpleStates = {
381
+ opening: 'left',
382
+ towards: cache.dragWatchers.state,
383
+ hyperExtending: settings.maxPosition < absoluteTranslation,
384
+ halfway: absoluteTranslation > (settings.maxPosition / 2),
385
+ flick: Math.abs(cache.dragWatchers.current - cache.dragWatchers.hold) > settings.flickThreshold,
386
+ translation: {
387
+ absolute: absoluteTranslation,
388
+ relative: whileDragX,
389
+ sinceDirectionChange: (cache.dragWatchers.current - cache.dragWatchers.hold),
390
+ percentage: (absoluteTranslation/settings.maxPosition)*100
391
+ }
392
+ };
393
+ } else {
394
+ // Pulling too far to the left
395
+ if (settings.minPosition > absoluteTranslation) {
396
+ diff = (absoluteTranslation - settings.minPosition) * settings.resistance;
397
+ translateTo = whileDragX - diff;
398
+ }
399
+ cache.simpleStates = {
400
+ opening: 'right',
401
+ towards: cache.dragWatchers.state,
402
+ hyperExtending: settings.minPosition > absoluteTranslation,
403
+ halfway: absoluteTranslation < (settings.minPosition / 2),
404
+ flick: Math.abs(cache.dragWatchers.current - cache.dragWatchers.hold) > settings.flickThreshold,
405
+ translation: {
406
+ absolute: absoluteTranslation,
407
+ relative: whileDragX,
408
+ sinceDirectionChange: (cache.dragWatchers.current - cache.dragWatchers.hold),
409
+ percentage: (absoluteTranslation/settings.minPosition)*100
410
+ }
411
+ };
412
+ }
413
+ action.translate.x(translateTo + translated);
414
+ }
415
+ },
416
+ endDrag: function(e) {
417
+ if (cache.isDragging) {
418
+ utils.dispatchEvent('end');
419
+ var translated = action.translate.get.matrix(4);
420
+
421
+ // Tap Close
422
+ if (cache.dragWatchers.current === 0 && translated !== 0 && settings.tapToClose) {
423
+ utils.dispatchEvent('close');
424
+ utils.events.prevent(e);
425
+ action.translate.easeTo(0);
426
+ cache.isDragging = false;
427
+ cache.startDragX = 0;
428
+ return;
429
+ }
430
+
431
+ // Revealing Left
432
+ if (cache.simpleStates.opening === 'left') {
433
+ // Halfway, Flicking, or Too Far Out
434
+ if ((cache.simpleStates.halfway || cache.simpleStates.hyperExtending || cache.simpleStates.flick)) {
435
+ if (cache.simpleStates.flick && cache.simpleStates.towards === 'left') { // Flicking Closed
436
+ action.translate.easeTo(0);
437
+ } else if (
438
+ (cache.simpleStates.flick && cache.simpleStates.towards === 'right') || // Flicking Open OR
439
+ (cache.simpleStates.halfway || cache.simpleStates.hyperExtending) // At least halfway open OR hyperextending
440
+ ) {
441
+ action.translate.easeTo(settings.maxPosition); // Open Left
442
+ }
443
+ } else {
444
+ action.translate.easeTo(0); // Close Left
445
+ }
446
+ // Revealing Right
447
+ } else if (cache.simpleStates.opening === 'right') {
448
+ // Halfway, Flicking, or Too Far Out
449
+ if ((cache.simpleStates.halfway || cache.simpleStates.hyperExtending || cache.simpleStates.flick)) {
450
+ if (cache.simpleStates.flick && cache.simpleStates.towards === 'right') { // Flicking Closed
451
+ action.translate.easeTo(0);
452
+ } else if (
453
+ (cache.simpleStates.flick && cache.simpleStates.towards === 'left') || // Flicking Open OR
454
+ (cache.simpleStates.halfway || cache.simpleStates.hyperExtending) // At least halfway open OR hyperextending
455
+ ) {
456
+ action.translate.easeTo(settings.minPosition); // Open Right
457
+ }
458
+ } else {
459
+ action.translate.easeTo(0); // Close Right
460
+ }
461
+ }
462
+ cache.isDragging = false;
463
+ cache.startDragX = utils.page('X', e);
464
+ }
465
+ }
466
+ }
467
+ },
468
+ init = function(opts) {
469
+ if (opts.element) {
470
+ utils.deepExtend(settings, opts);
471
+ cache.vendor = utils.vendor();
472
+ action.drag.listen();
473
+ }
474
+ };
475
+ /*
476
+ * Public
477
+ */
478
+ this.open = function(side) {
479
+ utils.dispatchEvent('open');
480
+ utils.klass.remove(doc.body, 'snapjs-expand-left');
481
+ utils.klass.remove(doc.body, 'snapjs-expand-right');
482
+
483
+ if (side === 'left') {
484
+ cache.simpleStates.opening = 'left';
485
+ cache.simpleStates.towards = 'right';
486
+ utils.klass.add(doc.body, 'snapjs-left');
487
+ utils.klass.remove(doc.body, 'snapjs-right');
488
+ action.translate.easeTo(settings.maxPosition);
489
+ } else if (side === 'right') {
490
+ cache.simpleStates.opening = 'right';
491
+ cache.simpleStates.towards = 'left';
492
+ utils.klass.remove(doc.body, 'snapjs-left');
493
+ utils.klass.add(doc.body, 'snapjs-right');
494
+ action.translate.easeTo(settings.minPosition);
495
+ }
496
+ };
497
+ this.close = function() {
498
+ utils.dispatchEvent('close');
499
+ action.translate.easeTo(0);
500
+ };
501
+ this.expand = function(side){
502
+ var to = win.innerWidth || doc.documentElement.clientWidth;
503
+
504
+ if(side==='left'){
505
+ utils.dispatchEvent('expandLeft');
506
+ utils.klass.add(doc.body, 'snapjs-expand-left');
507
+ utils.klass.remove(doc.body, 'snapjs-expand-right');
508
+ } else {
509
+ utils.dispatchEvent('expandRight');
510
+ utils.klass.add(doc.body, 'snapjs-expand-right');
511
+ utils.klass.remove(doc.body, 'snapjs-expand-left');
512
+ to *= -1;
513
+ }
514
+ action.translate.easeTo(to);
515
+ };
516
+
517
+ this.on = function(evt, fn) {
518
+ eventList[evt] = fn;
519
+ return this;
520
+ };
521
+ this.off = function(evt) {
522
+ if (eventList[evt]) {
523
+ eventList[evt] = false;
524
+ }
525
+ };
526
+
527
+ this.enable = function() {
528
+ utils.dispatchEvent('enable');
529
+ action.drag.listen();
530
+ };
531
+ this.disable = function() {
532
+ utils.dispatchEvent('disable');
533
+ action.drag.stopListening();
534
+ };
535
+
536
+ this.settings = function(opts){
537
+ utils.deepExtend(settings, opts);
538
+ };
539
+
540
+ this.state = function() {
541
+ var state,
542
+ fromLeft = action.translate.get.matrix(4);
543
+ if (fromLeft === settings.maxPosition) {
544
+ state = 'left';
545
+ } else if (fromLeft === settings.minPosition) {
546
+ state = 'right';
547
+ } else {
548
+ state = 'closed';
549
+ }
550
+ return {
551
+ state: state,
552
+ info: cache.simpleStates
553
+ };
554
+ };
555
+ init(userOpts);
556
+ };
557
+ if ((typeof module !== 'undefined') && module.exports) {
558
+ module.exports = Snap;
559
+ }
560
+ if (typeof ender === 'undefined') {
561
+ this.Snap = Snap;
562
+ }
563
+ if ((typeof define === "function") && define.amd) {
564
+ define("snap", [], function() {
565
+ return Snap;
566
+ });
567
+ }
562
568
  }).call(this, window, document);