foundation.util.motion.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. 'use strict';
  2. import $ from 'jquery';
  3. import { transitionend } from './foundation.core.utils';
  4. /**
  5. * Motion module.
  6. * @module foundation.motion
  7. */
  8. const initClasses = ['mui-enter', 'mui-leave'];
  9. const activeClasses = ['mui-enter-active', 'mui-leave-active'];
  10. const Motion = {
  11. animateIn: function(element, animation, cb) {
  12. animate(true, element, animation, cb);
  13. },
  14. animateOut: function(element, animation, cb) {
  15. animate(false, element, animation, cb);
  16. }
  17. }
  18. function Move(duration, elem, fn){
  19. var anim, prog, start = null;
  20. // console.log('called');
  21. if (duration === 0) {
  22. fn.apply(elem);
  23. elem.trigger('finished.zf.animate', [elem]).triggerHandler('finished.zf.animate', [elem]);
  24. return;
  25. }
  26. function move(ts){
  27. if(!start) start = ts;
  28. // console.log(start, ts);
  29. prog = ts - start;
  30. fn.apply(elem);
  31. if(prog < duration){ anim = window.requestAnimationFrame(move, elem); }
  32. else{
  33. window.cancelAnimationFrame(anim);
  34. elem.trigger('finished.zf.animate', [elem]).triggerHandler('finished.zf.animate', [elem]);
  35. }
  36. }
  37. anim = window.requestAnimationFrame(move);
  38. }
  39. /**
  40. * Animates an element in or out using a CSS transition class.
  41. * @function
  42. * @private
  43. * @param {Boolean} isIn - Defines if the animation is in or out.
  44. * @param {Object} element - jQuery or HTML object to animate.
  45. * @param {String} animation - CSS class to use.
  46. * @param {Function} cb - Callback to run when animation is finished.
  47. */
  48. function animate(isIn, element, animation, cb) {
  49. element = $(element).eq(0);
  50. if (!element.length) return;
  51. var initClass = isIn ? initClasses[0] : initClasses[1];
  52. var activeClass = isIn ? activeClasses[0] : activeClasses[1];
  53. // Set up the animation
  54. reset();
  55. element
  56. .addClass(animation)
  57. .css('transition', 'none');
  58. requestAnimationFrame(() => {
  59. element.addClass(initClass);
  60. if (isIn) element.show();
  61. });
  62. // Start the animation
  63. requestAnimationFrame(() => {
  64. element[0].offsetWidth;
  65. element
  66. .css('transition', '')
  67. .addClass(activeClass);
  68. });
  69. // Clean up the animation when it finishes
  70. element.one(transitionend(element), finish);
  71. // Hides the element (for out animations), resets the element, and runs a callback
  72. function finish() {
  73. if (!isIn) element.hide();
  74. reset();
  75. if (cb) cb.apply(element);
  76. }
  77. // Resets transitions and removes motion-specific classes
  78. function reset() {
  79. element[0].style.transitionDuration = 0;
  80. element.removeClass(`${initClass} ${activeClass} ${animation}`);
  81. }
  82. }
  83. export { Move, Motion };