bindingx.js 5.6 KB

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