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, 
 | 
}; 
 |