[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 /* 2 YUI 3.17.2 (build 9c3c78e) 3 Copyright 2014 Yahoo! Inc. All rights reserved. 4 Licensed under the BSD License. 5 http://yuilibrary.com/license/ 6 */ 7 8 YUI.add('node-flick', function (Y, NAME) { 9 10 /** 11 * Provide a simple Flick plugin, which can be used along with the "flick" gesture event, to 12 * animate the motion of the host node in response to a (mouse or touch) flick gesture. 13 * 14 * <p>The current implementation is designed to move the node, relative to the bounds of a parent node and is suitable 15 * for scroll/carousel type implementations. Future versions will remove that constraint, to allow open ended movement within 16 * the document.</p> 17 * 18 * @module node-flick 19 */ 20 21 var HOST = "host", 22 PARENT_NODE = "parentNode", 23 BOUNDING_BOX = "boundingBox", 24 OFFSET_HEIGHT = "offsetHeight", 25 OFFSET_WIDTH = "offsetWidth", 26 SCROLL_HEIGHT = "scrollHeight", 27 SCROLL_WIDTH = "scrollWidth", 28 BOUNCE = "bounce", 29 MIN_DISTANCE = "minDistance", 30 MIN_VELOCITY = "minVelocity", 31 BOUNCE_DISTANCE = "bounceDistance", 32 DECELERATION = "deceleration", 33 STEP = "step", 34 DURATION = "duration", 35 EASING = "easing", 36 FLICK = "flick", 37 38 getClassName = Y.ClassNameManager.getClassName; 39 40 /** 41 * A plugin class which can be used to animate the motion of a node, in response to a flick gesture. 42 * 43 * @class Flick 44 * @namespace Plugin 45 * @param {Object} config The initial attribute values for the plugin 46 */ 47 function Flick(config) { 48 Flick.superclass.constructor.apply(this, arguments); 49 } 50 51 Flick.ATTRS = { 52 53 /** 54 * Drag coefficent for inertial scrolling. The closer to 1 this 55 * value is, the less friction during scrolling. 56 * 57 * @attribute deceleration 58 * @default 0.98 59 */ 60 deceleration : { 61 value: 0.98 62 }, 63 64 /** 65 * Drag coefficient for intertial scrolling at the upper 66 * and lower boundaries of the scrollview. Set to 0 to 67 * disable "rubber-banding". 68 * 69 * @attribute bounce 70 * @type Number 71 * @default 0.7 72 */ 73 bounce : { 74 value: 0.7 75 }, 76 77 /** 78 * The bounce distance in pixels 79 * 80 * @attribute bounceDistance 81 * @type Number 82 * @default 150 83 */ 84 bounceDistance : { 85 value: 150 86 }, 87 88 /** 89 * The minimum flick gesture velocity (px/ms) at which to trigger the flick response 90 * 91 * @attribute minVelocity 92 * @type Number 93 * @default 0 94 */ 95 minVelocity : { 96 value: 0 97 }, 98 99 /** 100 * The minimum flick gesture distance (px) for which to trigger the flick response 101 * 102 * @attribute minVelocity 103 * @type Number 104 * @default 10 105 */ 106 minDistance : { 107 value: 10 108 }, 109 110 /** 111 * The constraining box relative to which the flick animation and bounds should be calculated. 112 * 113 * @attribute boundingBox 114 * @type Node 115 * @default parentNode 116 */ 117 boundingBox : { 118 valueFn : function() { 119 return this.get(HOST).get(PARENT_NODE); 120 } 121 }, 122 123 /** 124 * Time between flick animation frames. 125 * 126 * @attribute step 127 * @type Number 128 * @default 10 129 */ 130 step : { 131 value:10 132 }, 133 134 /** 135 * The custom duration to apply to the flick animation. By default, 136 * the animation duration is controlled by the deceleration factor. 137 * 138 * @attribute duration 139 * @type Number 140 * @default null 141 */ 142 duration : { 143 value:null 144 }, 145 146 /** 147 * The custom transition easing to use for the flick animation. If not 148 * provided defaults to internally to Flick.EASING, or Flick.SNAP_EASING based 149 * on whether or not we're animating the flick or bounce step. 150 * 151 * @attribute easing 152 * @type String 153 * @default null 154 */ 155 easing : { 156 value:null 157 } 158 }; 159 160 /** 161 * The NAME of the Flick class. Used to prefix events generated 162 * by the plugin. 163 * 164 * @property NAME 165 * @static 166 * @type String 167 * @default "pluginFlick" 168 */ 169 Flick.NAME = "pluginFlick"; 170 171 /** 172 * The namespace for the plugin. This will be the property on the node, which will 173 * reference the plugin instance, when it's plugged in. 174 * 175 * @property NS 176 * @static 177 * @type String 178 * @default "flick" 179 */ 180 Flick.NS = "flick"; 181 182 Y.extend(Flick, Y.Plugin.Base, { 183 184 /** 185 * The initializer lifecycle implementation. 186 * 187 * @method initializer 188 * @param {Object} config The user configuration for the plugin 189 */ 190 initializer : function(config) { 191 this._node = this.get(HOST); 192 193 this._renderClasses(); 194 this.setBounds(); 195 196 this._node.on(FLICK, Y.bind(this._onFlick, this), { 197 minDistance : this.get(MIN_DISTANCE), 198 minVelocity : this.get(MIN_VELOCITY) 199 }); 200 }, 201 202 /** 203 * Sets the min/max boundaries for the flick animation, 204 * based on the boundingBox dimensions. 205 * 206 * @method setBounds 207 */ 208 setBounds : function () { 209 var box = this.get(BOUNDING_BOX), 210 node = this._node, 211 212 boxHeight = box.get(OFFSET_HEIGHT), 213 boxWidth = box.get(OFFSET_WIDTH), 214 215 contentHeight = node.get(SCROLL_HEIGHT), 216 contentWidth = node.get(SCROLL_WIDTH); 217 218 if (contentHeight > boxHeight) { 219 this._maxY = contentHeight - boxHeight; 220 this._minY = 0; 221 this._scrollY = true; 222 } 223 224 if (contentWidth > boxWidth) { 225 this._maxX = contentWidth - boxWidth; 226 this._minX = 0; 227 this._scrollX = true; 228 } 229 230 this._x = this._y = 0; 231 232 node.set("top", this._y + "px"); 233 node.set("left", this._x + "px"); 234 }, 235 236 /** 237 * Adds the CSS classes, necessary to set up overflow/position properties on the 238 * node and boundingBox. 239 * 240 * @method _renderClasses 241 * @protected 242 */ 243 _renderClasses : function() { 244 this.get(BOUNDING_BOX).addClass(Flick.CLASS_NAMES.box); 245 this._node.addClass(Flick.CLASS_NAMES.content); 246 }, 247 248 /** 249 * The flick event listener. Kicks off the flick animation. 250 * 251 * @method _onFlick 252 * @param e {EventFacade} The flick event facade, containing e.flick.distance, e.flick.velocity etc. 253 * @protected 254 */ 255 _onFlick: function(e) { 256 this._v = e.flick.velocity; 257 this._flick = true; 258 this._flickAnim(); 259 }, 260 261 /** 262 * Executes a single frame in the flick animation 263 * 264 * @method _flickFrame 265 * @protected 266 */ 267 _flickAnim: function() { 268 269 var y = this._y, 270 x = this._x, 271 272 maxY = this._maxY, 273 minY = this._minY, 274 maxX = this._maxX, 275 minX = this._minX, 276 velocity = this._v, 277 278 step = this.get(STEP), 279 deceleration = this.get(DECELERATION), 280 bounce = this.get(BOUNCE); 281 282 this._v = (velocity * deceleration); 283 284 this._snapToEdge = false; 285 286 if (this._scrollX) { 287 x = x - (velocity * step); 288 } 289 290 if (this._scrollY) { 291 y = y - (velocity * step); 292 } 293 294 if (Math.abs(velocity).toFixed(4) <= Flick.VELOCITY_THRESHOLD) { 295 296 this._flick = false; 297 298 this._killTimer(!(this._exceededYBoundary || this._exceededXBoundary)); 299 300 if (this._scrollX) { 301 if (x < minX) { 302 this._snapToEdge = true; 303 this._setX(minX); 304 } else if (x > maxX) { 305 this._snapToEdge = true; 306 this._setX(maxX); 307 } 308 } 309 310 if (this._scrollY) { 311 if (y < minY) { 312 this._snapToEdge = true; 313 this._setY(minY); 314 } else if (y > maxY) { 315 this._snapToEdge = true; 316 this._setY(maxY); 317 } 318 } 319 320 } else { 321 322 if (this._scrollX && (x < minX || x > maxX)) { 323 this._exceededXBoundary = true; 324 this._v *= bounce; 325 } 326 327 if (this._scrollY && (y < minY || y > maxY)) { 328 this._exceededYBoundary = true; 329 this._v *= bounce; 330 } 331 332 if (this._scrollX) { 333 this._setX(x); 334 } 335 336 if (this._scrollY) { 337 this._setY(y); 338 } 339 340 this._flickTimer = Y.later(step, this, this._flickAnim); 341 } 342 }, 343 344 /** 345 * Internal utility method to set the X offset position 346 * 347 * @method _setX 348 * @param {Number} val 349 * @private 350 */ 351 _setX : function(val) { 352 this._move(val, null, this.get(DURATION), this.get(EASING)); 353 }, 354 355 /** 356 * Internal utility method to set the Y offset position 357 * 358 * @method _setY 359 * @param {Number} val 360 * @private 361 */ 362 _setY : function(val) { 363 this._move(null, val, this.get(DURATION), this.get(EASING)); 364 }, 365 366 /** 367 * Internal utility method to move the node to a given XY position, 368 * using transitions, if specified. 369 * 370 * @method _move 371 * @param {Number} x The X offset position 372 * @param {Number} y The Y offset position 373 * @param {Number} duration The duration to use for the transition animation 374 * @param {String} easing The easing to use for the transition animation. 375 * 376 * @private 377 */ 378 _move: function(x, y, duration, easing) { 379 380 if (x !== null) { 381 x = this._bounce(x); 382 } else { 383 x = this._x; 384 } 385 386 if (y !== null) { 387 y = this._bounce(y); 388 } else { 389 y = this._y; 390 } 391 392 duration = duration || this._snapToEdge ? Flick.SNAP_DURATION : 0; 393 easing = easing || this._snapToEdge ? Flick.SNAP_EASING : Flick.EASING; 394 395 this._x = x; 396 this._y = y; 397 398 this._anim(x, y, duration, easing); 399 }, 400 401 /** 402 * Internal utility method to perform the transition step 403 * 404 * @method _anim 405 * @param {Number} x The X offset position 406 * @param {Number} y The Y offset position 407 * @param {Number} duration The duration to use for the transition animation 408 * @param {String} easing The easing to use for the transition animation. 409 * 410 * @private 411 */ 412 _anim : function(x, y, duration, easing) { 413 var xn = x * -1, 414 yn = y * -1, 415 416 transition = { 417 duration : duration / 1000, 418 easing : easing 419 }; 420 421 Y.log("Transition: duration, easing:" + transition.duration, transition.easing, "node-flick"); 422 423 if (Y.Transition.useNative) { 424 transition.transform = 'translate('+ (xn) + 'px,' + (yn) +'px)'; 425 } else { 426 transition.left = xn + 'px'; 427 transition.top = yn + 'px'; 428 } 429 430 this._node.transition(transition); 431 }, 432 433 /** 434 * Internal utility method to constrain the offset value 435 * based on the bounce criteria. 436 * 437 * @method _bounce 438 * @param {Number} x The offset value to constrain. 439 * @param {Number} max The max offset value. 440 * 441 * @private 442 */ 443 _bounce : function(val, max) { 444 var bounce = this.get(BOUNCE), 445 dist = this.get(BOUNCE_DISTANCE), 446 min = bounce ? -dist : 0; 447 448 max = bounce ? max + dist : max; 449 450 if(!bounce) { 451 if(val < min) { 452 val = min; 453 } else if(val > max) { 454 val = max; 455 } 456 } 457 return val; 458 }, 459 460 /** 461 * Stop the animation timer 462 * 463 * @method _killTimer 464 * @private 465 */ 466 _killTimer: function() { 467 if(this._flickTimer) { 468 this._flickTimer.cancel(); 469 } 470 } 471 472 }, { 473 474 /** 475 * The threshold used to determine when the decelerated velocity of the node 476 * is practically 0. 477 * 478 * @property VELOCITY_THRESHOLD 479 * @static 480 * @type Number 481 * @default 0.015 482 */ 483 VELOCITY_THRESHOLD : 0.015, 484 485 /** 486 * The duration to use for the bounce snap-back transition 487 * 488 * @property SNAP_DURATION 489 * @static 490 * @type Number 491 * @default 400 492 */ 493 SNAP_DURATION : 400, 494 495 /** 496 * The default easing to use for the main flick movement transition 497 * 498 * @property EASING 499 * @static 500 * @type String 501 * @default 'cubic-bezier(0, 0.1, 0, 1.0)' 502 */ 503 EASING : 'cubic-bezier(0, 0.1, 0, 1.0)', 504 505 /** 506 * The default easing to use for the bounce snap-back transition 507 * 508 * @property SNAP_EASING 509 * @static 510 * @type String 511 * @default 'ease-out' 512 */ 513 SNAP_EASING : 'ease-out', 514 515 /** 516 * The default CSS class names used by the plugin 517 * 518 * @property CLASS_NAMES 519 * @static 520 * @type Object 521 */ 522 CLASS_NAMES : { 523 box: getClassName(Flick.NS), 524 content: getClassName(Flick.NS, "content") 525 } 526 }); 527 528 Y.Plugin.Flick = Flick; 529 530 531 }, '3.17.2', {"requires": ["classnamemanager", "transition", "event-flick", "plugin"], "skinnable": true});
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |