123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238 |
- var classPrefix = '';
- var startIndex = 0;
- var endIndex = 0;
- var dragCollisionList = [];
- var isOutRange = function (x1, y1, x2, y2, x3, y3) {
- return x1 < 0 || x1 >= y1 || x2 < 0 || x2 >= y2 || x3 < 0 || x3 >= y3;
- };
- var sortCore = function (sKey, eKey, st) {
- var _ = st.dragBaseData;
- var excludeFix = function (cKey, type) {
- if (st.list[cKey].fixed) {
- // fixed 元素位置不会变化, 这里直接用 cKey(sortKey) 获取, 更加快捷
- type ? --cKey : ++cKey;
- return excludeFix(cKey, type);
- }
- return cKey;
- };
- // 先获取到 endKey 对应的 realKey, 防止下面排序过程中该 realKey 被修改
- var endRealKey = -1;
- st.list.forEach(function (item) {
- if (item.sortKey === eKey) endRealKey = item.realKey;
- });
- return st.list.map(function (item) {
- if (item.fixed) return item;
- var cKey = item.sortKey;
- var rKey = item.realKey;
- if (sKey < eKey) {
- // 正序拖动
- if (cKey > sKey && cKey <= eKey) {
- --rKey;
- cKey = excludeFix(--cKey, true);
- } else if (cKey === sKey) {
- rKey = endRealKey;
- cKey = eKey;
- }
- } else if (sKey > eKey) {
- // 倒序拖动
- if (cKey >= eKey && cKey < sKey) {
- ++rKey;
- cKey = excludeFix(++cKey, false);
- } else if (cKey === sKey) {
- rKey = endRealKey;
- cKey = eKey;
- }
- }
- if (item.sortKey !== cKey) {
- item.tranX = (cKey % _.columns) * 100 + '%';
- item.tranY = Math.floor(cKey / _.columns) * 100 + '%';
- item.sortKey = cKey;
- item.realKey = rKey;
- }
- return item;
- });
- };
- var triggerCustomEvent = function (list, type, ins) {
- var _list = [],
- listData = [];
- list.forEach(function (item) {
- _list[item.sortKey] = item;
- });
- _list.forEach(function (item) {
- if (!item.extraNode) {
- listData.push(item.data);
- }
- });
- ins.triggerEvent(type, { listData: listData });
- };
- var longPress = function (event, ownerInstance) {
- var ins = event.instance;
- var st = ownerInstance.getState();
- var _ = st.dragBaseData;
- var sTouch = event.changedTouches[0];
- if (!sTouch) return;
- st.cur = ins.getDataset().index;
- longPressIndex = st.cur;
- // 初始项是固定项则返回
- var item = st.list[st.cur];
- if (item && item.fixed) return;
- // 如果已经在 drag 中则返回, 防止多指触发 drag 动作, touchstart 事件中有效果
- if (st.dragging) return;
- st.dragging = true;
- ownerInstance.callMethod('dragStatusChange', { dragging: true });
- // 计算X,Y轴初始位移, 使 item 中心移动到点击处, 单列时候X轴初始不做位移
- st.tranX = _.columns === 1 ? 0 : sTouch.pageX - (_.itemWidth / 2 + _.wrapLeft);
- st.tranY = sTouch.pageY - (_.itemHeight / 2 + _.wrapTop);
- st.sId = sTouch.identifier;
- ins.setStyle({
- transform: 'translate3d(' + st.tranX + 'px, ' + st.tranY + 'px, 0)',
- });
- st.itemsInstance.forEach(function (item, index) {
- item.removeClass(classPrefix + '__drag--tran').removeClass(classPrefix + '__drag--cur');
- item.addClass(index === st.cur ? classPrefix + '__drag--cur' : classPrefix + '__drag--tran');
- });
- ownerInstance.callMethod('dragVibrate', { vibrateType: 'longPress' });
- };
- var touchMove = function (event, ownerInstance) {
- var ins = event.instance;
- var st = ownerInstance.getState();
- var _ = st.dragBaseData;
- var mTouch = event.changedTouches[0];
- if (!mTouch) return;
- if (!st.dragging) return;
- // 如果不是同一个触发点则返回
- if (st.sId !== mTouch.identifier) return;
- // 计算X,Y轴位移, 单列时候X轴初始不做位移
- var tranX = _.columns === 1 ? 0 : mTouch.pageX - (_.itemWidth / 2 + _.wrapLeft);
- var tranY = mTouch.pageY - (_.itemHeight / 2 + _.wrapTop);
- // 到顶到底自动滑动
- if (mTouch.clientY > _.windowHeight - _.itemHeight - _.realBottomSize) {
- // 当前触摸点pageY + item高度 - (屏幕高度 - 底部固定区域高度)
- ownerInstance.callMethod('pageScroll', {
- scrollTop: mTouch.pageY + _.itemHeight - (_.windowHeight - _.realBottomSize),
- });
- } else if (mTouch.clientY < _.itemHeight + _.realTopSize) {
- // 当前触摸点pageY - item高度 - 顶部固定区域高度
- ownerInstance.callMethod('pageScroll', {
- scrollTop: mTouch.pageY - _.itemHeight - _.realTopSize,
- });
- }
- // 设置当前激活元素偏移量
- ins.setStyle({
- transform: 'translate3d(' + tranX + 'px, ' + tranY + 'px, 0)',
- });
- var startKey = st.list[st.cur].sortKey;
- var curX = Math.round(tranX / _.itemWidth);
- var curY = Math.round(tranY / _.itemHeight);
- var endKey = curX + _.columns * curY;
- // 目标项是固定项则返回
- var item = st.list[endKey];
- if (item && item.fixed) return;
- // X轴或Y轴超出范围则返回
- if (isOutRange(curX, _.columns, curY, _.rows, endKey, st.list.length)) return;
- // 防止拖拽过程中发生乱序问题
- if (startKey === endKey || startKey === st.preStartKey) return;
- st.preStartKey = startKey;
- dragCollisionList = sortCore(startKey, endKey, st);
- startIndex = startKey;
- endIndex = endKey;
- st.itemsInstance.forEach(function (itemIns, index) {
- var item = dragCollisionList[index];
- if (index !== st.cur) {
- itemIns.setStyle({
- transform: 'translate3d(' + item.tranX + ',' + item.tranY + ', 0)',
- });
- }
- });
- ownerInstance.callMethod('dragVibrate', { vibrateType: 'touchMove' });
- ownerInstance.callMethod('dragCollision', {
- dragCollisionList: dragCollisionList,
- startIndex: startIndex,
- endIndex: endIndex,
- });
- triggerCustomEvent(dragCollisionList, 'change', ownerInstance);
- };
- var touchEnd = function (event, ownerInstance) {
- var ins = event.instance;
- var st = ownerInstance.getState();
- if (!st.dragging) return;
- triggerCustomEvent(st.list, 'sortend', ownerInstance);
- ins.addClass(classPrefix + '__drag--tran');
- ins.setStyle({
- transform: 'translate3d(' + st.list[st.cur].tranX + ',' + st.list[st.cur].tranY + ', 0)',
- });
- st.preStartKey = -1;
- st.dragging = false;
- ownerInstance.callMethod('dragStatusChange', { dragging: false });
- ownerInstance.callMethod('dragEnd', {
- dragCollisionList: dragCollisionList,
- startIndex: startIndex,
- endIndex: endIndex,
- });
- st.cur = -1;
- st.tranX = 0;
- st.tranY = 0;
- };
- var baseDataObserver = function (newVal, oldVal, ownerInstance, ins) {
- var st = ownerInstance.getState();
- st.dragBaseData = newVal;
- classPrefix = newVal.classPrefix;
- };
- var listObserver = function (newVal, oldVal, ownerInstance, ins) {
- var st = ownerInstance.getState();
- st.itemsInstance = ownerInstance.selectAllComponents('.' + classPrefix + '__drag-item');
- st.list = newVal || [];
- st.list.forEach(function (item, index) {
- var itemIns = st.itemsInstance[index];
- if (item && itemIns) {
- itemIns.removeClass(classPrefix + '__drag--tran');
- itemIns.setStyle({
- transform: 'translate3d(' + item.tranX + ',' + item.tranY + ', 0)',
- });
- if (item.fixed) itemIns.addClass(classPrefix + '__drag--fixed');
- }
- });
- dragCollisionList = [];
- };
- module.exports = {
- longPress: longPress,
- touchMove: touchMove,
- touchEnd: touchEnd,
- baseDataObserver: baseDataObserver,
- listObserver: listObserver,
- };
|