bindingx.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. const BindingX = weex.requireModule('bindingx');
  2. const dom = weex.requireModule('dom');
  3. const animation = weex.requireModule('animation');
  4. export default {
  5. data() {
  6. return {
  7. right: 0,
  8. button: [],
  9. preventGesture: false
  10. }
  11. },
  12. mounted() {
  13. this.boxSelector = this.getEl(this.$refs['selector-box-hock']);
  14. this.selector = this.getEl(this.$refs['selector-content-hock']);
  15. this.buttonSelector = this.getEl(this.$refs['selector-button-hock']);
  16. this.position = {}
  17. this.x = 0
  18. setTimeout(() => {
  19. this.getSelectorQuery()
  20. }, 200)
  21. },
  22. beforeDestoy() {
  23. BindingX.unbind({
  24. token: this.timing.token,
  25. eventType: 'timing'
  26. })
  27. BindingX.unbind({
  28. token: this.pan.token,
  29. eventType: 'pan'
  30. })
  31. },
  32. watch: {
  33. show(newVal) {
  34. if (!this.position || JSON.stringify(this.position) === '{}') return;
  35. if (this.autoClose) return
  36. if (this.isInAnimation) return
  37. if (newVal) {
  38. this.open()
  39. } else {
  40. this.close()
  41. }
  42. },
  43. },
  44. methods: {
  45. onClick(index, item) {
  46. this.$emit('click', {
  47. content: item,
  48. index
  49. })
  50. },
  51. touchstart(e) {
  52. if (this.isInAnimation) return
  53. if (this.stop) return
  54. this.stop = true
  55. let endWidth = this.right
  56. let boxStep = `(x+${this.x})`
  57. let pageX = `${boxStep}> ${-endWidth} && ${boxStep} < 0?${boxStep}:(x+${this.x} < 0? ${-endWidth}:0)`
  58. let props = [{
  59. element: this.selector,
  60. property: 'transform.translateX',
  61. expression: pageX
  62. }]
  63. let left = 0
  64. for (let i = 0; i < this.options.length; i++) {
  65. let buttonSelectors = this.getEl(this.$refs['button-hock'][i]);
  66. if (this.button.length === 0 || !this.button[i] || !this.button[i].width) return
  67. let moveMix = endWidth - left
  68. left += this.button[i].width
  69. let step = `(${this.x}+x)/${endWidth}`
  70. let moveX = `(${step}) * ${moveMix}`
  71. let pageButtonX = `${moveX}&& (x+${this.x} > ${-endWidth})?${moveX}:${-moveMix}`
  72. props.push({
  73. element: buttonSelectors,
  74. property: 'transform.translateX',
  75. expression: pageButtonX
  76. })
  77. }
  78. this.eventpan = this._bind(this.boxSelector, props, 'pan', (e) => {
  79. if (e.state === 'end') {
  80. this.x = e.deltaX + this.x;
  81. if (this.x < -endWidth) {
  82. this.x = -endWidth
  83. }
  84. if (this.x > 0) {
  85. this.x = 0
  86. }
  87. this.stop = false
  88. this.bindTiming();
  89. }
  90. })
  91. },
  92. touchend(e) {
  93. this.$nextTick(() => {
  94. if (this.isopen && !this.isDrag && !this.isInAnimation) {
  95. this.close()
  96. }
  97. })
  98. },
  99. bindTiming() {
  100. if (this.isopen) {
  101. this.move(this.x, -this.right)
  102. } else {
  103. this.move(this.x, -40)
  104. }
  105. },
  106. move(left, value) {
  107. if (left >= value) {
  108. this.close()
  109. } else {
  110. this.open()
  111. }
  112. },
  113. /**
  114. * 开启swipe
  115. */
  116. open() {
  117. this.animation(true)
  118. },
  119. /**
  120. * 关闭swipe
  121. */
  122. close() {
  123. this.animation(false)
  124. },
  125. /**
  126. * 开启关闭动画
  127. * @param {Object} type
  128. */
  129. animation(type) {
  130. this.isDrag = true
  131. let endWidth = this.right
  132. let time = 200
  133. this.isInAnimation = true;
  134. let exit = `t>${time}`;
  135. let translate_x_expression = `easeOutExpo(t,${this.x},${type?(-endWidth-this.x):(-this.x)},${time})`
  136. let props = [{
  137. element: this.selector,
  138. property: 'transform.translateX',
  139. expression: translate_x_expression
  140. }]
  141. let left = 0
  142. for (let i = 0; i < this.options.length; i++) {
  143. let buttonSelectors = this.getEl(this.$refs['button-hock'][i]);
  144. if (this.button.length === 0 || !this.button[i] || !this.button[i].width) return
  145. let moveMix = endWidth - left
  146. left += this.button[i].width
  147. let step = `${this.x}/${endWidth}`
  148. let moveX = `(${step}) * ${moveMix}`
  149. let pageButtonX = `easeOutExpo(t,${moveX},${type ? -moveMix + '-' + moveX: 0 + '-' + moveX},${time})`
  150. props.push({
  151. element: buttonSelectors,
  152. property: 'transform.translateX',
  153. expression: pageButtonX
  154. })
  155. }
  156. this.timing = BindingX.bind({
  157. eventType: 'timing',
  158. exitExpression: exit,
  159. props: props
  160. }, (e) => {
  161. if (e.state === 'end' || e.state === 'exit') {
  162. this.x = type ? -endWidth : 0
  163. this.isInAnimation = false;
  164. this.isopen = type
  165. this.isDrag = false
  166. this.$emit('change', type)
  167. }
  168. });
  169. },
  170. /**
  171. * 绑定 BindingX
  172. * @param {Object} anchor
  173. * @param {Object} props
  174. * @param {Object} fn
  175. */
  176. _bind(anchor, props, eventType, fn) {
  177. return BindingX.bind({
  178. anchor,
  179. eventType,
  180. props
  181. }, (e) => {
  182. typeof(fn) === 'function' && fn(e)
  183. });
  184. },
  185. /**
  186. * 获取ref
  187. * @param {Object} el
  188. */
  189. getEl(el) {
  190. return el.ref
  191. },
  192. /**
  193. * 获取节点信息
  194. */
  195. getSelectorQuery() {
  196. dom.getComponentRect(this.$refs['selector-content-hock'], (data) => {
  197. if (this.position.content) return
  198. this.position.content = data.size
  199. })
  200. for (let i = 0; i < this.options.length; i++) {
  201. dom.getComponentRect(this.$refs['button-hock'][i], (data) => {
  202. if (!this.button) {
  203. this.button = []
  204. }
  205. if (this.options.length === this.button.length) return
  206. this.button.push(data.size)
  207. this.right += data.size.width
  208. if (this.autoClose) return
  209. if (this.show) {
  210. this.open()
  211. }
  212. })
  213. }
  214. }
  215. }
  216. }