Skip to content

Commit

Permalink
feat: Touch device support
Browse files Browse the repository at this point in the history
  • Loading branch information
sweetbrulee committed Sep 15, 2024
1 parent f88eb5b commit 2ca123f
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 6 deletions.
4 changes: 4 additions & 0 deletions MinimumBoundingBox/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,7 @@ pnpm dev
- **Mouse Left (Click on TransformControls Widget):** 拖动物体
- **Shift + Mouse Left:** 选中多个物体
- **Del:** 删除选中物体

#### 触控设备:

- **长按:** 新增物体
24 changes: 18 additions & 6 deletions MinimumBoundingBox/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { ControlsManager } from "./controls";
import { SelectionManager } from "./selection";
import { BoundingBoxManager } from "./boundingBox";
import { computeCentroid } from "./utils";
import { addTouchEventListener } from "./touch";

// 初始化 SceneManager
const sceneManager = new SceneManager();
Expand Down Expand Up @@ -118,14 +119,25 @@ document.addEventListener("keyup", (event) => {
}
});

addTouchEventListener(onAddPoint);

// 点击新增点的逻辑
function onAddPoint(event: MouseEvent) {
const mouse = new THREE.Vector2(
(event.clientX / window.innerWidth) * 2 - 1,
-(event.clientY / window.innerHeight) * 2 + 1
);
function onAddPoint(event: MouseEvent | TouchEvent) {
let coords = new THREE.Vector2();
if (event instanceof MouseEvent) {
coords = new THREE.Vector2(
(event.clientX / window.innerWidth) * 2 - 1,
-(event.clientY / window.innerHeight) * 2 + 1
);
} else if (event instanceof TouchEvent) {
const touch = event.touches[0];
coords = new THREE.Vector2(
(touch.clientX / window.innerWidth) * 2 - 1,
-(touch.clientY / window.innerHeight) * 2 + 1
);
}
const raycaster = new THREE.Raycaster();
raycaster.setFromCamera(mouse, sceneManager.camera);
raycaster.setFromCamera(coords, sceneManager.camera);

// 使用已经存在的 testPlane 进行交叉检测
const intersects = raycaster.intersectObject(sceneManager.testPlane);
Expand Down
72 changes: 72 additions & 0 deletions MinimumBoundingBox/src/touch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// 初始化变量
let touchStartX = 0;
let touchStartY = 0;
let touchStartTime = 0;
let longPressTimer: any = null;
const LONG_PRESS_DURATION = 500; // 长按时间,单位毫秒

export function addTouchEventListener(
longPressCallback: (event: TouchEvent) => void
) {
// 支援触摸事件
document.addEventListener("touchstart", (event) => {
// 如果有多个触摸点,则取消长按检测
if (event.touches.length > 1) {
clearTimeout(longPressTimer);
longPressTimer = null;
return;
}

// 记录触摸的起始位置和时间
const touch = event.touches[0];
touchStartX = touch.clientX;
touchStartY = touch.clientY;
touchStartTime = Date.now();

// 设置一个计时器,检测长按
longPressTimer = setTimeout(() => {
// 在这里可以触发长按的相关逻辑
longPressCallback(event);
}, LONG_PRESS_DURATION);
});

// touchend 事件处理
document.addEventListener("touchend", (event) => {
// 如果触摸点数减少到0或1,可能需要重新判断
if (event.touches.length === 0 || event.touches.length === 1) {
// 触摸结束时清除计时器
clearTimeout(longPressTimer);
longPressTimer = null;
}
});

// touchmove 事件处理
document.addEventListener("touchmove", (event) => {
// 如果有多个触摸点,则取消长按检测
if (event.touches.length > 1) {
clearTimeout(longPressTimer);
longPressTimer = null;
return;
}

// 检查触摸点是否有移动
const touch = event.touches[0];
const moveX = touch.clientX;
const moveY = touch.clientY;

// 如果移动超过一定范围,认为不是长按
if (
Math.abs(moveX - touchStartX) > 10 ||
Math.abs(moveY - touchStartY) > 10
) {
clearTimeout(longPressTimer);
longPressTimer = null;
}
});

document.addEventListener("touchcancel", () => {
// 触摸被中断时,清除计时器
clearTimeout(longPressTimer);
longPressTimer = null;
});
}

0 comments on commit 2ca123f

Please sign in to comment.