import { reactive, ref } from "vue"; import { sum, square } from "../util"; export function useSlideAction() { const origin = reactive({ x: 0, y: 0, }); const success = ref(false); const isMouseDown = ref(false); const timestamp = ref(0); const trail = ref([]); const start = (e: MouseEvent | TouchEvent) => { if (success.value) return; if (e instanceof MouseEvent) { origin.x = e.clientX; origin.y = e.clientY; } else { origin.x = e.changedTouches[0].pageX; origin.y = e.changedTouches[0].pageY; } isMouseDown.value = true; timestamp.value = Date.now(); }; const move = (w: number, e: MouseEvent | TouchEvent, cb: (moveX: number) => void) => { if (!isMouseDown.value) return false; let moveX = 0; let moveY = 0; if (e instanceof MouseEvent) { moveX = e.clientX - origin.x; moveY = e.clientY - origin.y; } else { moveX = e.changedTouches[0].pageX - origin.x; moveY = e.changedTouches[0].pageY - origin.y; } if (moveX < 0 || moveX + 38 >= w) return false; cb(moveX); trail.value.push(moveY); }; /** * * @param left : block.style.left; * @param blockX * @param accuracy * @returns */ const verify = (left: string, blockX: number, accuracy: number) => { const arr = trail.value; // drag y move distance const average = arr.reduce(sum) / arr.length; // average const deviations = arr.map((x) => x - average); // deviation array const stddev = Math.sqrt(deviations.map(square).reduce(sum) / arr.length); // standard deviation const leftNum = parseInt(left); accuracy = accuracy <= 1 ? 1 : accuracy > 10 ? 10 : accuracy; return { spliced: Math.abs(leftNum - blockX) <= accuracy, TuringTest: average !== stddev, // equal => not person operate }; }; const end = (e: MouseEvent | TouchEvent, cb: (timestamp: number) => void) => { if (!isMouseDown.value) return false; isMouseDown.value = false; const moveX = e instanceof MouseEvent ? e.clientX : e.changedTouches[0].pageX; if (moveX === origin.x) return false; timestamp.value = Date.now() - timestamp.value; cb(timestamp.value); }; return { origin, success, isMouseDown, timestamp, trail, start, move, end, verify }; }