Files
2024-09-27 01:22:07 +08:00

133 lines
3.8 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

class Joystick {
// 元素id最大移动距离
constructor(stickID, direction, callback) {
this.id = stickID;
this.maxDistance = 64;
this.direction = direction;
this.callback = callback;
this.time = null
this.stick = document.getElementById(stickID);
// 开始拖动的位置,用于计算偏移量
this.dragStart = null;
// 如果存在多个操纵手柄,则跟踪触摸标识符
this.touchId = null;
this.active = false;
this.EventListener();
}
handleDown(event) {
this.active = true;
this.stick.style.transition = '0s';
// 阻止默认事件
event.preventDefault();
// 记录初始点击的坐标
if (event.changedTouches) {
this.dragStart = { x: event.changedTouches[0].clientX, y: event.changedTouches[0].clientY };
} else {
this.dragStart = { x: event.clientX, y: event.clientY };
}
// console.log("event: ", event);
// console.log("event.changedTouches: ", event.changedTouches);
// 记录点击的id
if (event.changedTouches) {
this.touchId = event.changedTouches[0].identifier;
}
}
handleMove(event) {
if (!this.active) return;
// 处理多点触控
if (event.changedTouches) {
for (let i = 0; i < event.changedTouches.length; i++) {
if (this.touchId == event.changedTouches[i].identifier) {
event.clientX = event.changedTouches[i].clientX;
event.clientY = event.changedTouches[i].clientY;
}
}
}
// 计算 x 轴距离
const xDiff = event.clientX - this.dragStart.x;
// 计算 y 轴距离
const yDiff = event.clientY - this.dragStart.y;
// 计算 角度
const angle = Math.atan2(yDiff, xDiff);
// 计算 距离
const distance = Math.min(this.maxDistance, Math.hypot(xDiff, yDiff));
// 计算 xy 的新位置
const xPosition = distance * Math.cos(angle);
const yPosition = distance * Math.sin(angle);
if (this.time && (Date.now() - this.time) < 160) return
this.time = Date.now()
if (this.direction == "x") {
// console.log("xPosition: ", Math.sign(xPosition));
// 左边 0 ~ -64 -1 3
if (xPosition < 0) {
if (xPosition < -63) {
console.log("左边: ", xPosition);
this.callback(3)
}
// 右边 1 4
} else if (xPosition > 0){
if (xPosition > 63) {
console.log("右边: ", xPosition);
this.callback(4)
}
}
// 将图片移动到新位置
this.stick.style.transform = `translate3d(${xPosition}px,0px, 0px)`;
// this.callback(Math.sign(xPosition) == -1 ? 3 : 4)
} else {
console.log("yPosition: ", yPosition);
this.stick.style.transform = `translate3d(0px,${yPosition}px, 0px)`;
this.callback(Math.sign(yPosition) == -1 ? 1 : 2, Math.round(255 * Math.round(Math.abs(yPosition)) / 64))
}
}
handleUp(event) {
if (!this.active) return;
if (event.changedTouches && this.touchId != event.changedTouches[0].identifier) return;
this.active = false;
// console.log("3 handleUp ==== ", this.active);
this.stick.style.transition = '.2s';
this.stick.style.transform = `translate3d(0px, 0px, 0px)`;
this.touchId = null;
this.callback(0, 0)
}
EventListener() {
// 鼠标 & 手指 按下
this.stick.addEventListener('mousedown', this.handleDown.bind(this));
this.stick.addEventListener('touchstart', this.handleDown.bind(this));
// 鼠标 & 手指 移动
document.addEventListener('mousemove', this.handleMove.bind(this), { passive: false });
document.addEventListener('touchmove', this.handleMove.bind(this), { passive: false });
// 鼠标 & 手指 松开
document.addEventListener('mouseup', this.handleUp.bind(this));
document.addEventListener('touchend', this.handleUp.bind(this));
}
}