vendor: 7,861 bytes, lines 1-303
1/** 2 jQuery.kinetic v2.0.1 3 Dave Taylor http://davetayls.me 4 5 @license The MIT License (MIT) 6 @preserve Copyright (c) 2012 Dave Taylor http://davetayls.me 7 */ 8(function ($){ 9 'use strict'; 10 11 var ACTIVE_CLASS = 'kinetic-active'; 12 13 /** 14 * Provides requestAnimationFrame in a cross browser way. 15 * http://paulirish.com/2011/requestanimationframe-for-smart-animating/ 16 */ 17 if (!window.requestAnimationFrame){ 18 19 window.requestAnimationFrame = (function (){ 20 21 return window.webkitRequestAnimationFrame || 22 window.mozRequestAnimationFrame || 23 window.oRequestAnimationFrame || 24 window.msRequestAnimationFrame || 25 function (/* function FrameRequestCallback */ callback, /* DOMElement Element */ element){ 26 window.setTimeout(callback, 1000 / 60); 27 }; 28 29 }()); 30 31 } 32 33 // add touch checker to jQuery.support 34 $.support = $.support || {}; 35 $.extend($.support, { 36 touch: 'ontouchend' in document 37 }); 38 var selectStart = function (){ 39 return false; 40 }; 41 42 43 // KINETIC CLASS DEFINITION 44 // ====================== 45 46 var Kinetic = function (element, settings) { 47 this.settings = settings; 48 this.el = element; 49 this.$el = $(element); 50 51 this._initElements(); 52 53 return this; 54 }; 55 56 Kinetic.DATA_KEY = 'kinetic'; 57 Kinetic.DEFAULTS = { 58 cursor: 'move', 59 decelerate: true, 60 triggerHardware: false, 61 y: true, 62 x: true, 63 slowdown: 0.9, 64 maxvelocity: 40, 65 throttleFPS: 60, 66 movingClass: { 67 up: 'kinetic-moving-up', 68 down: 'kinetic-moving-down', 69 left: 'kinetic-moving-left', 70 right: 'kinetic-moving-right' 71 }, 72 deceleratingClass: { 73 up: 'kinetic-decelerating-up', 74 down: 'kinetic-decelerating-down', 75 left: 'kinetic-decelerating-left', 76 right: 'kinetic-decelerating-right' 77 } 78 }; 79 80 81 // Public functions 82 83 Kinetic.prototype.start = function (options){ 84 this.settings = $.extend(this.settings, options); 85 this.velocity = options.velocity || this.velocity; 86 this.velocityY = options.velocityY || this.velocityY; 87 this.settings.decelerate = false; 88 this._move(); 89 }; 90 91 Kinetic.prototype.end = function (){ 92 this.settings.decelerate = true; 93 }; 94 95 Kinetic.prototype.stop = function (){ 96 this.velocity = 0; 97 this.velocityY = 0; 98 this.settings.decelerate = true; 99 if ($.isFunction(this.settings.stopped)){ 100 this.settings.stopped.call(this); 101 } 102 }; 103 104 Kinetic.prototype.detach = function (){ 105 this._detachListeners(); 106 this.$el 107 .removeClass(ACTIVE_CLASS) 108 .css('cursor', ''); 109 }; 110 111 Kinetic.prototype.attach = function (){ 112 if (this.$el.hasClass(ACTIVE_CLASS)) { 113 return; 114 } 115 this._attachListeners(this.$el); 116 this.$el 117 .addClass(ACTIVE_CLASS) 118 .css('cursor', this.settings.cursor); 119 }; 120 121 122 // Internal functions 123 124 Kinetic.prototype._initElements = function (){ 125 this.$el.addClass(ACTIVE_CLASS); 126 127 $.extend(this, { 128 xpos: null, 129 prevXPos: false, 130 ypos: null, 131 prevYPos: false, 132 mouseDown: false, 133 throttleTimeout: 1000 / this.settings.throttleFPS, 134 lastMove: null, 135 elementFocused: null 136 }); 137 138 this.velocity = 0; 139 this.velocityY = 0; 140 141 // make sure we reset everything when mouse up 142 $(document) 143 .mouseup($.proxy(this._resetMouse, this)) 144 .click($.proxy(this._resetMouse, this)); 145 146 this._initEvents(); 147 148 this.$el.css('cursor', this.settings.cursor); 149 150 if (this.settings.triggerHardware){ 151 this.$el.css({ 152 '-webkit-transform': 'translate3d(0,0,0)', 153 '-webkit-perspective': '1000', 154 '-webkit-backface-visibility': 'hidden' 155 }); 156 } 157 }; 158 159 Kinetic.prototype._initEvents = function(){ 160 var self = this; 161 this.settings.events = { 162 touchStart: function (e){ 163 var touch; 164 if (self._useTarget(e.target)){ 165 touch = e.originalEvent.touches[0]; 166 self._start(touch.clientX, touch.clientY); 167 e.stopPropagation(); 168 } 169 }, 170 touchMove: function (e){ 171 var touch; 172 if (self.mouseDown){ 173 touch = e.originalEvent.touches[0]; 174 self._inputmove(touch.clientX, touch.clientY); 175 if (e.preventDefault){ 176 e.preventDefault(); 177 } 178 } 179 }, 180 inputDown: function (e){ 181 if (self._useTarget(e.target)){ 182 self._start(e.clientX, e.clientY); 183 self.elementFocused = e.target; 184 if (e.target.nodeName === 'IMG'){ 185 e.preventDefault(); 186 } 187 e.stopPropagation(); 188 } 189 }, 190 inputEnd: function (e){ 191 if (self._useTarget(e.target)){ 192 self._end(); 193 self.elementFocused = null; 194 if (e.preventDefault){ 195 e.preventDefault(); 196 } 197 } 198 }, 199 inputMove: function (e){ 200 if (self.mouseDown){ 201 self._inputmove(e.clientX, e.clientY); 202 if (e.preventDefault){ 203 e.preventDefault(); 204 } 205 } 206 }, 207 scroll: function (e){ 208 if ($.isFunction(self.settings.moved)){ 209 self.settings.moved.call(self, self.settings); 210 } 211 if (e.preventDefault){ 212 e.preventDefault(); 213 } 214 }, 215 inputClick: function (e){ 216 if (Math.abs(self.velocity) > 0){ 217 e.preventDefault(); 218 return false; 219 } 220 }, 221 // prevent drag and drop images in ie 222 dragStart: function (e){ 223 if (self.elementFocused){ 224 return false; 225 } 226 } 227 }; 228 229 this._attachListeners(this.$el, this.settings); 230 231 }; 232 233 Kinetic.prototype._inputmove = function (clientX, clientY){ 234 var $this = this.$el; 235 var el = this.el; 236 237 if (!this.lastMove || new Date() > new Date(this.lastMove.getTime() + this.throttleTimeout)){ 238 this.lastMove = new Date(); 239 240 if (this.mouseDown && (this.xpos || this.ypos)){ 241 if (this.elementFocused){ 242 $(this.elementFocused).blur(); 243 this.elementFocused = null; 244 $this.focus(); 245 } 246 247 this.settings.decelerate = false; 248 this.velocity = this.velocityY = 0; 249 250 var scrollLeft = this.scrollLeft(); 251 var scrollTop = this.scrollTop(); 252 var movedX = (clientX - this.xpos); 253 var movedY = (clientY - this.ypos); 254 255 this.scrollLeft(this.settings.x ? scrollLeft - movedX : scrollLeft); 256 this.scrollTop(this.settings.y ? scrollTop - movedY : scrollTop); 257 258 this.prevXPos = this.xpos; 259 this.prevYPos = this.ypos; 260 this.xpos = clientX; 261 this.ypos = clientY; 262 263 this._calculateVelocities(); 264 this._setMoveClasses(this.settings.movingClass); 265 266 if ($.isFunction(this.settings.moved)){ 267 this.settings.moved.call($this, this.settings); 268 } 269 } 270 } 271 }; 272 273 Kinetic.prototype._calculateVelocities = function (){ 274 this.velocity = this._capVelocity(this.prevXPos - this.xpos, this.settings.maxvelocity); 275 this.velocityY = this._capVelocity(this.prevYPos - this.ypos, this.settings.maxvelocity); 276 }; 277 278 Kinetic.prototype._end = function (){ 279 if (this.xpos && this.prevXPos && this.settings.decelerate === false){ 280 this.settings.decelerate = true; 281 this._calculateVelocities(); 282 this.xpos = this.prevXPos = this.mouseDown = false; 283 this._move(); 284 } 285 }; 286 287 Kinetic.prototype._useTarget = function (target){ 288 if ($.isFunction(this.settings.filterTarget)){ 289 return this.settings.filterTarget.call(this, target) !== false; 290 } 291 return true; 292 }; 293 294 Kinetic.prototype._start = function (clientX, clientY){ 295 this.mouseDown = true; 296 this.velocity = this.prevXPos = 0; 297 this.velocityY = this.prevYPos = 0; 298 this.xpos = clientX; 299 this.ypos = clientY; 300 }; 301 302 Kinetic.prototype._resetMouse = function (){ 303 this.xpos = false;
304 this.ypos = false; 305 this.mouseDown = false; 306 }; 307 308 Kinetic.prototype._decelerateVelocity = function (velocity, slowdown){ 309 return Math.floor(Math.abs(velocity)) === 0 ? 0 // is velocity less than 1? 310 : velocity * slowdown; // reduce slowdown 311 }; 312 313 Kinetic.prototype._capVelocity = function (velocity, max){ 314 var newVelocity = velocity; 315 if (velocity > 0){ 316 if (velocity > max){ 317 newVelocity = max; 318 } 319 } else { 320 if (velocity < (0 - max)){ 321 newVelocity = (0 - max); 322 } 323 } 324 return newVelocity; 325 }; 326 327 Kinetic.prototype._setMoveClasses = function (classes){ 328 // FIXME: consider if we want to apply PL #44, this should not remove 329 // classes we have not defined on the element! 330 var settings = this.settings; 331 var $this = this.$el; 332 333 $this.removeClass(settings.movingClass.up) 334 .removeClass(settings.movingClass.down) 335 .removeClass(settings.movingClass.left) 336 .removeClass(settings.movingClass.right) 337 .removeClass(settings.deceleratingClass.up) 338 .removeClass(settings.deceleratingClass.down) 339 .removeClass(settings.deceleratingClass.left) 340 .removeClass(settings.deceleratingClass.right); 341 342 if (this.velocity > 0){
vendor: 4,558 bytes, lines 343-505
343 $this.addClass(classes.right); 344 } 345 if (this.velocity < 0){ 346 $this.addClass(classes.left); 347 } 348 if (this.velocityY > 0){ 349 $this.addClass(classes.down); 350 } 351 if (this.velocityY < 0){ 352 $this.addClass(classes.up); 353 } 354 355 }; 356 357 358 // do the actual kinetic movement 359 Kinetic.prototype._move = function (){ 360 var $scroller = this.$el; 361 var scroller = this.el; 362 var self = this; 363 var settings = self.settings; 364 365 // set scrollLeft 366 if (settings.x && scroller.scrollWidth > 0){ 367 this.scrollLeft(this.scrollLeft() + this.velocity); 368 if (Math.abs(this.velocity) > 0){ 369 this.velocity = settings.decelerate ? 370 self._decelerateVelocity(this.velocity, settings.slowdown) : this.velocity; 371 } 372 } else { 373 this.velocity = 0; 374 } 375 376 // set scrollTop 377 if (settings.y && scroller.scrollHeight > 0){ 378 this.scrollTop(this.scrollTop() + this.velocityY); 379 if (Math.abs(this.velocityY) > 0){ 380 this.velocityY = settings.decelerate ? 381 self._decelerateVelocity(this.velocityY, settings.slowdown) : this.velocityY; 382 } 383 } else { 384 this.velocityY = 0; 385 } 386 387 self._setMoveClasses(settings.deceleratingClass); 388 389 if ($.isFunction(settings.moved)){ 390 settings.moved.call(this, settings); 391 } 392 393 if (Math.abs(this.velocity) > 0 || Math.abs(this.velocityY) > 0){ 394 if (!this.moving) { 395 this.moving = true; 396 // tick for next movement 397 window.requestAnimationFrame(function (){ 398 self.moving = false; 399 self._move(); 400 }); 401 } 402 } else { 403 self.stop(); 404 } 405 }; 406 407 // get current scroller to apply positioning to 408 Kinetic.prototype._getScroller = function(){ 409 var $scroller = this.$el; 410 if (this.$el.is('body') || this.$el.is('html')){ 411 $scroller = $(window); 412 } 413 return $scroller; 414 }; 415 416 // set the scroll position 417 Kinetic.prototype.scrollLeft = function(left){ 418 var $scroller = this._getScroller(); 419 if (typeof left === 'number'){ 420 $scroller.scrollLeft(left); 421 this.settings.scrollLeft = left; 422 } else { 423 return $scroller.scrollLeft(); 424 } 425 }; 426 Kinetic.prototype.scrollTop = function(top){ 427 var $scroller = this._getScroller(); 428 if (typeof top === 'number'){ 429 $scroller.scrollTop(top); 430 this.settings.scrollTop = top; 431 } else { 432 return $scroller.scrollTop(); 433 } 434 }; 435 436 Kinetic.prototype._attachListeners = function (){ 437 var $this = this.$el; 438 var settings = this.settings; 439 440 if ($.support.touch){ 441 $this 442 .bind('touchstart', settings.events.touchStart) 443 .bind('touchend', settings.events.inputEnd) 444 .bind('touchmove', settings.events.touchMove); 445 } else { 446 $this 447 .mousedown(settings.events.inputDown) 448 .mouseup(settings.events.inputEnd) 449 .mousemove(settings.events.inputMove); 450 } 451 $this 452 .click(settings.events.inputClick) 453 .scroll(settings.events.scroll) 454 .bind('selectstart', selectStart) // prevent selection when dragging 455 .bind('dragstart', settings.events.dragStart); 456 }; 457 458 Kinetic.prototype._detachListeners = function (){ 459 var $this = this.$el; 460 var settings = this.settings; 461 if ($.support.touch){ 462 $this 463 .unbind('touchstart', settings.events.touchStart) 464 .unbind('touchend', settings.events.inputEnd) 465 .unbind('touchmove', settings.events.touchMove); 466 } else { 467 $this 468 .unbind('mousedown', settings.events.inputDown) 469 .unbind('mouseup', settings.events.inputEnd) 470 .unbind('mousemove', settings.events.inputMove) 471 .unbind('scroll', settings.events.scroll); 472 } 473 $this 474 .unbind('click', settings.events.inputClick) 475 .unbind('selectstart', selectStart) // prevent selection when dragging 476 .unbind('dragstart', settings.events.dragStart); 477 }; 478 479 480 // EXPOSE KINETIC CONSTRUCTOR 481 // ========================== 482 $.Kinetic = Kinetic; 483 484 // KINETIC PLUGIN DEFINITION 485 // ======================= 486 487 $.fn.kinetic = function (option, callOptions) { 488 return this.each(function () { 489 var $this = $(this); 490 var instance = $this.data(Kinetic.DATA_KEY); 491 var options = $.extend({}, Kinetic.DEFAULTS, $this.data(), typeof option === 'object' && option); 492 493 if (!instance) { 494 $this.data(Kinetic.DATA_KEY, (instance = new Kinetic(this, options))); 495 } 496 497 if (typeof option === 'string') { 498 instance[option](callOptions); 499 } 500 501 }); 502 }; 503 504}(window.jQuery || window.Zepto)); 505
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.