skrollr-rails 0.5.14 → 0.6.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,103 +2,130 @@
2
2
  * Plugin for skrollr.
3
3
  * This plugin makes hashlinks scroll nicely to their target position.
4
4
  *
5
- * https://github.com/Prinzhorn/skrollr
5
+ * Alexander Prinzhorn - https://github.com/Prinzhorn/skrollr
6
6
  *
7
- * free to use under terms of MIT license
8
- */
9
- (function(document, skrollr) {
10
- var DEFAULT_DURATION = 500;
11
- var DEFAULT_EASING = 'sqrt';
12
-
13
- /*
14
- Since we are using event bubbling, the element that has been clicked
15
- might not acutally be the link but a child.
16
- */
17
- var findParentLink = function(element) {
18
- //Yay, it's a link!
19
- if(element.tagName === 'A') {
20
- return element;
21
- }
22
-
23
- //We reached the top, no link found.
24
- if(element === document) {
25
- return false;
26
- }
27
-
28
- //Maybe the parent is a link.
29
- return findParentLink(element.parentNode);
30
- };
31
-
32
- /*
33
- Animate to the element.
34
- */
35
- var scrollToId = function(id, duration, easing) {
36
- //Grab the target element.
37
- var scrollTarget = document.getElementById(id);
38
-
39
- if(!scrollTarget) {
40
- return false;
41
- }
42
-
43
- //Get the position to scroll to.
44
- var offset = _skrollrInstance.relativeToAbsolute(scrollTarget, 'top', 'top');
45
-
46
- //Now finally scroll there.
47
- _skrollrInstance.animateTo(offset, {
48
- duration: duration,
49
- easing: easing
50
- });
51
-
52
- return true;
53
- };
54
-
55
- /*
56
- Handle the click event on the document.
57
- */
58
- var handleClick = function(e) {
59
- var link = findParentLink(e.target);
60
-
61
- //The click did not happen inside a link.
62
- if(!link) {
63
- return;
64
- }
65
-
66
- //Don't use the href property because it contains the full url.
67
- var href = link.getAttribute('href');
68
-
69
- //Check if it's a hashlink.
70
- if(href.indexOf('#') !== 0) {
71
- return;
72
- }
73
-
74
- //Great, it's a hashlink. Scroll to the element.
75
- var id = href.substr(1);
76
- var scollSuccess = scrollToId(id, DEFAULT_DURATION, DEFAULT_EASING);
77
-
78
- if(scollSuccess) {
79
- e.preventDefault();
80
- }
81
- };
82
-
83
- /*
84
- Global menu function accessible through window.skrollr.menu.init.
85
- */
86
- skrollr.menu = {};
87
- skrollr.menu.init = function(skrollrInstance) {
88
- _skrollrInstance = skrollrInstance;
89
-
90
- //Use event bubbling and attach a single listener to the document.
91
- skrollr.addEvent(document, 'click', handleClick);
92
- };
93
-
94
- //Private reference to the initialized skrollr.
95
- var _skrollrInstance;
96
-
97
- //In case the page was opened with a hash, prevent jumping to it.
98
- //http://stackoverflow.com/questions/3659072/jquery-disable-anchor-jump-when-loading-a-page
99
- window.setTimeout(function() {
100
- if(location.hash) {
101
- window.scrollTo(0, 0);
102
- }
103
- }, 1);
104
- }(document, window.skrollr));
7
+ * Free to use under terms of MIT license
8
+ */ (function(document, window) {
9
+ 'use strict';
10
+
11
+ var DEFAULT_DURATION = 500;
12
+ var DEFAULT_EASING = 'sqrt';
13
+
14
+ var MENU_TOP_ATTR = 'data-menu-top';
15
+ var MENU_OFFSET_ATTR = 'data-menu-offset';
16
+
17
+ var skrollr = window.skrollr;
18
+
19
+ /*
20
+ Since we are using event bubbling, the element that has been clicked
21
+ might not acutally be the link but a child.
22
+ */
23
+ var findParentLink = function(element) {
24
+ //Yay, it's a link!
25
+ if (element.tagName === 'A') {
26
+ return element;
27
+ }
28
+
29
+ //We reached the top, no link found.
30
+ if (element === document) {
31
+ return false;
32
+ }
33
+
34
+ //Maybe the parent is a link.
35
+ return findParentLink(element.parentNode);
36
+ };
37
+
38
+ /*
39
+ Handle the click event on the document.
40
+ */
41
+ var handleClick = function(e) {
42
+ //Only handle left click.
43
+ if ((e.which || e.button) !== 1) {
44
+ return;
45
+ }
46
+
47
+ var link = findParentLink(e.target);
48
+
49
+ //The click did not happen inside a link.
50
+ if (!link) {
51
+ return;
52
+ }
53
+
54
+ //Don't use the href property (link.href) because it contains the absolute url.
55
+ var href = link.getAttribute('href');
56
+
57
+ //Check if it's a hashlink.
58
+ if (!/^#/.test(href)) {
59
+ return;
60
+ }
61
+
62
+ //Now get the targetTop to scroll to.
63
+ var targetTop;
64
+
65
+ //If there's a data-menu-top attribute, it overrides the actuall anchor offset.
66
+ var menuTop = link.getAttribute(MENU_TOP_ATTR);
67
+
68
+ if (menuTop !== null) {
69
+ targetTop = +menuTop;
70
+ } else {
71
+ var scrollTarget = document.getElementById(href.substr(1));
72
+
73
+ //Ignore the click if no target is found.
74
+ if (!scrollTarget) {
75
+ return;
76
+ }
77
+
78
+ targetTop = _skrollrInstance.relativeToAbsolute(scrollTarget, 'top', 'top');
79
+
80
+ var menuOffset = scrollTarget.getAttribute(MENU_OFFSET_ATTR);
81
+
82
+ if (menuOffset !== null) {
83
+ targetTop += +menuOffset;
84
+ }
85
+ }
86
+
87
+ //Now finally scroll there.
88
+ if (_animate) {
89
+ _skrollrInstance.animateTo(targetTop, {
90
+ duration: _duration,
91
+ easing: _easing
92
+ });
93
+ } else {
94
+ _skrollrInstance.setScrollTop(targetTop);
95
+ }
96
+
97
+ e.preventDefault();
98
+ };
99
+
100
+ /*
101
+ Global menu function accessible through window.skrollr.menu.init.
102
+ */
103
+ skrollr.menu = {};
104
+ skrollr.menu.init = function(skrollrInstance, options) {
105
+ _skrollrInstance = skrollrInstance;
106
+
107
+ options = options || {};
108
+
109
+ _duration = options.duration || DEFAULT_DURATION;
110
+ _easing = options.easing || DEFAULT_EASING;
111
+ _animate = options.animate !== false;
112
+
113
+ //Use event bubbling and attach a single listener to the document.
114
+ skrollr.addEvent(document, 'click', handleClick);
115
+ };
116
+
117
+ //Private reference to the initialized skrollr.
118
+ var _skrollrInstance;
119
+
120
+ var _easing;
121
+ var _duration;
122
+ var _animate;
123
+
124
+ //In case the page was opened with a hash, prevent jumping to it.
125
+ //http://stackoverflow.com/questions/3659072/jquery-disable-anchor-jump-when-loading-a-page
126
+ window.setTimeout(function() {
127
+ if (window.location.hash) {
128
+ window.scrollTo(0, 0);
129
+ }
130
+ }, 1);
131
+ }(document, window));
metadata CHANGED
@@ -1,27 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: skrollr-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.14
5
- prerelease:
4
+ version: 0.6.4
6
5
  platform: ruby
7
6
  authors:
8
7
  - Nick Reed
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-02-21 00:00:00.000000000 Z
11
+ date: 2013-05-21 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: rails
16
- requirement: &70121688733060 !ruby/object:Gem::Requirement
17
- none: false
15
+ requirement: !ruby/object:Gem::Requirement
18
16
  requirements:
19
- - - ! '>='
17
+ - - '>='
20
18
  - !ruby/object:Gem::Version
21
19
  version: 3.1.0
22
20
  type: :runtime
23
21
  prerelease: false
24
- version_requirements: *70121688733060
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: 3.1.0
25
27
  description: Integrates the skrollr javascript library with the Rails asset pipeline
26
28
  email:
27
29
  - reednj77@gmail.com
@@ -41,36 +43,28 @@ files:
41
43
  - vendor/assets/javascripts/skrollr.ie.js
42
44
  - vendor/assets/javascripts/skrollr.js
43
45
  - vendor/assets/javascripts/skrollr.menu.js
44
- - vendor/assets/javascripts/skrollr.mobile.js
45
- homepage: https://github.com/reednj77/skrollr-rails
46
+ homepage: https://github.com/reed/skrollr-rails
46
47
  licenses: []
48
+ metadata: {}
47
49
  post_install_message:
48
50
  rdoc_options: []
49
51
  require_paths:
50
52
  - lib
51
53
  required_ruby_version: !ruby/object:Gem::Requirement
52
- none: false
53
54
  requirements:
54
- - - ! '>='
55
+ - - '>='
55
56
  - !ruby/object:Gem::Version
56
57
  version: '0'
57
- segments:
58
- - 0
59
- hash: -508049786068435937
60
58
  required_rubygems_version: !ruby/object:Gem::Requirement
61
- none: false
62
59
  requirements:
63
- - - ! '>='
60
+ - - '>='
64
61
  - !ruby/object:Gem::Version
65
62
  version: '0'
66
- segments:
67
- - 0
68
- hash: -508049786068435937
69
63
  requirements: []
70
64
  rubyforge_project:
71
- rubygems_version: 1.8.10
65
+ rubygems_version: 2.0.3
72
66
  signing_key:
73
- specification_version: 3
67
+ specification_version: 4
74
68
  summary: Skrollr is a stand-alone parallax scrolling library for mobile and desktop. This
75
69
  gem integrates skrollr with the Rails asset pipeline for ease of use and version
76
70
  control.
@@ -1,1136 +0,0 @@
1
- /*!
2
- * iScroll v4.2.4 ~ Copyright (c) 2012 Matteo Spinelli, http://cubiq.org
3
- * Released under MIT license, http://cubiq.org/license
4
- */
5
- (function(window, doc){
6
- var m = Math,
7
- dummyStyle = doc.createElement('div').style,
8
- vendor = (function () {
9
- var vendors = 't,webkitT,MozT,msT,OT'.split(','),
10
- t,
11
- i = 0,
12
- l = vendors.length;
13
-
14
- for ( ; i < l; i++ ) {
15
- t = vendors[i] + 'ransform';
16
- if ( t in dummyStyle ) {
17
- return vendors[i].substr(0, vendors[i].length - 1);
18
- }
19
- }
20
-
21
- return false;
22
- })(),
23
- cssVendor = vendor ? '-' + vendor.toLowerCase() + '-' : '',
24
-
25
- // Style properties
26
- transform = prefixStyle('transform'),
27
- transitionProperty = prefixStyle('transitionProperty'),
28
- transitionDuration = prefixStyle('transitionDuration'),
29
- transformOrigin = prefixStyle('transformOrigin'),
30
- transitionTimingFunction = prefixStyle('transitionTimingFunction'),
31
- transitionDelay = prefixStyle('transitionDelay'),
32
-
33
- // Browser capabilities
34
- isAndroid = (/android/gi).test(navigator.appVersion),
35
- isIDevice = (/iphone|ipad/gi).test(navigator.appVersion),
36
- isTouchPad = (/hp-tablet/gi).test(navigator.appVersion),
37
-
38
- has3d = prefixStyle('perspective') in dummyStyle,
39
- hasTouch = 'ontouchstart' in window && !isTouchPad,
40
- hasTransform = vendor !== false,
41
- hasTransitionEnd = prefixStyle('transition') in dummyStyle,
42
-
43
- RESIZE_EV = 'onorientationchange' in window ? 'orientationchange' : 'resize',
44
- START_EV = hasTouch ? 'touchstart' : 'mousedown',
45
- MOVE_EV = hasTouch ? 'touchmove' : 'mousemove',
46
- END_EV = hasTouch ? 'touchend' : 'mouseup',
47
- CANCEL_EV = hasTouch ? 'touchcancel' : 'mouseup',
48
- TRNEND_EV = (function () {
49
- if ( vendor === false ) return false;
50
-
51
- var transitionEnd = {
52
- '' : 'transitionend',
53
- 'webkit' : 'webkitTransitionEnd',
54
- 'Moz' : 'transitionend',
55
- 'O' : 'otransitionend',
56
- 'ms' : 'MSTransitionEnd'
57
- };
58
-
59
- return transitionEnd[vendor];
60
- })(),
61
-
62
- nextFrame = (function() {
63
- return window.requestAnimationFrame ||
64
- window.webkitRequestAnimationFrame ||
65
- window.mozRequestAnimationFrame ||
66
- window.oRequestAnimationFrame ||
67
- window.msRequestAnimationFrame ||
68
- function(callback) { return setTimeout(callback, 1); };
69
- })(),
70
- cancelFrame = (function () {
71
- return window.cancelRequestAnimationFrame ||
72
- window.webkitCancelAnimationFrame ||
73
- window.webkitCancelRequestAnimationFrame ||
74
- window.mozCancelRequestAnimationFrame ||
75
- window.oCancelRequestAnimationFrame ||
76
- window.msCancelRequestAnimationFrame ||
77
- clearTimeout;
78
- })(),
79
-
80
- // Helpers
81
- translateZ = has3d ? ' translateZ(0)' : '',
82
-
83
- // Constructor
84
- iScroll = function (el, options) {
85
- var that = this,
86
- i;
87
-
88
- that.wrapper = typeof el == 'object' ? el : doc.getElementById(el);
89
- that.wrapper.style.overflow = 'hidden';
90
- that.scroller = that.wrapper.children[0];
91
-
92
- // Default options
93
- that.options = {
94
- hScroll: true,
95
- vScroll: true,
96
- x: 0,
97
- y: 0,
98
- bounce: true,
99
- bounceLock: false,
100
- momentum: true,
101
- lockDirection: true,
102
- useTransform: true,
103
- useTransition: false,
104
- topOffset: 0,
105
- checkDOMChanges: false, // Experimental
106
- handleClick: true,
107
-
108
- // Scrollbar
109
- hScrollbar: true,
110
- vScrollbar: true,
111
- fixedScrollbar: isAndroid,
112
- hideScrollbar: isIDevice,
113
- fadeScrollbar: isIDevice && has3d,
114
- scrollbarClass: '',
115
-
116
- // Zoom
117
- zoom: false,
118
- zoomMin: 1,
119
- zoomMax: 4,
120
- doubleTapZoom: 2,
121
- wheelAction: 'scroll',
122
-
123
- // Snap
124
- snap: false,
125
- snapThreshold: 1,
126
-
127
- // Events
128
- onRefresh: null,
129
- onBeforeScrollStart: function (e) { e.preventDefault(); },
130
- onScrollStart: null,
131
- onBeforeScrollMove: null,
132
- onScrollMove: null,
133
- onBeforeScrollEnd: null,
134
- onScrollEnd: null,
135
- onTouchEnd: null,
136
- onDestroy: null,
137
- onZoomStart: null,
138
- onZoom: null,
139
- onZoomEnd: null
140
- };
141
-
142
- // User defined options
143
- for (i in options) that.options[i] = options[i];
144
-
145
- // Set starting position
146
- that.x = that.options.x;
147
- that.y = that.options.y;
148
-
149
- // Normalize options
150
- that.options.useTransform = hasTransform && that.options.useTransform;
151
- that.options.hScrollbar = that.options.hScroll && that.options.hScrollbar;
152
- that.options.vScrollbar = that.options.vScroll && that.options.vScrollbar;
153
- that.options.zoom = that.options.useTransform && that.options.zoom;
154
- that.options.useTransition = hasTransitionEnd && that.options.useTransition;
155
-
156
- // Helpers FIX ANDROID BUG!
157
- // translate3d and scale doesn't work together!
158
- // Ignoring 3d ONLY WHEN YOU SET that.options.zoom
159
- if ( that.options.zoom && isAndroid ){
160
- translateZ = '';
161
- }
162
-
163
- // Set some default styles
164
- that.scroller.style[transitionProperty] = that.options.useTransform ? cssVendor + 'transform' : 'top left';
165
- that.scroller.style[transitionDuration] = '0';
166
- that.scroller.style[transformOrigin] = '0 0';
167
- if (that.options.useTransition) that.scroller.style[transitionTimingFunction] = 'cubic-bezier(0.33,0.66,0.66,1)';
168
-
169
- if (that.options.useTransform) that.scroller.style[transform] = 'translate(' + that.x + 'px,' + that.y + 'px)' + translateZ;
170
- else that.scroller.style.cssText += ';position:absolute;top:' + that.y + 'px;left:' + that.x + 'px';
171
-
172
- if (that.options.useTransition) that.options.fixedScrollbar = true;
173
-
174
- that.refresh();
175
-
176
- that._bind(RESIZE_EV, window);
177
- that._bind(START_EV);
178
- if (!hasTouch) {
179
- if (that.options.wheelAction != 'none') {
180
- that._bind('DOMMouseScroll');
181
- that._bind('mousewheel');
182
- }
183
- }
184
-
185
- if (that.options.checkDOMChanges) that.checkDOMTime = setInterval(function () {
186
- that._checkDOMChanges();
187
- }, 500);
188
- };
189
-
190
- // Prototype
191
- iScroll.prototype = {
192
- enabled: true,
193
- x: 0,
194
- y: 0,
195
- steps: [],
196
- scale: 1,
197
- currPageX: 0, currPageY: 0,
198
- pagesX: [], pagesY: [],
199
- aniTime: null,
200
- wheelZoomCount: 0,
201
-
202
- handleEvent: function (e) {
203
- var that = this;
204
- switch(e.type) {
205
- case START_EV:
206
- if (!hasTouch && e.button !== 0) return;
207
- that._start(e);
208
- break;
209
- case MOVE_EV: that._move(e); break;
210
- case END_EV:
211
- case CANCEL_EV: that._end(e); break;
212
- case RESIZE_EV: that._resize(); break;
213
- case 'DOMMouseScroll': case 'mousewheel': that._wheel(e); break;
214
- case TRNEND_EV: that._transitionEnd(e); break;
215
- }
216
- },
217
-
218
- _checkDOMChanges: function () {
219
- if (this.moved || this.zoomed || this.animating ||
220
- (this.scrollerW == this.scroller.offsetWidth * this.scale && this.scrollerH == this.scroller.offsetHeight * this.scale)) return;
221
-
222
- this.refresh();
223
- },
224
-
225
- _scrollbar: function (dir) {
226
- var that = this,
227
- bar;
228
-
229
- if (!that[dir + 'Scrollbar']) {
230
- if (that[dir + 'ScrollbarWrapper']) {
231
- if (hasTransform) that[dir + 'ScrollbarIndicator'].style[transform] = '';
232
- that[dir + 'ScrollbarWrapper'].parentNode.removeChild(that[dir + 'ScrollbarWrapper']);
233
- that[dir + 'ScrollbarWrapper'] = null;
234
- that[dir + 'ScrollbarIndicator'] = null;
235
- }
236
-
237
- return;
238
- }
239
-
240
- if (!that[dir + 'ScrollbarWrapper']) {
241
- // Create the scrollbar wrapper
242
- bar = doc.createElement('div');
243
-
244
- if (that.options.scrollbarClass) bar.className = that.options.scrollbarClass + dir.toUpperCase();
245
- else bar.style.cssText = 'position:absolute;z-index:100;' + (dir == 'h' ? 'height:7px;bottom:1px;left:2px;right:' + (that.vScrollbar ? '7' : '2') + 'px' : 'width:7px;bottom:' + (that.hScrollbar ? '7' : '2') + 'px;top:2px;right:1px');
246
-
247
- bar.style.cssText += ';pointer-events:none;' + cssVendor + 'transition-property:opacity;' + cssVendor + 'transition-duration:' + (that.options.fadeScrollbar ? '350ms' : '0') + ';overflow:hidden;opacity:' + (that.options.hideScrollbar ? '0' : '1');
248
-
249
- that.wrapper.appendChild(bar);
250
- that[dir + 'ScrollbarWrapper'] = bar;
251
-
252
- // Create the scrollbar indicator
253
- bar = doc.createElement('div');
254
- if (!that.options.scrollbarClass) {
255
- bar.style.cssText = 'position:absolute;z-index:100;background:rgba(0,0,0,0.5);border:1px solid rgba(255,255,255,0.9);' + cssVendor + 'background-clip:padding-box;' + cssVendor + 'box-sizing:border-box;' + (dir == 'h' ? 'height:100%' : 'width:100%') + ';' + cssVendor + 'border-radius:3px;border-radius:3px';
256
- }
257
- bar.style.cssText += ';pointer-events:none;' + cssVendor + 'transition-property:' + cssVendor + 'transform;' + cssVendor + 'transition-timing-function:cubic-bezier(0.33,0.66,0.66,1);' + cssVendor + 'transition-duration:0;' + cssVendor + 'transform: translate(0,0)' + translateZ;
258
- if (that.options.useTransition) bar.style.cssText += ';' + cssVendor + 'transition-timing-function:cubic-bezier(0.33,0.66,0.66,1)';
259
-
260
- that[dir + 'ScrollbarWrapper'].appendChild(bar);
261
- that[dir + 'ScrollbarIndicator'] = bar;
262
- }
263
-
264
- if (dir == 'h') {
265
- that.hScrollbarSize = that.hScrollbarWrapper.clientWidth;
266
- that.hScrollbarIndicatorSize = m.max(m.round(that.hScrollbarSize * that.hScrollbarSize / that.scrollerW), 8);
267
- that.hScrollbarIndicator.style.width = that.hScrollbarIndicatorSize + 'px';
268
- that.hScrollbarMaxScroll = that.hScrollbarSize - that.hScrollbarIndicatorSize;
269
- that.hScrollbarProp = that.hScrollbarMaxScroll / that.maxScrollX;
270
- } else {
271
- that.vScrollbarSize = that.vScrollbarWrapper.clientHeight;
272
- that.vScrollbarIndicatorSize = m.max(m.round(that.vScrollbarSize * that.vScrollbarSize / that.scrollerH), 8);
273
- that.vScrollbarIndicator.style.height = that.vScrollbarIndicatorSize + 'px';
274
- that.vScrollbarMaxScroll = that.vScrollbarSize - that.vScrollbarIndicatorSize;
275
- that.vScrollbarProp = that.vScrollbarMaxScroll / that.maxScrollY;
276
- }
277
-
278
- // Reset position
279
- that._scrollbarPos(dir, true);
280
- },
281
-
282
- _resize: function () {
283
- var that = this;
284
- setTimeout(function () { that.refresh(); }, isAndroid ? 200 : 0);
285
- },
286
-
287
- _pos: function (x, y) {
288
- if (this.zoomed) return;
289
-
290
- x = this.hScroll ? x : 0;
291
- y = this.vScroll ? y : 0;
292
-
293
- if (this.options.useTransform) {
294
- this.scroller.style[transform] = 'translate(' + x + 'px,' + y + 'px) scale(' + this.scale + ')' + translateZ;
295
- } else {
296
- x = m.round(x);
297
- y = m.round(y);
298
- this.scroller.style.left = x + 'px';
299
- this.scroller.style.top = y + 'px';
300
- }
301
-
302
- this.x = x;
303
- this.y = y;
304
-
305
- this._scrollbarPos('h');
306
- this._scrollbarPos('v');
307
- },
308
-
309
- _scrollbarPos: function (dir, hidden) {
310
- var that = this,
311
- pos = dir == 'h' ? that.x : that.y,
312
- size;
313
-
314
- if (!that[dir + 'Scrollbar']) return;
315
-
316
- pos = that[dir + 'ScrollbarProp'] * pos;
317
-
318
- if (pos < 0) {
319
- if (!that.options.fixedScrollbar) {
320
- size = that[dir + 'ScrollbarIndicatorSize'] + m.round(pos * 3);
321
- if (size < 8) size = 8;
322
- that[dir + 'ScrollbarIndicator'].style[dir == 'h' ? 'width' : 'height'] = size + 'px';
323
- }
324
- pos = 0;
325
- } else if (pos > that[dir + 'ScrollbarMaxScroll']) {
326
- if (!that.options.fixedScrollbar) {
327
- size = that[dir + 'ScrollbarIndicatorSize'] - m.round((pos - that[dir + 'ScrollbarMaxScroll']) * 3);
328
- if (size < 8) size = 8;
329
- that[dir + 'ScrollbarIndicator'].style[dir == 'h' ? 'width' : 'height'] = size + 'px';
330
- pos = that[dir + 'ScrollbarMaxScroll'] + (that[dir + 'ScrollbarIndicatorSize'] - size);
331
- } else {
332
- pos = that[dir + 'ScrollbarMaxScroll'];
333
- }
334
- }
335
-
336
- that[dir + 'ScrollbarWrapper'].style[transitionDelay] = '0';
337
- that[dir + 'ScrollbarWrapper'].style.opacity = hidden && that.options.hideScrollbar ? '0' : '1';
338
- that[dir + 'ScrollbarIndicator'].style[transform] = 'translate(' + (dir == 'h' ? pos + 'px,0)' : '0,' + pos + 'px)') + translateZ;
339
- },
340
-
341
- _start: function (e) {
342
- var that = this,
343
- point = hasTouch ? e.touches[0] : e,
344
- matrix, x, y,
345
- c1, c2;
346
-
347
- if (!that.enabled) return;
348
-
349
- if (that.options.onBeforeScrollStart) that.options.onBeforeScrollStart.call(that, e);
350
-
351
- if (that.options.useTransition || that.options.zoom) that._transitionTime(0);
352
-
353
- that.moved = false;
354
- that.animating = false;
355
- that.zoomed = false;
356
- that.distX = 0;
357
- that.distY = 0;
358
- that.absDistX = 0;
359
- that.absDistY = 0;
360
- that.dirX = 0;
361
- that.dirY = 0;
362
-
363
- // Gesture start
364
- if (that.options.zoom && hasTouch && e.touches.length > 1) {
365
- c1 = m.abs(e.touches[0].pageX-e.touches[1].pageX);
366
- c2 = m.abs(e.touches[0].pageY-e.touches[1].pageY);
367
- that.touchesDistStart = m.sqrt(c1 * c1 + c2 * c2);
368
-
369
- that.originX = m.abs(e.touches[0].pageX + e.touches[1].pageX - that.wrapperOffsetLeft * 2) / 2 - that.x;
370
- that.originY = m.abs(e.touches[0].pageY + e.touches[1].pageY - that.wrapperOffsetTop * 2) / 2 - that.y;
371
-
372
- if (that.options.onZoomStart) that.options.onZoomStart.call(that, e);
373
- }
374
-
375
- if (that.options.momentum) {
376
- if (that.options.useTransform) {
377
- // Very lame general purpose alternative to CSSMatrix
378
- matrix = getComputedStyle(that.scroller, null)[transform].replace(/[^0-9\-.,]/g, '').split(',');
379
- x = +matrix[4];
380
- y = +matrix[5];
381
- } else {
382
- x = +getComputedStyle(that.scroller, null).left.replace(/[^0-9-]/g, '');
383
- y = +getComputedStyle(that.scroller, null).top.replace(/[^0-9-]/g, '');
384
- }
385
-
386
- if (x != that.x || y != that.y) {
387
- if (that.options.useTransition) that._unbind(TRNEND_EV);
388
- else cancelFrame(that.aniTime);
389
- that.steps = [];
390
- that._pos(x, y);
391
- if (that.options.onScrollEnd) that.options.onScrollEnd.call(that);
392
- }
393
- }
394
-
395
- that.absStartX = that.x; // Needed by snap threshold
396
- that.absStartY = that.y;
397
-
398
- that.startX = that.x;
399
- that.startY = that.y;
400
- that.pointX = point.pageX;
401
- that.pointY = point.pageY;
402
-
403
- that.startTime = e.timeStamp || Date.now();
404
-
405
- if (that.options.onScrollStart) that.options.onScrollStart.call(that, e);
406
-
407
- that._bind(MOVE_EV, window);
408
- that._bind(END_EV, window);
409
- that._bind(CANCEL_EV, window);
410
- },
411
-
412
- _move: function (e) {
413
- var that = this,
414
- point = hasTouch ? e.touches[0] : e,
415
- deltaX = point.pageX - that.pointX,
416
- deltaY = point.pageY - that.pointY,
417
- newX = that.x + deltaX,
418
- newY = that.y + deltaY,
419
- c1, c2, scale,
420
- timestamp = e.timeStamp || Date.now();
421
-
422
- if (that.options.onBeforeScrollMove) that.options.onBeforeScrollMove.call(that, e);
423
-
424
- // Zoom
425
- if (that.options.zoom && hasTouch && e.touches.length > 1) {
426
- c1 = m.abs(e.touches[0].pageX - e.touches[1].pageX);
427
- c2 = m.abs(e.touches[0].pageY - e.touches[1].pageY);
428
- that.touchesDist = m.sqrt(c1*c1+c2*c2);
429
-
430
- that.zoomed = true;
431
-
432
- scale = 1 / that.touchesDistStart * that.touchesDist * this.scale;
433
-
434
- if (scale < that.options.zoomMin) scale = 0.5 * that.options.zoomMin * Math.pow(2.0, scale / that.options.zoomMin);
435
- else if (scale > that.options.zoomMax) scale = 2.0 * that.options.zoomMax * Math.pow(0.5, that.options.zoomMax / scale);
436
-
437
- that.lastScale = scale / this.scale;
438
-
439
- newX = this.originX - this.originX * that.lastScale + this.x,
440
- newY = this.originY - this.originY * that.lastScale + this.y;
441
-
442
- this.scroller.style[transform] = 'translate(' + newX + 'px,' + newY + 'px) scale(' + scale + ')' + translateZ;
443
-
444
- if (that.options.onZoom) that.options.onZoom.call(that, e);
445
- return;
446
- }
447
-
448
- that.pointX = point.pageX;
449
- that.pointY = point.pageY;
450
-
451
- // Slow down if outside of the boundaries
452
- if (newX > 0 || newX < that.maxScrollX) {
453
- newX = that.options.bounce ? that.x + (deltaX / 2) : newX >= 0 || that.maxScrollX >= 0 ? 0 : that.maxScrollX;
454
- }
455
- if (newY > that.minScrollY || newY < that.maxScrollY) {
456
- newY = that.options.bounce ? that.y + (deltaY / 2) : newY >= that.minScrollY || that.maxScrollY >= 0 ? that.minScrollY : that.maxScrollY;
457
- }
458
-
459
- that.distX += deltaX;
460
- that.distY += deltaY;
461
- that.absDistX = m.abs(that.distX);
462
- that.absDistY = m.abs(that.distY);
463
-
464
- if (that.absDistX < 6 && that.absDistY < 6) {
465
- return;
466
- }
467
-
468
- // Lock direction
469
- if (that.options.lockDirection) {
470
- if (that.absDistX > that.absDistY + 5) {
471
- newY = that.y;
472
- deltaY = 0;
473
- } else if (that.absDistY > that.absDistX + 5) {
474
- newX = that.x;
475
- deltaX = 0;
476
- }
477
- }
478
-
479
- that.moved = true;
480
- that._pos(newX, newY);
481
- that.dirX = deltaX > 0 ? -1 : deltaX < 0 ? 1 : 0;
482
- that.dirY = deltaY > 0 ? -1 : deltaY < 0 ? 1 : 0;
483
-
484
- if (timestamp - that.startTime > 300) {
485
- that.startTime = timestamp;
486
- that.startX = that.x;
487
- that.startY = that.y;
488
- }
489
-
490
- if (that.options.onScrollMove) that.options.onScrollMove.call(that, e);
491
- },
492
-
493
- _end: function (e) {
494
- if (hasTouch && e.touches.length !== 0) return;
495
-
496
- var that = this,
497
- point = hasTouch ? e.changedTouches[0] : e,
498
- target, ev,
499
- momentumX = { dist:0, time:0 },
500
- momentumY = { dist:0, time:0 },
501
- duration = (e.timeStamp || Date.now()) - that.startTime,
502
- newPosX = that.x,
503
- newPosY = that.y,
504
- distX, distY,
505
- newDuration,
506
- snap,
507
- scale;
508
-
509
- that._unbind(MOVE_EV, window);
510
- that._unbind(END_EV, window);
511
- that._unbind(CANCEL_EV, window);
512
-
513
- if (that.options.onBeforeScrollEnd) that.options.onBeforeScrollEnd.call(that, e);
514
-
515
- if (that.zoomed) {
516
- scale = that.scale * that.lastScale;
517
- scale = Math.max(that.options.zoomMin, scale);
518
- scale = Math.min(that.options.zoomMax, scale);
519
- that.lastScale = scale / that.scale;
520
- that.scale = scale;
521
-
522
- that.x = that.originX - that.originX * that.lastScale + that.x;
523
- that.y = that.originY - that.originY * that.lastScale + that.y;
524
-
525
- that.scroller.style[transitionDuration] = '200ms';
526
- that.scroller.style[transform] = 'translate(' + that.x + 'px,' + that.y + 'px) scale(' + that.scale + ')' + translateZ;
527
-
528
- that.zoomed = false;
529
- that.refresh();
530
-
531
- if (that.options.onZoomEnd) that.options.onZoomEnd.call(that, e);
532
- return;
533
- }
534
-
535
- if (!that.moved) {
536
- if (hasTouch) {
537
- if (that.doubleTapTimer && that.options.zoom) {
538
- // Double tapped
539
- clearTimeout(that.doubleTapTimer);
540
- that.doubleTapTimer = null;
541
- if (that.options.onZoomStart) that.options.onZoomStart.call(that, e);
542
- that.zoom(that.pointX, that.pointY, that.scale == 1 ? that.options.doubleTapZoom : 1);
543
- if (that.options.onZoomEnd) {
544
- setTimeout(function() {
545
- that.options.onZoomEnd.call(that, e);
546
- }, 200); // 200 is default zoom duration
547
- }
548
- } else if (this.options.handleClick) {
549
- that.doubleTapTimer = setTimeout(function () {
550
- that.doubleTapTimer = null;
551
-
552
- // Find the last touched element
553
- target = point.target;
554
- while (target.nodeType != 1) target = target.parentNode;
555
-
556
- if (target.tagName != 'SELECT' && target.tagName != 'INPUT' && target.tagName != 'TEXTAREA') {
557
- ev = doc.createEvent('MouseEvents');
558
- ev.initMouseEvent('click', true, true, e.view, 1,
559
- point.screenX, point.screenY, point.clientX, point.clientY,
560
- e.ctrlKey, e.altKey, e.shiftKey, e.metaKey,
561
- 0, null);
562
- ev._fake = true;
563
- target.dispatchEvent(ev);
564
- }
565
- }, that.options.zoom ? 250 : 0);
566
- }
567
- }
568
-
569
- that._resetPos(400);
570
-
571
- if (that.options.onTouchEnd) that.options.onTouchEnd.call(that, e);
572
- return;
573
- }
574
-
575
- if (duration < 300 && that.options.momentum) {
576
- momentumX = newPosX ? that._momentum(newPosX - that.startX, duration, -that.x, that.scrollerW - that.wrapperW + that.x, that.options.bounce ? that.wrapperW : 0) : momentumX;
577
- momentumY = newPosY ? that._momentum(newPosY - that.startY, duration, -that.y, (that.maxScrollY < 0 ? that.scrollerH - that.wrapperH + that.y - that.minScrollY : 0), that.options.bounce ? that.wrapperH : 0) : momentumY;
578
-
579
- newPosX = that.x + momentumX.dist;
580
- newPosY = that.y + momentumY.dist;
581
-
582
- if ((that.x > 0 && newPosX > 0) || (that.x < that.maxScrollX && newPosX < that.maxScrollX)) momentumX = { dist:0, time:0 };
583
- if ((that.y > that.minScrollY && newPosY > that.minScrollY) || (that.y < that.maxScrollY && newPosY < that.maxScrollY)) momentumY = { dist:0, time:0 };
584
- }
585
-
586
- if (momentumX.dist || momentumY.dist) {
587
- newDuration = m.max(m.max(momentumX.time, momentumY.time), 10);
588
-
589
- // Do we need to snap?
590
- if (that.options.snap) {
591
- distX = newPosX - that.absStartX;
592
- distY = newPosY - that.absStartY;
593
- if (m.abs(distX) < that.options.snapThreshold && m.abs(distY) < that.options.snapThreshold) { that.scrollTo(that.absStartX, that.absStartY, 200); }
594
- else {
595
- snap = that._snap(newPosX, newPosY);
596
- newPosX = snap.x;
597
- newPosY = snap.y;
598
- newDuration = m.max(snap.time, newDuration);
599
- }
600
- }
601
-
602
- that.scrollTo(m.round(newPosX), m.round(newPosY), newDuration);
603
-
604
- if (that.options.onTouchEnd) that.options.onTouchEnd.call(that, e);
605
- return;
606
- }
607
-
608
- // Do we need to snap?
609
- if (that.options.snap) {
610
- distX = newPosX - that.absStartX;
611
- distY = newPosY - that.absStartY;
612
- if (m.abs(distX) < that.options.snapThreshold && m.abs(distY) < that.options.snapThreshold) that.scrollTo(that.absStartX, that.absStartY, 200);
613
- else {
614
- snap = that._snap(that.x, that.y);
615
- if (snap.x != that.x || snap.y != that.y) that.scrollTo(snap.x, snap.y, snap.time);
616
- }
617
-
618
- if (that.options.onTouchEnd) that.options.onTouchEnd.call(that, e);
619
- return;
620
- }
621
-
622
- that._resetPos(200);
623
- if (that.options.onTouchEnd) that.options.onTouchEnd.call(that, e);
624
- },
625
-
626
- _resetPos: function (time) {
627
- var that = this,
628
- resetX = that.x >= 0 ? 0 : that.x < that.maxScrollX ? that.maxScrollX : that.x,
629
- resetY = that.y >= that.minScrollY || that.maxScrollY > 0 ? that.minScrollY : that.y < that.maxScrollY ? that.maxScrollY : that.y;
630
-
631
- if (resetX == that.x && resetY == that.y) {
632
- if (that.moved) {
633
- that.moved = false;
634
- if (that.options.onScrollEnd) that.options.onScrollEnd.call(that); // Execute custom code on scroll end
635
- }
636
-
637
- if (that.hScrollbar && that.options.hideScrollbar) {
638
- if (vendor == 'webkit') that.hScrollbarWrapper.style[transitionDelay] = '300ms';
639
- that.hScrollbarWrapper.style.opacity = '0';
640
- }
641
- if (that.vScrollbar && that.options.hideScrollbar) {
642
- if (vendor == 'webkit') that.vScrollbarWrapper.style[transitionDelay] = '300ms';
643
- that.vScrollbarWrapper.style.opacity = '0';
644
- }
645
-
646
- return;
647
- }
648
-
649
- that.scrollTo(resetX, resetY, time || 0);
650
- },
651
-
652
- _wheel: function (e) {
653
- var that = this,
654
- wheelDeltaX, wheelDeltaY,
655
- deltaX, deltaY,
656
- deltaScale;
657
-
658
- if ('wheelDeltaX' in e) {
659
- wheelDeltaX = e.wheelDeltaX / 12;
660
- wheelDeltaY = e.wheelDeltaY / 12;
661
- } else if('wheelDelta' in e) {
662
- wheelDeltaX = wheelDeltaY = e.wheelDelta / 12;
663
- } else if ('detail' in e) {
664
- wheelDeltaX = wheelDeltaY = -e.detail * 3;
665
- } else {
666
- return;
667
- }
668
-
669
- if (that.options.wheelAction == 'zoom') {
670
- deltaScale = that.scale * Math.pow(2, 1/3 * (wheelDeltaY ? wheelDeltaY / Math.abs(wheelDeltaY) : 0));
671
- if (deltaScale < that.options.zoomMin) deltaScale = that.options.zoomMin;
672
- if (deltaScale > that.options.zoomMax) deltaScale = that.options.zoomMax;
673
-
674
- if (deltaScale != that.scale) {
675
- if (!that.wheelZoomCount && that.options.onZoomStart) that.options.onZoomStart.call(that, e);
676
- that.wheelZoomCount++;
677
-
678
- that.zoom(e.pageX, e.pageY, deltaScale, 400);
679
-
680
- setTimeout(function() {
681
- that.wheelZoomCount--;
682
- if (!that.wheelZoomCount && that.options.onZoomEnd) that.options.onZoomEnd.call(that, e);
683
- }, 400);
684
- }
685
-
686
- return;
687
- }
688
-
689
- deltaX = that.x + wheelDeltaX;
690
- deltaY = that.y + wheelDeltaY;
691
-
692
- if (deltaX > 0) deltaX = 0;
693
- else if (deltaX < that.maxScrollX) deltaX = that.maxScrollX;
694
-
695
- if (deltaY > that.minScrollY) deltaY = that.minScrollY;
696
- else if (deltaY < that.maxScrollY) deltaY = that.maxScrollY;
697
-
698
- if (that.maxScrollY < 0) {
699
- that.scrollTo(deltaX, deltaY, 0);
700
- }
701
- },
702
-
703
- _transitionEnd: function (e) {
704
- var that = this;
705
-
706
- if (e.target != that.scroller) return;
707
-
708
- that._unbind(TRNEND_EV);
709
-
710
- that._startAni();
711
- },
712
-
713
-
714
- /**
715
- *
716
- * Utilities
717
- *
718
- */
719
- _startAni: function () {
720
- var that = this,
721
- startX = that.x, startY = that.y,
722
- startTime = Date.now(),
723
- step, easeOut,
724
- animate;
725
-
726
- if (that.animating) return;
727
-
728
- if (!that.steps.length) {
729
- that._resetPos(400);
730
- return;
731
- }
732
-
733
- step = that.steps.shift();
734
-
735
- if (step.x == startX && step.y == startY) step.time = 0;
736
-
737
- that.animating = true;
738
- that.moved = true;
739
-
740
- if (that.options.useTransition) {
741
- that._transitionTime(step.time);
742
- that._pos(step.x, step.y);
743
- that.animating = false;
744
- if (step.time) that._bind(TRNEND_EV);
745
- else that._resetPos(0);
746
- return;
747
- }
748
-
749
- animate = function () {
750
- var now = Date.now(),
751
- newX, newY;
752
-
753
- if (now >= startTime + step.time) {
754
- that._pos(step.x, step.y);
755
- that.animating = false;
756
- if (that.options.onAnimationEnd) that.options.onAnimationEnd.call(that); // Execute custom code on animation end
757
- that._startAni();
758
- return;
759
- }
760
-
761
- now = (now - startTime) / step.time - 1;
762
- easeOut = m.sqrt(1 - now * now);
763
- newX = (step.x - startX) * easeOut + startX;
764
- newY = (step.y - startY) * easeOut + startY;
765
- that._pos(newX, newY);
766
- if (that.animating) that.aniTime = nextFrame(animate);
767
- };
768
-
769
- animate();
770
- },
771
-
772
- _transitionTime: function (time) {
773
- time += 'ms';
774
- this.scroller.style[transitionDuration] = time;
775
- if (this.hScrollbar) this.hScrollbarIndicator.style[transitionDuration] = time;
776
- if (this.vScrollbar) this.vScrollbarIndicator.style[transitionDuration] = time;
777
- },
778
-
779
- _momentum: function (dist, time, maxDistUpper, maxDistLower, size) {
780
- var deceleration = 0.0006,
781
- speed = m.abs(dist) / time,
782
- newDist = (speed * speed) / (2 * deceleration),
783
- newTime = 0, outsideDist = 0;
784
-
785
- // Proportinally reduce speed if we are outside of the boundaries
786
- if (dist > 0 && newDist > maxDistUpper) {
787
- outsideDist = size / (6 / (newDist / speed * deceleration));
788
- maxDistUpper = maxDistUpper + outsideDist;
789
- speed = speed * maxDistUpper / newDist;
790
- newDist = maxDistUpper;
791
- } else if (dist < 0 && newDist > maxDistLower) {
792
- outsideDist = size / (6 / (newDist / speed * deceleration));
793
- maxDistLower = maxDistLower + outsideDist;
794
- speed = speed * maxDistLower / newDist;
795
- newDist = maxDistLower;
796
- }
797
-
798
- newDist = newDist * (dist < 0 ? -1 : 1);
799
- newTime = speed / deceleration;
800
-
801
- return { dist: newDist, time: m.round(newTime) };
802
- },
803
-
804
- _offset: function (el) {
805
- var left = -el.offsetLeft,
806
- top = -el.offsetTop;
807
-
808
- while (el = el.offsetParent) {
809
- left -= el.offsetLeft;
810
- top -= el.offsetTop;
811
- }
812
-
813
- if (el != this.wrapper) {
814
- left *= this.scale;
815
- top *= this.scale;
816
- }
817
-
818
- return { left: left, top: top };
819
- },
820
-
821
- _snap: function (x, y) {
822
- var that = this,
823
- i, l,
824
- page, time,
825
- sizeX, sizeY;
826
-
827
- // Check page X
828
- page = that.pagesX.length - 1;
829
- for (i=0, l=that.pagesX.length; i<l; i++) {
830
- if (x >= that.pagesX[i]) {
831
- page = i;
832
- break;
833
- }
834
- }
835
- if (page == that.currPageX && page > 0 && that.dirX < 0) page--;
836
- x = that.pagesX[page];
837
- sizeX = m.abs(x - that.pagesX[that.currPageX]);
838
- sizeX = sizeX ? m.abs(that.x - x) / sizeX * 500 : 0;
839
- that.currPageX = page;
840
-
841
- // Check page Y
842
- page = that.pagesY.length-1;
843
- for (i=0; i<page; i++) {
844
- if (y >= that.pagesY[i]) {
845
- page = i;
846
- break;
847
- }
848
- }
849
- if (page == that.currPageY && page > 0 && that.dirY < 0) page--;
850
- y = that.pagesY[page];
851
- sizeY = m.abs(y - that.pagesY[that.currPageY]);
852
- sizeY = sizeY ? m.abs(that.y - y) / sizeY * 500 : 0;
853
- that.currPageY = page;
854
-
855
- // Snap with constant speed (proportional duration)
856
- time = m.round(m.max(sizeX, sizeY)) || 200;
857
-
858
- return { x: x, y: y, time: time };
859
- },
860
-
861
- _bind: function (type, el, bubble) {
862
- (el || this.scroller).addEventListener(type, this, !!bubble);
863
- },
864
-
865
- _unbind: function (type, el, bubble) {
866
- (el || this.scroller).removeEventListener(type, this, !!bubble);
867
- },
868
-
869
-
870
- /**
871
- *
872
- * Public methods
873
- *
874
- */
875
- destroy: function () {
876
- var that = this;
877
-
878
- that.scroller.style[transform] = '';
879
-
880
- // Remove the scrollbars
881
- that.hScrollbar = false;
882
- that.vScrollbar = false;
883
- that._scrollbar('h');
884
- that._scrollbar('v');
885
-
886
- // Remove the event listeners
887
- that._unbind(RESIZE_EV, window);
888
- that._unbind(START_EV);
889
- that._unbind(MOVE_EV, window);
890
- that._unbind(END_EV, window);
891
- that._unbind(CANCEL_EV, window);
892
-
893
- if (!that.options.hasTouch) {
894
- that._unbind('DOMMouseScroll');
895
- that._unbind('mousewheel');
896
- }
897
-
898
- if (that.options.useTransition) that._unbind(TRNEND_EV);
899
-
900
- if (that.options.checkDOMChanges) clearInterval(that.checkDOMTime);
901
-
902
- if (that.options.onDestroy) that.options.onDestroy.call(that);
903
- },
904
-
905
- refresh: function () {
906
- var that = this,
907
- offset,
908
- i, l,
909
- els,
910
- pos = 0,
911
- page = 0;
912
-
913
- if (that.scale < that.options.zoomMin) that.scale = that.options.zoomMin;
914
- that.wrapperW = that.wrapper.clientWidth || 1;
915
- that.wrapperH = that.wrapper.clientHeight || 1;
916
-
917
- that.minScrollY = -that.options.topOffset || 0;
918
- that.scrollerW = m.round(that.scroller.offsetWidth * that.scale);
919
- that.scrollerH = m.round((that.scroller.offsetHeight + that.minScrollY) * that.scale);
920
- that.maxScrollX = that.wrapperW - that.scrollerW;
921
- that.maxScrollY = that.wrapperH - that.scrollerH + that.minScrollY;
922
- that.dirX = 0;
923
- that.dirY = 0;
924
-
925
- if (that.options.onRefresh) that.options.onRefresh.call(that);
926
-
927
- that.hScroll = that.options.hScroll && that.maxScrollX < 0;
928
- that.vScroll = that.options.vScroll && (!that.options.bounceLock && !that.hScroll || that.scrollerH > that.wrapperH);
929
-
930
- that.hScrollbar = that.hScroll && that.options.hScrollbar;
931
- that.vScrollbar = that.vScroll && that.options.vScrollbar && that.scrollerH > that.wrapperH;
932
-
933
- offset = that._offset(that.wrapper);
934
- that.wrapperOffsetLeft = -offset.left;
935
- that.wrapperOffsetTop = -offset.top;
936
-
937
- // Prepare snap
938
- if (typeof that.options.snap == 'string') {
939
- that.pagesX = [];
940
- that.pagesY = [];
941
- els = that.scroller.querySelectorAll(that.options.snap);
942
- for (i=0, l=els.length; i<l; i++) {
943
- pos = that._offset(els[i]);
944
- pos.left += that.wrapperOffsetLeft;
945
- pos.top += that.wrapperOffsetTop;
946
- that.pagesX[i] = pos.left < that.maxScrollX ? that.maxScrollX : pos.left * that.scale;
947
- that.pagesY[i] = pos.top < that.maxScrollY ? that.maxScrollY : pos.top * that.scale;
948
- }
949
- } else if (that.options.snap) {
950
- that.pagesX = [];
951
- while (pos >= that.maxScrollX) {
952
- that.pagesX[page] = pos;
953
- pos = pos - that.wrapperW;
954
- page++;
955
- }
956
- if (that.maxScrollX%that.wrapperW) that.pagesX[that.pagesX.length] = that.maxScrollX - that.pagesX[that.pagesX.length-1] + that.pagesX[that.pagesX.length-1];
957
-
958
- pos = 0;
959
- page = 0;
960
- that.pagesY = [];
961
- while (pos >= that.maxScrollY) {
962
- that.pagesY[page] = pos;
963
- pos = pos - that.wrapperH;
964
- page++;
965
- }
966
- if (that.maxScrollY%that.wrapperH) that.pagesY[that.pagesY.length] = that.maxScrollY - that.pagesY[that.pagesY.length-1] + that.pagesY[that.pagesY.length-1];
967
- }
968
-
969
- // Prepare the scrollbars
970
- that._scrollbar('h');
971
- that._scrollbar('v');
972
-
973
- if (!that.zoomed) {
974
- that.scroller.style[transitionDuration] = '0';
975
- that._resetPos(400);
976
- }
977
- },
978
-
979
- scrollTo: function (x, y, time, relative) {
980
- var that = this,
981
- step = x,
982
- i, l;
983
-
984
- that.stop();
985
-
986
- if (!step.length) step = [{ x: x, y: y, time: time, relative: relative }];
987
-
988
- for (i=0, l=step.length; i<l; i++) {
989
- if (step[i].relative) { step[i].x = that.x - step[i].x; step[i].y = that.y - step[i].y; }
990
- that.steps.push({ x: step[i].x, y: step[i].y, time: step[i].time || 0 });
991
- }
992
-
993
- that._startAni();
994
- },
995
-
996
- scrollToElement: function (el, time) {
997
- var that = this, pos;
998
- el = el.nodeType ? el : that.scroller.querySelector(el);
999
- if (!el) return;
1000
-
1001
- pos = that._offset(el);
1002
- pos.left += that.wrapperOffsetLeft;
1003
- pos.top += that.wrapperOffsetTop;
1004
-
1005
- pos.left = pos.left > 0 ? 0 : pos.left < that.maxScrollX ? that.maxScrollX : pos.left;
1006
- pos.top = pos.top > that.minScrollY ? that.minScrollY : pos.top < that.maxScrollY ? that.maxScrollY : pos.top;
1007
- time = time === undefined ? m.max(m.abs(pos.left)*2, m.abs(pos.top)*2) : time;
1008
-
1009
- that.scrollTo(pos.left, pos.top, time);
1010
- },
1011
-
1012
- scrollToPage: function (pageX, pageY, time) {
1013
- var that = this, x, y;
1014
-
1015
- time = time === undefined ? 400 : time;
1016
-
1017
- if (that.options.onScrollStart) that.options.onScrollStart.call(that);
1018
-
1019
- if (that.options.snap) {
1020
- pageX = pageX == 'next' ? that.currPageX+1 : pageX == 'prev' ? that.currPageX-1 : pageX;
1021
- pageY = pageY == 'next' ? that.currPageY+1 : pageY == 'prev' ? that.currPageY-1 : pageY;
1022
-
1023
- pageX = pageX < 0 ? 0 : pageX > that.pagesX.length-1 ? that.pagesX.length-1 : pageX;
1024
- pageY = pageY < 0 ? 0 : pageY > that.pagesY.length-1 ? that.pagesY.length-1 : pageY;
1025
-
1026
- that.currPageX = pageX;
1027
- that.currPageY = pageY;
1028
- x = that.pagesX[pageX];
1029
- y = that.pagesY[pageY];
1030
- } else {
1031
- x = -that.wrapperW * pageX;
1032
- y = -that.wrapperH * pageY;
1033
- if (x < that.maxScrollX) x = that.maxScrollX;
1034
- if (y < that.maxScrollY) y = that.maxScrollY;
1035
- }
1036
-
1037
- that.scrollTo(x, y, time);
1038
- },
1039
-
1040
- disable: function () {
1041
- this.stop();
1042
- this._resetPos(0);
1043
- this.enabled = false;
1044
-
1045
- // If disabled after touchstart we make sure that there are no left over events
1046
- this._unbind(MOVE_EV, window);
1047
- this._unbind(END_EV, window);
1048
- this._unbind(CANCEL_EV, window);
1049
- },
1050
-
1051
- enable: function () {
1052
- this.enabled = true;
1053
- },
1054
-
1055
- stop: function () {
1056
- if (this.options.useTransition) this._unbind(TRNEND_EV);
1057
- else cancelFrame(this.aniTime);
1058
- this.steps = [];
1059
- this.moved = false;
1060
- this.animating = false;
1061
- },
1062
-
1063
- zoom: function (x, y, scale, time) {
1064
- var that = this,
1065
- relScale = scale / that.scale;
1066
-
1067
- if (!that.options.useTransform) return;
1068
-
1069
- that.zoomed = true;
1070
- time = time === undefined ? 200 : time;
1071
- x = x - that.wrapperOffsetLeft - that.x;
1072
- y = y - that.wrapperOffsetTop - that.y;
1073
- that.x = x - x * relScale + that.x;
1074
- that.y = y - y * relScale + that.y;
1075
-
1076
- that.scale = scale;
1077
- that.refresh();
1078
-
1079
- that.x = that.x > 0 ? 0 : that.x < that.maxScrollX ? that.maxScrollX : that.x;
1080
- that.y = that.y > that.minScrollY ? that.minScrollY : that.y < that.maxScrollY ? that.maxScrollY : that.y;
1081
-
1082
- that.scroller.style[transitionDuration] = time + 'ms';
1083
- that.scroller.style[transform] = 'translate(' + that.x + 'px,' + that.y + 'px) scale(' + scale + ')' + translateZ;
1084
- that.zoomed = false;
1085
- },
1086
-
1087
- isReady: function () {
1088
- return !this.moved && !this.zoomed && !this.animating;
1089
- }
1090
- };
1091
-
1092
- function prefixStyle (style) {
1093
- if ( vendor === '' ) return style;
1094
-
1095
- style = style.charAt(0).toUpperCase() + style.substr(1);
1096
- return vendor + style;
1097
- }
1098
-
1099
- dummyStyle = null; // for the sake of it
1100
-
1101
- if (typeof exports !== 'undefined') exports.iScroll = iScroll;
1102
- else window.iScroll = iScroll;
1103
-
1104
- })(window, document);
1105
-
1106
- /*
1107
- * This file is the bridge between iscroll and skrollr.
1108
- * It configures the page so that both work together
1109
- * and exposes an instance of iscroll to skrollr.
1110
- */
1111
-
1112
- (function(window, document, undefined) {
1113
- document.addEventListener('DOMContentLoaded', function () {
1114
- window.setTimeout(function() {
1115
- var skrollrBody = document.getElementById('skrollr-body');
1116
-
1117
- if(!skrollrBody) {
1118
- throw "For mobile support skrollr needs a #skrollr-body element";
1119
- }
1120
-
1121
- skrollrBody.style.cssText += 'position:absolute;width:100%;';
1122
-
1123
- document.body.style.cssText += 'position:absolute;left:0;top:0;bottom:0;width:100%;padding:0;margin:0;';
1124
-
1125
- skrollr.iscroll = new iScroll(document.body, {
1126
- bounce: false,
1127
- //When using transform, all fixed-positioned child elements degrade to absolut positioned.
1128
- useTransform: false
1129
- });
1130
-
1131
- document.documentElement.className += ' skrollr-mobile';
1132
-
1133
- window.scroll(0, 0);
1134
- }, 200);
1135
- },false);
1136
- }(window, document));