1 // ==========================================================================
  2 // Project:   SproutCore
  3 // Copyright: @2013 7x7 Software, Inc.
  4 // License:   Licensed under MIT license (see license.js)
  5 // ==========================================================================
  6 
  7 
  8 SC.mixin(SC.View,
  9   /** @scope SC.View */ {
 10 
 11   /** @class
 12 
 13     To modify the bounce animation, you may set the following transition
 14     options in `transitionAdjustOptions`:
 15 
 16       - bounces {Number} the number of bounce back iterations.  Default: 2
 17       - bounciness {Number} the bounce coefficient.  Default: 0.25
 18       - duration {Number} the number of seconds for the animation.  Default: 0.4
 19 
 20     @extends SC.ViewTransitionProtocol
 21     @see SC.View#animate for other timing functions.
 22     @since Version 1.10
 23   */
 24   BOUNCE_ADJUST: {
 25 
 26     /** @private */
 27     run: function (view, options, finalLayout) {
 28       var bounces = options.bounces || 2,
 29         bounciness = options.bounciness || 0.25,
 30         layout = view.get('layout'),
 31         frames = [],
 32         frameCount = (bounces * 2) + 1,
 33         duration,
 34         i;
 35 
 36       // Split the duration evenly per frame.
 37       duration = options.duration || 0.4;
 38       duration = duration / frameCount;
 39 
 40       // Construct the frame layouts.
 41       for (i = 0; i < frameCount; i++) {
 42         if (i % 2) {
 43           // Bounce back.
 44           frames[i] = { value: SC.clone(finalLayout), duration: duration, timing: 'ease-out' };
 45         } else {
 46           // Hit target.
 47           if (i === frameCount - 1) {
 48             frames[i] = { value: SC.clone(finalLayout), duration: duration, timing: 'ease-in-out' };
 49           } else {
 50             frames[i] = { value: SC.clone(finalLayout), duration: duration, timing: 'ease-in' };
 51           }
 52         }
 53       }
 54 
 55       // Adjust the bounce frame layouts.
 56       for (var key in finalLayout) {
 57         var finalValue = finalLayout[key],
 58           // The bounce is based on the "distance" to the final value and the bounciness value.
 59           bounce = Math.round((finalValue - layout[key]) * bounciness);
 60 
 61         // Adjust the layout property for each bounce.
 62         for (i = 0; i < bounces; i++) {
 63           // Pull out the bounce frames only.
 64           frames[(i * 2) + 1].value[key] = finalValue - bounce;
 65 
 66           // Cut back the bounce amount after each bounce
 67           bounce = Math.round(bounce * 0.5);
 68         }
 69       }
 70 
 71       var callback = function () {
 72         view.didTransitionAdjust();
 73       };
 74 
 75       // Animate through the frames.
 76       view._animateFrames(frames, callback, options.delay || 0);
 77     }
 78   }
 79 
 80 });
 81