[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/yuilib/3.17.2/node-flick/ -> node-flick-debug.js (source)

   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});


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1