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     @extends SC.ViewTransitionProtocol
 14     @since Version 1.10
 15   */
 16   BOUNCE_IN: {
 17 
 18     /** @private */
 19     setup: function (view, options, inPlace) {
 20       var parentView = view.get('parentView'),
 21         parentFrame,
 22         viewFrame = view.get('borderFrame'),
 23         left,
 24         top;
 25 
 26 
 27       if (inPlace) {
 28         // Move from the current position.
 29       } else {
 30         // If there is no parentView, use the window's frame.
 31         if (parentView) {
 32           parentFrame = parentView.get('borderFrame');
 33         } else {
 34           parentFrame = SC.RootResponder.responder.currentWindowSize;
 35         }
 36 
 37         switch (options.direction) {
 38         case 'left':
 39           left = parentFrame.width;
 40           break;
 41         case 'up':
 42           top = parentFrame.height;
 43           break;
 44         case 'down':
 45           top = -viewFrame.height;
 46           break;
 47         default:
 48           left = -viewFrame.width;
 49         }
 50       }
 51 
 52       view.adjust({ centerX: null, centerY: null, bottom: null, left: left || viewFrame.x, right: null, top: top || viewFrame.y, height: viewFrame.height, width: viewFrame.width });
 53     },
 54 
 55     /** @private */
 56     run: function (view, options, finalLayout, finalFrame) {
 57       var layout = view.get('layout'),
 58         bounciness = options.bounciness || 0.25,
 59         bounce,
 60         duration,
 61         frames,
 62         finalValue,
 63         value, bounce1, bounce2;
 64 
 65       switch (options.direction) {
 66       case 'left':
 67         finalValue = finalFrame.x;
 68         value = { left: finalValue };
 69         bounce = -(finalValue - layout.left) * bounciness;
 70         bounce1 = { left: finalValue + bounce };
 71         bounce2 = { left: finalValue + (bounce * 0.5) };
 72         break;
 73       case 'up':
 74         finalValue = finalFrame.y;
 75         value = { top: finalValue };
 76         bounce = -(finalValue - layout.top) * bounciness;
 77         bounce1 = { top: finalValue + bounce };
 78         bounce2 = { top: finalValue + (bounce * 0.5) };
 79         break;
 80       case 'down':
 81         finalValue = finalFrame.y;
 82         value = { top: finalValue };
 83         bounce = (layout.top - finalValue) * bounciness;
 84         bounce1 = { top: finalValue + bounce };
 85         bounce2 = { top: finalValue + (bounce * 0.5) };
 86         break;
 87       default:
 88         finalValue = finalFrame.x;
 89         value = { left: finalValue };
 90         bounce = (layout.left - finalValue) * bounciness;
 91         bounce1 = { left: finalValue + bounce };
 92         bounce2 = { left: finalValue + (bounce * 0.5) };
 93       }
 94 
 95       // Split the duration evenly per frame.
 96       duration = options.duration || 0.4;
 97       duration = duration * 0.2;
 98 
 99       // Define the frames.
100       frames = [
101         { value: value, duration: duration, timing: 'ease-in' },
102         { value: bounce1, duration: duration, timing: 'ease-out' },
103         { value: value, duration: duration, timing: 'ease-in' },
104         { value: bounce2, duration: duration, timing: 'ease-out' },
105         { value: value, duration: duration, timing: 'ease-in-out' }
106       ];
107 
108       var callback = function (data) {
109         if (!data.isCancelled) {
110           view.didTransitionIn();
111         }
112       };
113 
114       // Animate through the frames.
115       view._animateFrames(frames, callback, options.delay || 0);
116     }
117   },
118 
119 
120   /** @class
121 
122     @extends SC.ViewTransitionProtocol
123     @since Version 1.10
124   */
125   BOUNCE_OUT: {
126 
127     /** @private */
128     setup: function (view, options) {
129       var viewFrame = view.get('borderFrame'),
130         left = viewFrame.x,
131         top = viewFrame.y,
132         height = viewFrame.height,
133         width = viewFrame.width;
134 
135       view.adjust({ centerX: null, centerY: null, bottom: null, left: left, right: null, top: top, height: height, width: width });
136     },
137 
138     /** @private */
139     run: function (view, options, finalLayout, finalFrame) {
140       var bounciness = options.bounciness || 0.25,
141         bounce,
142         bounceValue,
143         bounceValue2,
144         duration,
145         finalValue,
146         frames,
147         layout = view.get('layout'),
148         viewFrame = view.get('borderFrame'),
149         parentView = view.get('parentView'),
150         parentFrame,
151         startValue;
152 
153       // If there is no parentView, use the window's frame.
154       if (parentView) {
155         parentFrame = parentView.get('borderFrame');
156       } else {
157         parentFrame = SC.RootResponder.responder.currentWindowSize;
158       }
159 
160       switch (options.direction) {
161       case 'left':
162         startValue = { left: layout.left };
163         finalValue = { left: -viewFrame.width };
164         bounce = (layout.left + viewFrame.width) * bounciness;
165         bounceValue = { left: layout.left - (bounce * 0.5) };
166         bounceValue2 = { left: layout.left - bounce };
167         break;
168       case 'up':
169         startValue = { top: layout.top };
170         finalValue = { top: -viewFrame.height };
171         bounce = (layout.top + viewFrame.height) * bounciness;
172         bounceValue = { top: layout.top - (bounce * 0.5) };
173         bounceValue2 = { top: layout.top - bounce };
174         break;
175       case 'down':
176         startValue = { top: layout.top };
177         finalValue = { top: parentFrame.height };
178         bounce = (parentFrame.height - layout.top) * bounciness;
179         bounceValue = { top: layout.top + (bounce * 0.5) };
180         bounceValue2 = { top: layout.top + bounce };
181         break;
182       default:
183         startValue = { left: layout.left };
184         finalValue = { left: parentFrame.width };
185         bounce = (parentFrame.width - layout.left) * bounciness;
186         bounceValue = { left: layout.left + (bounce * 0.5) };
187         bounceValue2 = { left: layout.left + bounce };
188       }
189 
190       // Split the duration evenly per frame.
191       duration = options.duration || 0.6;
192       duration = duration * 0.2;
193 
194       // Define the frames.
195       frames = [
196         { value: bounceValue, duration: duration, timing: 'ease-out' },
197         { value: startValue, duration: duration, timing: 'ease-in' },
198         { value: bounceValue2, duration: duration, timing: 'ease-out' },
199         { value: startValue, duration: duration, timing: 'ease-in-out' },
200         { value: finalValue, duration: duration, timing: 'ease-in' }
201       ];
202 
203       var callback = function (data) {
204         if (!data.isCancelled) {
205           view.didTransitionOut();
206         }
207       };
208 
209       // Animate through the frames.
210       view._animateFrames(frames, callback, options.delay || 0);
211     }
212 
213   }
214 
215 });
216