index.wxs 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. function setTimeout(instance, cb, time) {
  2. if (time > 0) {
  3. var s = getDate().getTime()
  4. var fn = function () {
  5. if (getDate().getTime() - s > time) {
  6. cb && cb()
  7. } else
  8. instance.requestAnimationFrame(fn)
  9. }
  10. fn()
  11. }
  12. else
  13. cb && cb()
  14. }
  15. // 判断触摸的移动方向
  16. function decideSwiperDirection(startTouches, currentTouches, vertical) {
  17. // 震动偏移容差
  18. var toleranceShake = 150
  19. // 移动容差
  20. var toleranceTranslate = 10
  21. if (!vertical) {
  22. // 水平方向移动
  23. if (Math.abs(currentTouches.y - startTouches.y) <= toleranceShake) {
  24. // console.log(currentTouches.x, startTouches.x);
  25. if (Math.abs(currentTouches.x - startTouches.x) > toleranceTranslate) {
  26. if (currentTouches.x - startTouches.x > 0) {
  27. return 'right'
  28. } else if (currentTouches.x - startTouches.x < 0) {
  29. return 'left'
  30. }
  31. }
  32. }
  33. } else {
  34. // 垂直方向移动
  35. if (Math.abs(currentTouches.x - startTouches.x) <= toleranceShake) {
  36. // console.log(currentTouches.x, startTouches.x);
  37. if (Math.abs(currentTouches.y - startTouches.y) > toleranceTranslate) {
  38. if (currentTouches.y - startTouches.y > 0) {
  39. return 'down'
  40. } else if (currentTouches.y - startTouches.y < 0) {
  41. return 'up'
  42. }
  43. }
  44. }
  45. }
  46. return ''
  47. }
  48. // swiperItem参数数据更新
  49. var itemDataObserver = function(newVal, oldVal, ownerInstance, instance) {
  50. if (!newVal || newVal === 'undefined') return
  51. var state = ownerInstance.getState()
  52. state.itemData = newVal
  53. }
  54. // swiperIndex数据更新
  55. var currentIndexObserver = function(newVal, oldVal, ownerInstance, instance) {
  56. if ((!newVal && newVal != 0) || newVal === 'undefined') return
  57. var state = ownerInstance.getState()
  58. state.currentIndex = newVal
  59. }
  60. // containerData数据更新
  61. var containerDataObserver = function(newVal, oldVal, ownerInstance, instance) {
  62. if (!newVal || newVal === 'undefined') return
  63. var state = ownerInstance.getState()
  64. state.containerData = newVal
  65. }
  66. // 开始触摸
  67. var touchStart = function(event, ownerInstance) {
  68. console.log('touchStart');
  69. var instance = event.instance
  70. var dataset = instance.getDataset()
  71. var state = ownerInstance.getState()
  72. var itemData = state.itemData
  73. var containerData = state.containerData
  74. // 由于当前SwiperIndex初始为0,可能会导致swiperIndex数据没有更新
  75. if (!state.currentIndex || state.currentIndex === 'undefined') {
  76. state.currentIndex = 0
  77. }
  78. if (!containerData || containerData.circular === 'undefined') {
  79. containerData.circular = false
  80. }
  81. state.containerData = containerData
  82. // 如果当前切换动画还没执行结束,再次触摸会重新加载对应的swiperContainer的信息
  83. // console.log(containerData.animationFinish);
  84. if (!containerData.animationFinish) {
  85. ownerInstance.callMethod('changeParentSwiperContainerStyleStatus',{
  86. status: 'reload'
  87. })
  88. }
  89. // 判断是否为为当前显示的SwiperItem
  90. if (itemData.index != state.currentIndex) return
  91. var touches = event.changedTouches[0]
  92. if (!touches) return
  93. // 标记滑动开始时间
  94. state.touchStartTime = getDate().getTime()
  95. // 记录当前滑动开始的x,y坐标
  96. state.touchRelactive = {
  97. x: touches.pageX,
  98. y: touches.pageY
  99. }
  100. // 记录触摸id,用于处理多指的情况
  101. state.touchId = touches.identifier
  102. // 标记开始触摸
  103. state.touching = true
  104. ownerInstance.callMethod('updateTouchingStatus', {
  105. status: true
  106. })
  107. }
  108. // 正在移动
  109. var touchMove = function(event, ownerInstance) {
  110. console.log('touchMove');
  111. var instance = event.instance
  112. var dataset = instance.getDataset()
  113. var state = ownerInstance.getState()
  114. var itemData = state.itemData
  115. var containerData = state.containerData
  116. // 判断是否为为当前显示的SwiperItem
  117. if (itemData.index != state.currentIndex) return
  118. // 判断是否开始触摸
  119. if (!state.touching) return
  120. var touches = event.changedTouches[0]
  121. if (!touches) return
  122. // 判断是否为同一个触摸点
  123. if (state.touchId != touches.identifier) return
  124. var currentTouchRelactive = {
  125. x: touches.pageX,
  126. y: touches.pageY
  127. }
  128. // 计算相对位移比例
  129. if (containerData.vertical) {
  130. var touchDistance = currentTouchRelactive.y - state.touchRelactive.y
  131. var itemHeight = itemData.itemHeight
  132. var distanceRate = touchDistance / itemHeight
  133. // console.log(currentTouchRelactive.y, touchDistance, itemHeight, distanceRate);
  134. // 判断是否为衔接轮播,如果不是衔接轮播,如果当前为第一个swiperItem并且向下滑、当前为最后一个swiperItem并且向上滑时不进行操作
  135. if (!containerData.circular &&
  136. ((state.currentIndex === 0 && touchDistance > 0) || (state.currentIndex === containerData.swiperItemLength - 1 && touchDistance < 0))
  137. ) {
  138. return
  139. }
  140. // 如果超出了距离则不进行操作
  141. if((Math.abs(touchDistance) > (itemData.itemTop + itemData.itemHeight))) {
  142. ownerInstance.callMethod('updateParentSwiperContainerStyle', {
  143. value: distanceRate < 0 ? -1 : 1
  144. })
  145. return
  146. }
  147. } else {
  148. var touchDistance = currentTouchRelactive.x - state.touchRelactive.x
  149. var itemWidth = itemData.itemWidth
  150. var distanceRate = touchDistance / itemWidth
  151. // console.log(currentTouchRelactive.x, touchDistance, itemWidth, distanceRate);
  152. // 判断是否为衔接轮播,如果不是衔接轮播,如果当前为第一个swiperItem并且向右滑、当前为最后一个swiperItem并且向左滑时不进行操作
  153. if (!containerData.circular &&
  154. ((state.currentIndex === 0 && touchDistance > 0) || (state.currentIndex === containerData.swiperItemLength - 1 && touchDistance < 0))
  155. ) {
  156. return
  157. }
  158. // 如果超出了距离则不进行操作
  159. if((Math.abs(touchDistance) > (itemData.itemLeft + itemData.itemWidth))) {
  160. ownerInstance.callMethod('updateParentSwiperContainerStyle', {
  161. value: distanceRate < 0 ? -1 : 1
  162. })
  163. return
  164. }
  165. }
  166. ownerInstance.callMethod('updateParentSwiperContainerStyle', {
  167. value: distanceRate
  168. })
  169. }
  170. // 移动结束
  171. var touchEnd = function(event, ownerInstance) {
  172. console.log('touchEnd');
  173. var instance = event.instance
  174. var dataset = instance.getDataset()
  175. var state = ownerInstance.getState()
  176. var itemData = state.itemData
  177. var containerData = state.containerData
  178. // 判断是否为为当前显示的SwiperItem
  179. if (itemData.index != state.currentIndex) return
  180. // 判断是否开始触摸
  181. if (!state.touching) return
  182. var touches = event.changedTouches[0]
  183. if (!touches) return
  184. // 判断是否为同一个触摸点
  185. if (state.touchId != touches.identifier) return
  186. var currentTime = getDate().getTime()
  187. var currentTouchRelactive = {
  188. x: touches.pageX,
  189. y: touches.pageY
  190. }
  191. if (containerData.vertical) {
  192. // 判断触摸移动方向
  193. var direction = decideSwiperDirection(state.touchRelactive, currentTouchRelactive, true)
  194. // 判断是否为衔接轮播,如果不是衔接轮播,如果当前为第一个swiperItem并且向下滑、当前为最后一个swiperItem并且向上滑时不进行操作
  195. if (containerData.circular ||
  196. !((state.currentIndex === 0 && direction === 'down') || (state.currentIndex === containerData.swiperItemLength - 1 && direction === 'up'))
  197. ) {
  198. // 判断触摸的时间和移动的距离是否超过了当前itemHeight的一半,如果是则执行切换操作
  199. // console.log(currentTime - state.touchStartTime, Math.abs(currentTouchRelactive.y - state.touchRelactive.y));
  200. if ((currentTime - state.touchStartTime) > 200 && Math.abs(currentTouchRelactive.y - state.touchRelactive.y) < itemData.itemHeight / 2) {
  201. ownerInstance.callMethod('changeParentSwiperContainerStyleStatus',{
  202. status: 'reset'
  203. })
  204. } else {
  205. // console.log(direction, state.touchRelactive.y, currentTouchRelactive.y);
  206. ownerInstance.callMethod('updateParentSwiperContainerStyleWithDirection', {
  207. direction: direction
  208. })
  209. }
  210. }
  211. } else {
  212. // 判断触摸移动方向
  213. var direction = decideSwiperDirection(state.touchRelactive, currentTouchRelactive, false)
  214. // 判断是否为衔接轮播,如果不是衔接轮播,如果当前为第一个swiperItem并且向右滑、当前为最后一个swiperItem并且向左滑时不进行操作
  215. if (containerData.circular ||
  216. !((state.currentIndex === 0 && direction === 'right') || (state.currentIndex === containerData.swiperItemLength - 1 && direction === 'left'))
  217. ) {
  218. // 判断触摸的时间和移动的距离是否超过了当前itemWidth的一半,如果是则执行切换操作
  219. // console.log(currentTime - state.touchStartTime, Math.abs(currentTouchRelactive.x - state.touchRelactive.x));
  220. if ((currentTime - state.touchStartTime) > 200 && Math.abs(currentTouchRelactive.x - state.touchRelactive.x) < itemData.itemWidth / 2) {
  221. ownerInstance.callMethod('changeParentSwiperContainerStyleStatus',{
  222. status: 'reset'
  223. })
  224. } else {
  225. // console.log(direction, state.touchRelactive.x, currentTouchRelactive.x);
  226. ownerInstance.callMethod('updateParentSwiperContainerStyleWithDirection', {
  227. direction: direction
  228. })
  229. }
  230. }
  231. }
  232. // 清除标记
  233. state.touchId = null
  234. state.touchRelactive = null
  235. state.touchStartTime = 0
  236. // 标记停止触摸
  237. state.touching = true
  238. ownerInstance.callMethod('updateTouchingStatus', {
  239. status: false
  240. })
  241. }
  242. module.exports = {
  243. itemDataObserver: itemDataObserver,
  244. currentIndexObserver: currentIndexObserver,
  245. containerDataObserver: containerDataObserver,
  246. touchStart: touchStart,
  247. touchMove: touchMove,
  248. touchEnd: touchEnd
  249. }