src/cm/media/js/lib/yui/yui_3.10.3/build/node-flick/node-flick-debug.js
changeset 525 89ef5ed3c48b
equal deleted inserted replaced
524:322d0feea350 525:89ef5ed3c48b
       
     1 /*
       
     2 YUI 3.10.3 (build 2fb5187)
       
     3 Copyright 2013 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.10.3', {"requires": ["classnamemanager", "transition", "event-flick", "plugin"], "skinnable": true});