index.wxs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. var isOutRange = function (x1, y1, x2, y2, x3, y3) {
  2. return x1 < 0 || x1 >= y1 || x2 < 0 || x2 >= y2 || x3 < 0 || x3 >= y3
  3. };
  4. var sortCore = function (sKey, eKey, st) {
  5. var _ = st.baseData;
  6. var excludeFix = function (cKey, type) {
  7. if (st.list[cKey].fixed) { // fixed 元素位置不会变化, 这里直接用 cKey(sortKey) 获取, 更加快捷
  8. type ? --cKey : ++cKey;
  9. return excludeFix(cKey, type);
  10. }
  11. return cKey;
  12. }
  13. // 先获取到 endKey 对应的 realKey, 防止下面排序过程中该 realKey 被修改
  14. var endRealKey = -1;
  15. st.list.forEach(function (item) {
  16. if(item.sortKey === eKey) endRealKey = item.realKey;
  17. });
  18. return st.list.map(function (item) {
  19. if (item.fixed) return item;
  20. var cKey = item.sortKey;
  21. var rKey = item.realKey;
  22. if (sKey < eKey) {
  23. // 正序拖动
  24. if (cKey > sKey && cKey <= eKey) {
  25. --rKey;
  26. cKey = excludeFix(--cKey, true);
  27. } else if (cKey === sKey) {
  28. rKey = endRealKey;
  29. cKey = eKey;
  30. }
  31. } else if (sKey > eKey) {
  32. // 倒序拖动
  33. if (cKey >= eKey && cKey < sKey) {
  34. ++rKey
  35. cKey = excludeFix(++cKey, false);
  36. } else if (cKey === sKey) {
  37. rKey = endRealKey;
  38. cKey = eKey;
  39. }
  40. }
  41. if (item.sortKey !== cKey) {
  42. item.tranX = (cKey % _.columns) * 100 + "%";
  43. item.tranY = Math.floor(cKey / _.columns) * 100 + "%";
  44. item.sortKey = cKey;
  45. item.realKey = rKey;
  46. }
  47. return item;
  48. });
  49. }
  50. var triggerCustomEvent = function(list, type, ins,curIndex) {
  51. var _list = [], listData = [];
  52. list.forEach(function (item) {
  53. _list[item.sortKey] = item;
  54. });
  55. _list.forEach(function (item) {
  56. if (!item.extraNode) {
  57. listData.push(item.data);
  58. }
  59. });
  60. ins.triggerEvent(type, {listData: listData,curIndex:curIndex});
  61. }
  62. var longPress = function (event, ownerInstance) {
  63. var ins = event.instance;
  64. var st = ownerInstance.getState();
  65. var _ = st.baseData;
  66. var sTouch = event.changedTouches[0];
  67. if (!sTouch) return;
  68. st.cur = ins.getDataset().index;
  69. // 初始项是固定项则返回
  70. var item = st.list[st.cur];
  71. if (item && item.fixed) return;
  72. // 如果已经在 drag 中则返回, 防止多指触发 drag 动作, touchstart 事件中有效果
  73. if (st.dragging) return;
  74. st.dragging = true;
  75. ownerInstance.callMethod("drag", {dragging: true});
  76. // 计算X,Y轴初始位移, 使 item 中心移动到点击处, 单列时候X轴初始不做位移
  77. st.tranX = _.columns === 1 ? 0 : sTouch.pageX - (_.itemWidth / 2 + _.wrapLeft);
  78. st.tranY = sTouch.pageY - (_.itemHeight / 2 + _.wrapTop);
  79. st.sId = sTouch.identifier;
  80. ins.setStyle({
  81. 'transform': 'translate3d(' + st.tranX + 'px, ' + st.tranY + 'px, 0)'
  82. });
  83. st.itemsInstance.forEach(function (item, index) {
  84. item.removeClass("tran").removeClass("cur");
  85. item.addClass(index === st.cur ? "cur" : "tran");
  86. })
  87. ownerInstance.callMethod("vibrate");
  88. };
  89. var touchMove = function (event, ownerInstance) {
  90. var ins = event.instance;
  91. var st = ownerInstance.getState();
  92. var _ = st.baseData;
  93. var mTouch = event.changedTouches[0];
  94. if (!mTouch) return;
  95. if (!st.dragging) return;
  96. // 如果不是同一个触发点则返回
  97. if (st.sId !== mTouch.identifier) return;
  98. // 计算X,Y轴位移, 单列时候X轴初始不做位移
  99. var tranX = _.columns === 1 ? 0 : mTouch.pageX - (_.itemWidth / 2 + _.wrapLeft);
  100. var tranY = mTouch.pageY - (_.itemHeight / 2 + _.wrapTop);
  101. // 到顶到底自动滑动
  102. if (mTouch.clientY > _.windowHeight - _.itemHeight - _.realBottomSize) {
  103. // 当前触摸点pageY + item高度 - (屏幕高度 - 底部固定区域高度)
  104. ownerInstance.callMethod("pageScroll", {
  105. scrollTop: mTouch.pageY + _.itemHeight - (_.windowHeight - _.realBottomSize)
  106. });
  107. } else if (mTouch.clientY < _.itemHeight + _.realTopSize) {
  108. // 当前触摸点pageY - item高度 - 顶部固定区域高度
  109. ownerInstance.callMethod("pageScroll", {
  110. scrollTop: mTouch.pageY - _.itemHeight - _.realTopSize
  111. });
  112. }
  113. // 设置当前激活元素偏移量
  114. ins.setStyle({
  115. 'transform': 'translate3d(' + tranX + 'px, ' + tranY + 'px, 0)'
  116. })
  117. var startKey = st.list[st.cur].sortKey;
  118. var curX = Math.round(tranX / _.itemWidth);
  119. var curY = Math.round(tranY / _.itemHeight);
  120. var endKey = curX + _.columns * curY;
  121. // 目标项是固定项则返回
  122. var item = st.list[endKey];
  123. if (item && item.fixed) return;
  124. // X轴或Y轴超出范围则返回
  125. if (isOutRange(curX, _.columns, curY, _.rows, endKey, st.list.length)) return;
  126. // 防止拖拽过程中发生乱序问题
  127. if (startKey === endKey || startKey === st.preStartKey) return;
  128. st.preStartKey = startKey;
  129. var list = sortCore(startKey, endKey, st);
  130. st.itemsInstance.forEach(function (itemIns, index) {
  131. var item = list[index];
  132. if (index !== st.cur) {
  133. itemIns.setStyle({
  134. 'transform': 'translate3d(' + item.tranX + ',' + item.tranY + ', 0)'
  135. });
  136. }
  137. });
  138. ownerInstance.callMethod("vibrate");
  139. ownerInstance.callMethod("listChange", {list: list});
  140. triggerCustomEvent(list, "change", ownerInstance,st.cur);
  141. }
  142. var touchEnd = function (event, ownerInstance) {
  143. var ins = event.instance;
  144. var st = ownerInstance.getState();
  145. if (!st.dragging) return;
  146. triggerCustomEvent(st.list, "sortend", ownerInstance,st.cur);
  147. ins.addClass("tran");
  148. ins.setStyle({
  149. 'transform': 'translate3d(' + st.list[st.cur].tranX + ',' + st.list[st.cur].tranY + ', 0)'
  150. });
  151. st.preStartKey = -1;
  152. st.dragging = false;
  153. ownerInstance.callMethod("drag", {dragging: false});
  154. st.cur = -1;
  155. st.tranX = 0;
  156. st.tranY = 0;
  157. }
  158. var baseDataObserver = function (newVal, oldVal, ownerInstance, ins) {
  159. var st = ownerInstance.getState();
  160. st.baseData = newVal;
  161. }
  162. var listObserver = function (newVal, oldVal, ownerInstance, ins) {
  163. var st = ownerInstance.getState();
  164. st.itemsInstance = ownerInstance.selectAllComponents('.item');
  165. st.list = newVal || [];
  166. st.list.forEach(function (item, index) {
  167. var itemIns = st.itemsInstance[index];
  168. if (item && itemIns) {
  169. itemIns.setStyle({
  170. 'transform': 'translate3d(' + item.tranX + ',' + item.tranY + ', 0)'
  171. });
  172. if (item.fixed) itemIns.addClass("fixed");
  173. }
  174. })
  175. }
  176. module.exports = {
  177. longPress: longPress,
  178. touchMove: touchMove,
  179. touchEnd: touchEnd,
  180. baseDataObserver: baseDataObserver,
  181. listObserver: listObserver
  182. }