You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

245 lines
5.8 KiB

3 years ago
  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) {
  60. this.$emit('click', {
  61. content: item,
  62. index
  63. })
  64. },
  65. touchstart(e) {
  66. if (this.isInAnimation) return
  67. if (this.stop) return
  68. this.stop = true
  69. if (this.autoClose) {
  70. this.swipeaction.closeOther(this)
  71. }
  72. let endWidth = this.right
  73. let boxStep = `(x+${this.x})`
  74. let pageX = `${boxStep}> ${-endWidth} && ${boxStep} < 0?${boxStep}:(x+${this.x} < 0? ${-endWidth}:0)`
  75. let props = [{
  76. element: this.selector,
  77. property: 'transform.translateX',
  78. expression: pageX
  79. }]
  80. let left = 0
  81. for (let i = 0; i < this.options.length; i++) {
  82. let buttonSelectors = this.getEl(this.$refs['button-hock'][i]);
  83. if (this.button.length === 0 || !this.button[i] || !this.button[i].width) return
  84. let moveMix = endWidth - left
  85. left += this.button[i].width
  86. let step = `(${this.x}+x)/${endWidth}`
  87. let moveX = `(${step}) * ${moveMix}`
  88. let pageButtonX = `${moveX}&& (x+${this.x} > ${-endWidth})?${moveX}:${-moveMix}`
  89. props.push({
  90. element: buttonSelectors,
  91. property: 'transform.translateX',
  92. expression: pageButtonX
  93. })
  94. }
  95. this.eventpan = this._bind(this.boxSelector, props, 'pan', (e) => {
  96. if (e.state === 'end') {
  97. this.x = e.deltaX + this.x;
  98. if (this.x < -endWidth) {
  99. this.x = -endWidth
  100. }
  101. if (this.x > 0) {
  102. this.x = 0
  103. }
  104. this.stop = false
  105. this.bindTiming();
  106. }
  107. })
  108. },
  109. touchend(e) {
  110. this.$nextTick(() => {
  111. if (this.isopen && !this.isDrag && !this.isInAnimation) {
  112. this.close()
  113. }
  114. })
  115. },
  116. bindTiming() {
  117. if (this.isopen) {
  118. this.move(this.x, -this.right)
  119. } else {
  120. this.move(this.x, -40)
  121. }
  122. },
  123. move(left, value) {
  124. if (left >= value) {
  125. this.close()
  126. } else {
  127. this.open()
  128. }
  129. },
  130. /**
  131. * 开启swipe
  132. */
  133. open() {
  134. this.animation(true)
  135. },
  136. /**
  137. * 关闭swipe
  138. */
  139. close() {
  140. this.animation(false)
  141. },
  142. /**
  143. * 开启关闭动画
  144. * @param {Object} type
  145. */
  146. animation(type) {
  147. this.isDrag = true
  148. let endWidth = this.right
  149. let time = 200
  150. this.isInAnimation = true;
  151. let exit = `t>${time}`;
  152. let translate_x_expression = `easeOutExpo(t,${this.x},${type?(-endWidth-this.x):(-this.x)},${time})`
  153. let props = [{
  154. element: this.selector,
  155. property: 'transform.translateX',
  156. expression: translate_x_expression
  157. }]
  158. let left = 0
  159. for (let i = 0; i < this.options.length; i++) {
  160. let buttonSelectors = this.getEl(this.$refs['button-hock'][i]);
  161. if (this.button.length === 0 || !this.button[i] || !this.button[i].width) return
  162. let moveMix = endWidth - left
  163. left += this.button[i].width
  164. let step = `${this.x}/${endWidth}`
  165. let moveX = `(${step}) * ${moveMix}`
  166. let pageButtonX = `easeOutExpo(t,${moveX},${type ? -moveMix + '-' + moveX: 0 + '-' + moveX},${time})`
  167. props.push({
  168. element: buttonSelectors,
  169. property: 'transform.translateX',
  170. expression: pageButtonX
  171. })
  172. }
  173. this.timing = BindingX.bind({
  174. eventType: 'timing',
  175. exitExpression: exit,
  176. props: props
  177. }, (e) => {
  178. if (e.state === 'end' || e.state === 'exit') {
  179. this.x = type ? -endWidth : 0
  180. this.isInAnimation = false;
  181. this.isopen = this.isopen || false
  182. if (this.isopen !== type) {
  183. this.$emit('change', type)
  184. }
  185. this.isopen = type
  186. this.isDrag = false
  187. }
  188. });
  189. },
  190. /**
  191. * 绑定 BindingX
  192. * @param {Object} anchor
  193. * @param {Object} props
  194. * @param {Object} fn
  195. */
  196. _bind(anchor, props, eventType, fn) {
  197. return BindingX.bind({
  198. anchor,
  199. eventType,
  200. props
  201. }, (e) => {
  202. typeof(fn) === 'function' && fn(e)
  203. });
  204. },
  205. /**
  206. * 获取ref
  207. * @param {Object} el
  208. */
  209. getEl(el) {
  210. return el.ref
  211. },
  212. /**
  213. * 获取节点信息
  214. */
  215. getSelectorQuery() {
  216. dom.getComponentRect(this.$refs['selector-content-hock'], (data) => {
  217. if (this.position.content) return
  218. this.position.content = data.size
  219. })
  220. for (let i = 0; i < this.options.length; i++) {
  221. dom.getComponentRect(this.$refs['button-hock'][i], (data) => {
  222. if (!this.button) {
  223. this.button = []
  224. }
  225. if (this.options.length === this.button.length) return
  226. this.button.push(data.size)
  227. this.right += data.size.width
  228. if (this.autoClose) return
  229. if (this.show) {
  230. this.open()
  231. }
  232. })
  233. }
  234. }
  235. }
  236. }