Lungo.Aside.coffee 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. ###
  2. Initialize the <articles> layout of a certain <section>
  3. @namespace Lungo
  4. @class Aside
  5. @author Javier Jimenez Villar <javi@tapquo.com> || @soyjavi
  6. ###
  7. Lungo.Aside = do (lng = Lungo) ->
  8. C = lng.Constants
  9. _callback = undefined
  10. _customAsideAnimation = undefined
  11. ###
  12. Display an aside element with a particular <section>
  13. @method show
  14. ###
  15. show = (aside_id, animate_section = true, fromX = 0) ->
  16. aside = lng.dom("##{aside_id}")
  17. if aside.length
  18. lng.Element.Cache.aside = aside
  19. aside_transition = aside.data(C.TRANSITION.ATTR) or "left"
  20. aside.addClass(C.CLASS.SHOW)
  21. if lng.DEVICE is C.DEVICE.PHONE
  22. if fromX then _phoneCustomAnimation fromX, false
  23. else lng.Element.Cache.section.data("aside-#{aside_transition}", "show")
  24. else
  25. aside_section = lng.dom("[data-aside=#{aside_id}]")
  26. if aside_section.data("children")
  27. if aside_section.attr("id") isnt lng.Element.Cache.section.attr("id")
  28. lng.Element.Cache.section.addClass "shadowing"
  29. aside_section.removeClass("aside").addClass "asideShowing"
  30. showFix = (aside_id) ->
  31. aside = lng.dom("##{aside_id}")
  32. if aside.length
  33. lng.Element.Cache.aside = aside
  34. aside.addClass(C.CLASS.SHOW).addClass("box")
  35. ###
  36. Hide an aside element with a particular section
  37. @method hide
  38. ###
  39. hide = (callback, fromX) ->
  40. if lng.Element.Cache.aside
  41. _callback = callback
  42. aside_transition = lng.Element.Cache.aside.data(C.TRANSITION.ATTR) or "left"
  43. if lng.DEVICE is C.DEVICE.PHONE
  44. lng.Element.Cache.section.removeClass("aside").removeClass("aside-right")
  45. if fromX then _phoneCustomAnimation fromX, true
  46. else lng.Element.Cache.section.data("aside-#{aside_transition}", "hide")
  47. else
  48. lng.dom(".aside").removeClass("aside").addClass("asideHidding")
  49. lng.Element.Cache.aside = null
  50. if callback then callback.call callback
  51. lng.dom(".shadow").removeClass("shadow").addClass("unshadowing")
  52. else if callback then callback.call callback
  53. ###
  54. Toggle an aside element
  55. @method toggle
  56. @param {string} Aside id
  57. ###
  58. toggle = (aside) ->
  59. if lng.Element.Cache.aside then do lng.Aside.hide
  60. else lng.Aside.show aside
  61. ###
  62. Triggered when <aside> animation ends.
  63. @method animationEnd
  64. @param {object} event
  65. ###
  66. animationEnd = (event) ->
  67. section = lng.dom(event.target)
  68. aside_transition = lng.Element.Cache.aside.data(C.TRANSITION.ATTR) or "left"
  69. if section.data("aside-#{aside_transition}") is "hide"
  70. lng.Element.Cache.aside.removeClass(C.CLASS.SHOW)
  71. lng.Element.Cache.aside = null
  72. section.removeAttr("data-aside-#{aside_transition}")
  73. if _callback then _callback.call _callback
  74. _callback = undefined
  75. else
  76. className = if aside_transition.indexOf("right") is -1 then "aside" else "aside-right"
  77. section.removeAttr("style").removeAttr("data-aside-#{aside_transition}").addClass(className)
  78. if _customAsideAnimation
  79. _customAsideAnimation.remove()
  80. _customAsideAnimation = undefined
  81. ###
  82. @todo
  83. @method draggable
  84. ###
  85. draggable = ->
  86. return false unless lng.DEVICE is C.DEVICE.PHONE
  87. MIN_XDIFF = 96
  88. lng.dom(C.QUERY.HREF_ASIDE).each ->
  89. started = false
  90. el = lng.dom(this)
  91. section = el.closest("section")
  92. aside = lng.dom("aside#" + el.data("aside"))
  93. section.swiping (gesture) ->
  94. unless section.hasClass("aside") or section.hasClass("aside-right")
  95. xdiff = gesture.currentTouch.x - gesture.iniTouch.x
  96. ydiff = Math.abs(gesture.currentTouch.y - gesture.iniTouch.y)
  97. started = (if started then true else xdiff > 3 * ydiff and xdiff < 50)
  98. if started
  99. xdiff = (if xdiff > 256 then 256 else (if xdiff < 0 then 0 else xdiff))
  100. aside.addClass C.CLASS.SHOW
  101. section.vendor "transform", "translateX(#{xdiff}px)"
  102. section.vendor "transition-duration", "0s"
  103. else
  104. section.attr "style", ""
  105. section.swipe (gesture) ->
  106. diff = gesture.currentTouch.x - gesture.iniTouch.x
  107. ydiff = Math.abs(gesture.currentTouch.y - gesture.iniTouch.y)
  108. section.attr "style", ""
  109. if diff > MIN_XDIFF and started
  110. show(aside.attr("id"), true, gesture.currentTouch.x)
  111. else hide
  112. started = false
  113. ###
  114. Private methods
  115. ###
  116. _asideStylesheet = ->
  117. if lng.Element.Cache.aside?.hasClass(C.CLASS.RIGHT) then "#{C.CLASS.RIGHT}" else " "
  118. _phoneCustomAnimation = (fromX, hide=false) ->
  119. if hide then kfStyle = document.createTextNode("""
  120. @-webkit-keyframes asideCustomKF {
  121. 0% { -webkit-transform: translateX(#{fromX}px); }
  122. 40% { -webkit-transform: translateX(#{fromX + 8}px); }
  123. 100% { -webkit-transform: translateX(0); }
  124. }""")
  125. else kfStyle = document.createTextNode("""
  126. @-webkit-keyframes asideCustomKF {
  127. 0% { -webkit-transform: translateX(#{fromX}px); }
  128. 60% { -webkit-transform: translateX(#{C.ASIDE.NORMAL + 8}px); }
  129. 100% { -webkit-transform: translateX(#{C.ASIDE.NORMAL}px); }
  130. }""")
  131. _customAsideAnimation = document.createElement('style')
  132. _customAsideAnimation.type = 'text/css'
  133. _customAsideAnimation.appendChild(kfStyle)
  134. document.getElementsByTagName("head")[0].appendChild(_customAsideAnimation)
  135. lng.Element.Cache.section.style("-webkit-animation-name", "asideCustomKF")
  136. toggle: toggle
  137. show: show
  138. showFix: showFix
  139. hide: hide
  140. draggable: draggable
  141. animationEnd: animationEnd