1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
|
const MOVE_ANIM_INTER = 1000 const raf = window.requestAnimationFrame;
export default function draggable($ele, adsorb = { x: 20, y: 80 }) { if (!$ele) { throw new Error("必须是可拖拽元素"); } let startX = 0; let startY = 0;
let left = 0; let top = 0;
const cw = document.documentElement.clientWidth; const ch = document.documentElement.clientHeight;
const { width, height } = $ele.getBoundingClientRect();
$ele.addEventListener( "touchstart", function (event) { startX = event.targetTouches[0].pageX; startY = event.targetTouches[0].pageY;
top = $ele.offsetTop; left = $ele.offsetLeft;
event.preventDefault(); }, false );
$ele.addEventListener( "touchmove", function (event) { const offsetX = event.targetTouches[0].pageX - startX; const offsetY = event.targetTouches[0].pageY - startY;
$ele.style.top = `${top + offsetY}px`; $ele.style.left = `${left + offsetX}px`; $ele.style.right = "auto"; $ele.style.bottom = "auto";
event.preventDefault(); }, false );
function touchDone(event) { const dx = event.changedTouches[0].pageX - startX; const dy = event.changedTouches[0].pageY - startY;
const ty = top + dy; const tx = left + dx;
$ele.style.top = `${ty}px`; $ele.style.left = `${tx}px`; $ele.style.right = "auto"; $ele.style.bottom = "auto";
const adsorb_safe_x = cw - width - adsorb.x; const adsorb_safe_y = ch - height - adsorb.y;
raf(() => { console.log('raf') let nx; let ny = ty;
if (tx + width / 2 < cw / 2) { nx = adsorb.x; } else { nx = adsorb_safe_x; }
if (ty < adsorb.y) { ny = adsorb.y; } else if (ty > adsorb_safe_y) { ny = adsorb_safe_y; }
$ele.style.webkitTransition = `left ${MOVE_ANIM_INTER}ms ease-in-out, top ${MOVE_ANIM_INTER}ms ease-in-out`; $ele.style.transition = `left ${MOVE_ANIM_INTER}ms ease-in-out, top ${MOVE_ANIM_INTER}ms ease-in-out`;
const onAnimationDone = () => { $ele.style.webkitTransition = $ele.style.transition = "none"; $ele.removeEventListener("webkitTransitionEnd", onAnimationDone, false); $ele.removeEventListener("transitionend", onAnimationDone, false); };
$ele.addEventListener("webkitTransitionEnd", onAnimationDone, false); $ele.addEventListener("transitionend", onAnimationDone, false); $ele.style.top = `${ny}px`; $ele.style.left = `${nx}px`; }); }
$ele.addEventListener("touchend", touchDone, true); $ele.addEventListener("touchcancel", touchDone, true); }
|