Posted By

lozioric on 04/27/09


Tagged

transition effect easing Scriptaculous


Versions (?)

Robert Penner's ActionScript easing functions ported to Scriptaculous 1.8


 / Published in: JavaScript
 

URL: http://groups.google.com/group/prototype-scriptaculous/browse_thread/thread/f584addd79fe323a

  1. // Effect.Transitions.easing.js
  2. //==============================================================================
  3. // Robert Penner's easing functions v2.0 (http://www.robertpenner.com/easing)
  4. // Ported to Scriptaculous 1.8 by Riccardo De Agostini (lozioric AT gmail.com)
  5. //
  6. // Original terms of use (http://www.robertpenner.com/easing_terms_of_use.html)
  7. // also apply to this modification.
  8. //==============================================================================
  9. //
  10. // Penner's functions take a minimum of four parameters named t, b, c and d,
  11. // plus, in some cases, optional customization parameters (for details, see
  12. // http://www.robertpenner.com/easing/penner_chapter7_tweening.pdf)
  13. //
  14. // Scriptaculous' transitions are a simplified case of Penner's functions,
  15. // where b is always 0, c is always 1, and d is always 1. I've thus simplified
  16. // the original ActionScript code.
  17. // I've also added some transformation functions, which can take an easeIn, an
  18. // easeOut or an easeIn / easeOut pair and turn them into a complete set of
  19. // transition functions. This obviously introduces some overhead, but greatly
  20. // simplifies the code.
  21. //
  22. // Simple usage example:
  23. //
  24. // new Effect.Move(myElement, {
  25. // transition: Effect.Transitions.Cubic.easeInOut
  26. // });
  27. //
  28. // Customization parameters, where present, may be used as follows:
  29. //
  30. // // No customization (use Penner's default value)
  31. // new Effect.Move(myElement, {
  32. // transition: Effect.Transitions.Back.easeIn
  33. // });
  34. //
  35. // // Customized easing
  36. // new Effect.Move(myElement, {
  37. // transition: Effect.Transitions.Back.easeIn.custom(2.5)
  38. // });
  39. //
  40. //==============================================================================
  41. // Changelog:
  42. // 2009-04-24 Initial release
  43. // 2009-04-27 Corrected Sine functions, thanks to advice from Henry on Google's
  44. // prototype-scriptaculous group
  45. // Added pre-computed HALF_PI and TWO_PI (also thanks to Henry)
  46. //==============================================================================
  47.  
  48. Object.extend(Effect.Transitions, (function() {
  49.  
  50. //----------------------------------------------------------------------
  51. // Function transformations
  52. //----------------------------------------------------------------------
  53.  
  54. // easeIn to easeOut and vice versa
  55. function reverse(eq, t)
  56. {
  57. return 1 - eq(1 - t);
  58. }
  59.  
  60. // easeIn to easeInOut
  61. function easeInToEaseInOut(easeIn, t)
  62. {
  63. t = 2 * t;
  64. return 0.5 * (t < 1 ? easeIn(t) : 2 - easeIn(2 - t));
  65. }
  66.  
  67. // easeOut to easeInOut
  68. function easeOutToEaseInOut(easeOut, t)
  69. {
  70. t = 2 * t;
  71. return 0.5 * (t < 1 ? 1 - easeOut(1 - t) : 1 + easeOut(t - 1));
  72. }
  73.  
  74. // easeIn / easeOut pair to easeInOut
  75. function easeInOutPairToEaseInOut(easeIn, easeOut, t)
  76. {
  77. t = 2 * t;
  78. return 0.5 * (t < 1 ? easeIn(t) : 1 + easeOut(t - 1));
  79. }
  80.  
  81. //----------------------------------------------------------------------
  82. // Function set builders
  83. //----------------------------------------------------------------------
  84.  
  85. // Build a function set from a complete set of easing functions
  86. function functionSet(easeIn, easeOut, easeInOut)
  87. {
  88. return {
  89. easeIn : easeIn,
  90. easeOut : easeOut,
  91. easeInOut: easeInOut
  92. };
  93. }
  94.  
  95. // Build a complete function set from just an easeIn
  96. function functionSetFromEaseIn(easeIn)
  97. {
  98. return {
  99. easeIn : easeIn,
  100. easeOut : reverse.curry(easeIn),
  101. easeInOut: easeInToEaseInOut.curry(easeIn)
  102. };
  103. }
  104.  
  105. // Build a complete function set from just an easeOut
  106. function functionSetFromEaseOut(easeOut)
  107. {
  108. return {
  109. easeIn : reverse.curry(easeOut),
  110. easeOut : easeOut,
  111. easeInOut: easeOutToEaseInOut.curry(easeOut)
  112. };
  113. }
  114.  
  115. // Build a complete function set from an easeIn / easeOut pair
  116. function functionSetFromEaseInOutPair(easeIn, easeOut)
  117. {
  118. return {
  119. easeIn : easeIn,
  120. easeOut : easeOut,
  121. easeInOut: easeInOutPairToEaseInOut.curry(easeIn, easeOut)
  122. };
  123. }
  124.  
  125. // Build a complete function set from just an easeIn,
  126. // where the given function has custom parameters
  127. function customizableFunctionSetFromEaseIn()
  128. {
  129. var args = $A(arguments);
  130. var easeIn = args.shift();
  131.  
  132. function customEaseIn()
  133. {
  134. var args = [0].concat($A(arguments));
  135.  
  136. return function(t)
  137. {
  138. args[0] = t;
  139. return easeIn.apply(this, args);
  140. };
  141. }
  142.  
  143. function customEaseOut()
  144. {
  145. return reverse.curry(customEaseIn.apply(this, arguments));
  146. }
  147.  
  148. function customEaseInOut()
  149. {
  150. return easeInToEaseInOut.curry(customEaseIn.apply(this, arguments));
  151. }
  152.  
  153. var myEaseIn = customEaseIn.apply(this, args);
  154. myEaseIn.custom = customEaseIn;
  155. var myEaseOut = reverse.curry(myEaseIn);
  156. myEaseOut.custom = customEaseOut;
  157. var myEaseInOut = easeInToEaseInOut.curry(myEaseIn);
  158. myEaseInOut.custom = customEaseInOut;
  159.  
  160. return {
  161. easeIn : myEaseIn,
  162. easeOut : myEaseOut,
  163. easeInOut: myEaseInOut
  164. };
  165. }
  166.  
  167. //----------------------------------------------------------------------
  168. // Useful pre-computed values
  169. //----------------------------------------------------------------------
  170.  
  171. var HALF_PI = Math.PI / 2;
  172. var TWO_PI = 2 * Math.PI;
  173.  
  174. //----------------------------------------------------------------------
  175. // Penner's tween equations, simplified for Scriptaculous
  176. //----------------------------------------------------------------------
  177.  
  178. function Quad_easeIn(t)
  179. {
  180. return t * t;
  181. }
  182.  
  183. function Cubic_easeIn(t)
  184. {
  185. return t * t * t;
  186. }
  187.  
  188. function Quart_easeIn(t)
  189. {
  190. return t * t * t * t;
  191. }
  192.  
  193. function Quint_easeIn(t)
  194. {
  195. return t * t * t * t * t;
  196. }
  197.  
  198. // This one is not Penner's: it's just a generalized case, for use when
  199. // i.e. Quad is too "soft" for your tastes but Cubic is too "quick"
  200. // (in this specific case you could use Pow.custom(2.5) for example)
  201. function Pow_easeIn(t, p)
  202. {
  203. return Math.pow(t, p);
  204. }
  205.  
  206. function Back_easeIn(t, s)
  207. {
  208. return t * t * ((s + 1) * t - s);
  209. }
  210.  
  211. // TODO (maybe): customize (customizableize? :-) ) this one
  212. function Bounce_easeOut(t)
  213. {
  214. if (t < (1 / 2.75))
  215. return 7.5625 * t * t;
  216. if (t < (2 / 2.75))
  217. return 7.5625 * (t-= (1.5 / 2.75)) * t + 0.75;
  218. if (t < (2.5 / 2.75))
  219. return 7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375;
  220. return 7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375;
  221. }
  222.  
  223. function Circ_easeIn(t)
  224. {
  225. return -1 * (Math.sqrt(1 - t * t) - 1);
  226. }
  227.  
  228. function Circ_easeOut(t)
  229. {
  230. t -= 1;
  231. return Math.sqrt(1 - t * t);
  232. }
  233.  
  234. function Elastic_easeIn(t, a, p)
  235. {
  236. if (t == 0) return 0;
  237. if (t == 1) return 1;
  238. if (a < 1)
  239. {
  240. a = 1;
  241. var s = p / 4;
  242. }
  243. else
  244. {
  245. var s = p / TWO_PI * Math.asin(1 / a);
  246. }
  247. return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * TWO_PI / p));
  248. }
  249.  
  250. function Expo_easeIn(t)
  251. {
  252. return (t == 0) ? 0 : Math.pow(2, 10 * (t - 1));
  253. }
  254.  
  255. function Expo_easeOut(t)
  256. {
  257. return (t == 1) ? 1 : 1 - Math.pow(2, -10 * t);
  258. }
  259.  
  260. function Sine_easeIn(t)
  261. {
  262. return Math.cos(t * HALF_PI) + 1;
  263. }
  264.  
  265. function Sine_easeOut(t)
  266. {
  267. return Math.sin(t * HALF_PI);
  268. }
  269.  
  270. function Sine_easeInOut(t)
  271. {
  272. return -0.5 * (Math.cos(Math.PI * t) - 1);
  273. }
  274.  
  275. //--------------------------------------------------------------------------
  276. // Build and return the equation sets
  277. //--------------------------------------------------------------------------
  278.  
  279. return {
  280. Quad : functionSetFromEaseIn(Quad_easeIn),
  281. Cubic : functionSetFromEaseIn(Cubic_easeIn),
  282. Quart : functionSetFromEaseIn(Quart_easeIn),
  283. Quint : functionSetFromEaseIn(Quint_easeIn),
  284. Pow : customizableFunctionSetFromEaseIn(Pow_easeIn, 2), // Defaults to Quad
  285. Back : customizableFunctionSetFromEaseIn(Back_easeIn, 1.70158),
  286. Bounce : functionSetFromEaseOut(Bounce_easeOut),
  287. Circ : functionSetFromEaseInOutPair(Circ_easeIn, Circ_easeOut),
  288. Elastic: customizableFunctionSetFromEaseIn(Elastic_easeIn, 1, 0.3),
  289. Expo : functionSetFromEaseInOutPair(Expo_easeIn, Expo_easeOut),
  290. Sine : functionSet(Sine_easeIn, Sine_easeOut, Sine_easeInOut)
  291. };
  292.  
  293. })());
  294.  
  295. // EOF

Report this snippet  

You need to login to post a comment.