1
0

Animation.coffee 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. class Animation
  2. slideDown: (elem, props) ->
  3. h = elem.offsetHeight
  4. cstyle = window.getComputedStyle(elem)
  5. margin_top = cstyle.marginTop
  6. margin_bottom = cstyle.marginBottom
  7. padding_top = cstyle.paddingTop
  8. padding_bottom = cstyle.paddingBottom
  9. border_top_width = cstyle.borderTopWidth
  10. border_bottom_width = cstyle.borderBottomWidth
  11. transition = cstyle.transition
  12. if window.Animation.shouldScrollFix(elem, props)
  13. # Keep objects in the screen at same position
  14. top_after = document.body.scrollHeight
  15. next_elem = elem.nextSibling
  16. parent = elem.parentNode
  17. parent.removeChild(elem)
  18. top_before = document.body.scrollHeight
  19. console.log("Scrollcorrection down", (top_before - top_after))
  20. window.scrollTo(window.scrollX, window.scrollY - (top_before - top_after))
  21. if next_elem
  22. parent.insertBefore(elem, next_elem)
  23. else
  24. parent.appendChild(elem)
  25. return
  26. if props.animate_scrollfix and elem.getBoundingClientRect().top > 1600
  27. # console.log "Skip down", elem
  28. return
  29. elem.style.boxSizing = "border-box"
  30. elem.style.overflow = "hidden"
  31. if not props.animate_noscale
  32. elem.style.transform = "scale(0.6)"
  33. elem.style.opacity = "0"
  34. elem.style.height = "0px"
  35. elem.style.marginTop = "0px"
  36. elem.style.marginBottom = "0px"
  37. elem.style.paddingTop = "0px"
  38. elem.style.paddingBottom = "0px"
  39. elem.style.borderTopWidth = "0px"
  40. elem.style.borderBottomWidth = "0px"
  41. elem.style.transition = "none"
  42. setTimeout (->
  43. elem.className += " animate-inout"
  44. elem.style.height = h+"px"
  45. elem.style.transform = "scale(1)"
  46. elem.style.opacity = "1"
  47. elem.style.marginTop = margin_top
  48. elem.style.marginBottom = margin_bottom
  49. elem.style.paddingTop = padding_top
  50. elem.style.paddingBottom = padding_bottom
  51. elem.style.borderTopWidth = border_top_width
  52. elem.style.borderBottomWidth = border_bottom_width
  53. ), 1
  54. elem.addEventListener "transitionend", ->
  55. elem.classList.remove("animate-inout")
  56. elem.style.transition = elem.style.transform = elem.style.opacity = elem.style.height = null
  57. elem.style.boxSizing = elem.style.marginTop = elem.style.marginBottom = null
  58. elem.style.paddingTop = elem.style.paddingBottom = elem.style.overflow = null
  59. elem.style.borderTopWidth = elem.style.borderBottomWidth = elem.style.overflow = null
  60. elem.removeEventListener "transitionend", arguments.callee, false
  61. shouldScrollFix: (elem, props) ->
  62. pos = elem.getBoundingClientRect()
  63. if props.animate_scrollfix and window.scrollY > 300 and pos.top < 0 and not document.querySelector(".noscrollfix:hover")
  64. return true
  65. else
  66. return false
  67. slideDownAnime: (elem, props) ->
  68. cstyle = window.getComputedStyle(elem)
  69. elem.style.overflowY = "hidden"
  70. anime({targets: elem, height: [0, elem.offsetHeight], easing: 'easeInOutExpo'})
  71. slideUpAnime: (elem, remove_func, props) ->
  72. elem.style.overflowY = "hidden"
  73. anime({targets: elem, height: [elem.offsetHeight, 0], complete: remove_func, easing: 'easeInOutExpo'})
  74. slideUp: (elem, remove_func, props) ->
  75. if window.Animation.shouldScrollFix(elem, props) and elem.nextSibling
  76. # Keep objects in the screen at same position
  77. top_after = document.body.scrollHeight
  78. next_elem = elem.nextSibling
  79. parent = elem.parentNode
  80. parent.removeChild(elem)
  81. top_before = document.body.scrollHeight
  82. console.log("Scrollcorrection down", (top_before - top_after))
  83. window.scrollTo(window.scrollX, window.scrollY + (top_before - top_after))
  84. if next_elem
  85. parent.insertBefore(elem, next_elem)
  86. else
  87. parent.appendChild(elem)
  88. remove_func()
  89. return
  90. if props.animate_scrollfix and elem.getBoundingClientRect().top > 1600
  91. remove_func()
  92. # console.log "Skip up", elem
  93. return
  94. elem.className += " animate-inout"
  95. elem.style.boxSizing = "border-box"
  96. elem.style.height = elem.offsetHeight+"px"
  97. elem.style.overflow = "hidden"
  98. elem.style.transform = "scale(1)"
  99. elem.style.opacity = "1"
  100. elem.style.pointerEvents = "none"
  101. setTimeout (->
  102. cstyle = window.getComputedStyle(elem)
  103. elem.style.height = "0px"
  104. elem.style.marginTop = (0-parseInt(cstyle.borderTopWidth)-parseInt(cstyle.borderBottomWidth))+"px"
  105. elem.style.marginBottom = "0px"
  106. elem.style.paddingTop = "0px"
  107. elem.style.paddingBottom = "0px"
  108. elem.style.transform = "scale(0.8)"
  109. elem.style.opacity = "0"
  110. ), 1
  111. elem.addEventListener "transitionend", (e) ->
  112. if e.propertyName == "opacity" or e.elapsedTime >= 0.6
  113. elem.removeEventListener "transitionend", arguments.callee, false
  114. setTimeout ( ->
  115. remove_func()
  116. ), 2000
  117. showRight: (elem, props) ->
  118. elem.className += " animate"
  119. elem.style.opacity = 0
  120. elem.style.transform = "TranslateX(-20px) Scale(1.01)"
  121. setTimeout (->
  122. elem.style.opacity = 1
  123. elem.style.transform = "TranslateX(0px) Scale(1)"
  124. ), 1
  125. elem.addEventListener "transitionend", ->
  126. elem.classList.remove("animate")
  127. elem.style.transform = elem.style.opacity = null
  128. elem.removeEventListener "transitionend", arguments.callee, false
  129. show: (elem, props) ->
  130. delay = arguments[arguments.length-2]?.delay*1000 or 1
  131. elem.className += " animate"
  132. elem.style.opacity = 0
  133. setTimeout (->
  134. elem.style.opacity = 1
  135. ), delay
  136. elem.addEventListener "transitionend", ->
  137. elem.classList.remove("animate")
  138. elem.style.opacity = null
  139. elem.removeEventListener "transitionend", arguments.callee, false
  140. hide: (elem, remove_func, props) ->
  141. delay = arguments[arguments.length-2]?.delay*1000 or 1
  142. elem.className += " animate"
  143. setTimeout (->
  144. elem.style.opacity = 0
  145. ), delay
  146. elem.addEventListener "transitionend", (e) ->
  147. if e.propertyName == "opacity"
  148. remove_func()
  149. elem.removeEventListener "transitionend", arguments.callee, false
  150. addVisibleClass: (elem, props) ->
  151. setTimeout ->
  152. elem.classList.add("visible")
  153. cloneAnimation: (elem, animation) ->
  154. window.requestAnimationFrame =>
  155. if elem.style.pointerEvents == "none" # Fix if animation called on cloned element
  156. elem = elem.nextSibling
  157. elem.style.position = "relative"
  158. elem.style.zIndex = "2"
  159. clone = elem.cloneNode(true)
  160. cstyle = window.getComputedStyle(elem)
  161. clone.classList.remove("loading")
  162. clone.style.position = "absolute"
  163. clone.style.zIndex = "1"
  164. clone.style.pointerEvents = "none"
  165. clone.style.animation = "none"
  166. # Check the position difference between original and cloned object
  167. elem.parentNode.insertBefore(clone, elem)
  168. cloneleft = clone.offsetLeft
  169. clone.parentNode.removeChild(clone) # Remove from dom to avoid animation
  170. clone.style.marginLeft = parseInt(cstyle.marginLeft) + elem.offsetLeft - cloneleft + "px"
  171. elem.parentNode.insertBefore(clone, elem)
  172. clone.style.animation = "#{animation} 0.8s ease-in-out forwards"
  173. setTimeout ( -> clone.remove() ), 1000
  174. flashIn: (elem) ->
  175. if elem.offsetWidth > 100
  176. @cloneAnimation(elem, "flash-in-big")
  177. else
  178. @cloneAnimation(elem, "flash-in")
  179. flashOut: (elem) ->
  180. if elem.offsetWidth > 100
  181. @cloneAnimation(elem, "flash-out-big")
  182. else
  183. @cloneAnimation(elem, "flash-out")
  184. window.Animation = new Animation()