import { MovableArea, MovableView, View, ScrollView, Text, Image } from '@tarojs/components' import './MoveOrderList.scss' import { useEffect, useRef, useState } from 'react'; import { ColorType } from '@/context/themes/color'; import Taro from '@tarojs/taro'; import { IconDrag } from '@/components/basic/Icons'; import { rpxToPx } from '@/utils/tools'; export default function Component(props: { array: any, itemHeight: number, color?: string, update: Function }) { const [list, setList] = useState(props.array) const [movaleViewY, setMovaleViewY] = useState(0) const [dragElement, setDragElement] = useState(null) const [lastTarget, setLastTarget] = useState(null) const [startOffsetY, setStartOffsetY] = useState(0) const [startPageY, setStartPageY] = useState(0) const [dragIndex, setDragIndex] = useState(-1) const [scrollThreshold, setScrollThreshold] = useState(0.5) const upperThreshold = 100 const lowThreshold = 100 const [duration, setDuration] = useState(1000) const [canScroll, setCanScroll] = useState(true) const [changedIndex, setChangedIndex] = useState(-1) const [hiddenContent, setHiddenContent] = useState(false) const [scrollTop, setScrollTop] = useState(0) const [contentY, setContentY] = useState(0) const [contentHeight, setContentHeight] = useState(0) const ref = useRef(null) useEffect(() => { if (process.env.TARO_ENV == 'weapp') { const query = Taro.createSelectorQuery(); query.select('#myScrollView').boundingClientRect(); query.exec((res) => { setContentY(res[0].top) setContentHeight(res[0].height) }) } else { } }, []) function touchStart(e, index) { setChangedIndex(index) setStartOffsetY(index*props.itemHeight) setStartPageY(e.touches[0].pageY) setDragIndex(index) setDragElement(list[index]) setMovaleViewY(index*props.itemHeight) setCanScroll(false) } function longPress(e, index) { alert('long press') setChangedIndex(index) setStartOffsetY(e.target.offsetTop) setStartPageY(e.touches[0].pageY) setDragIndex(index) setDragElement(list[index]) setMovaleViewY(e.target.offsetTop) setCanScroll(false) } function touchMove(e) { if (dragElement) { let clientY = e.nativeEvent.locationY; pageScroll(clientY); let pageY = e.nativeEvent.pageY; let targetMoveDistance = pageY - startPageY let movaleViewY2 = startOffsetY + targetMoveDistance let targetIndex = computeFutureIndex(targetMoveDistance, dragIndex) if (targetIndex !== false && targetIndex != changedIndex) { var temps = swapListItems(list, targetIndex, changedIndex) setList(temps) setChangedIndex(targetIndex) } if (targetIndex === false && targetIndex != changedIndex) { var temps = swapListItems(list, dragIndex, changedIndex) setList(temps) setChangedIndex(dragIndex) } setMovaleViewY(movaleViewY2) setLastTarget(targetIndex as any) setHiddenContent(true) } } function pageScroll(clientY) { return // console.log(clientY,contentY,contentHeight) if ((clientY - contentY) + upperThreshold >= contentHeight) { // var scroll = ref.current // debugger // (ref.current as any).scrollTo({scrollTop:100}) // setScrollTop((clientY - contentY) + props.itemHeight) // setScrollTop(2200) // setCanScroll(true) Taro.pageScrollTo({ selector: '#myScrollView', scrollTop: (clientY - contentY) + props.itemHeight, duration: 200 }) } else if ((clientY - contentY) - lowThreshold <= 0) { setScrollTop((clientY - contentY) - props.itemHeight) // setCanScroll(true) } else { // setCanScroll(true) } } function swapListItems(list: T[], index1: number, index2: number): T[] { const newList = [...list]; const temp = newList[index1]; newList[index1] = newList[index2]; newList[index2] = temp; return newList; } function touchEnd(e) { if (dragElement) { // let pageY = e.changedTouches[0].pageY // let targetMoveDistance = pageY - startPageY; // let dragElementIndex = dragIndex; // const futrueIndex = computeFutureIndex(targetMoveDistance, dragElementIndex) // if (futrueIndex !== false) { // var temps = list // temps.splice(futrueIndex, 0, temps.splice(dragIndex, 1)[0]) // setList(temps) // } setDragElement(null) setLastTarget(null) setDragIndex(-1) } setChangedIndex(-1) setCanScroll(true) setHiddenContent(false) setMovaleViewY(-100) props.update(list) } function computeFutureIndex(targetMoveDistance, dragElementIndex) { let willInsertAfter = getSwapDirection(targetMoveDistance); if (willInsertAfter !== false) { /** 偏移索引 */ let offsetElementIndex = dragElementIndex + willInsertAfter; /** 移动步数 */ let step = targetMoveDistance / props.itemHeight; /** 步数补偿,当只有移动距离超过单项 _scrollThreshold 时才算有效 */ if (step <= -1) { step += scrollThreshold; } else if (step >= 1) { step -= scrollThreshold; } /** 目标索引 */ let futureIndex = parseInt(step) + offsetElementIndex; // 避免越界 if (futureIndex < 0) { futureIndex = 0; } else if (futureIndex > list.length - 1) { futureIndex = list.length - 1; } return futureIndex; } else { return willInsertAfter; } } function getSwapDirection(targetMoveDistance) { if (Math.abs(targetMoveDistance) < props.itemHeight / 2) { // 轻轻拂动,滑动距离小于1/2单项高度 return false; } else if (targetMoveDistance >= props.itemHeight / 2) { // console.log('[_getSwapDirection] 👇👇👇'); return 1; // 下滑 } else if (targetMoveDistance <= props.itemHeight / -2) { // console.log('[_getSwapDirection] 👆👆👆'); return -1; // 上滑 } } return { list.map((item, index) => { return longPress(e, index)} onTouchStart={(e) => touchStart(e, index)} onTouchMove={(e) => touchMove(e)} onTouchEnd={(e) => touchEnd(e)} > {item.name} }) } = 0 ? props.itemHeight : 0}}> { dragIndex >= 0 && {list[changedIndex].name} } {/* = 0 ? props.itemHeight : 0, width: rpxToPx(750),backgroundColor:'red' }} direction='vertical' disabled animation={true} y={movaleViewY} > { dragIndex >= 0 && {list[changedIndex].name} } */} }