You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
76 lines
2.3 KiB
76 lines
2.3 KiB
6 months ago
|
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<number[]>([]);
|
||
|
|
||
|
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 };
|
||
|
}
|