added mouse click
This commit is contained in:
parent
bd5fa12a1e
commit
0a750606ac
|
|
@ -1,10 +1,9 @@
|
|||
import { useEffect, useRef } from "react";
|
||||
import * as THREE from 'three';
|
||||
import { useInteraction, type InteractionMouseMoveEventArgs } from "../helpers/hooks/useInteration";
|
||||
import { useInteraction, type InteractionMouseEventArgs } from "../helpers/hooks/useInteration";
|
||||
import { db } from "../backend/db";
|
||||
import { HitTestFactory, type HitTest } from "../helpers/hitTest";
|
||||
import { model } from "../model/model";
|
||||
import { Point3dHelper } from "../helpers/point3dHelper";
|
||||
import { SceneHelper } from "../helpers/sceneHelper";
|
||||
|
||||
export type ThreeViewEventArgs = {
|
||||
|
|
@ -17,14 +16,15 @@ export type ThreeViewTickEventArgs = ThreeViewEventArgs & {
|
|||
absoluteTime: number,
|
||||
}
|
||||
|
||||
export type ThreeViewMouseMoveEventArgs = ThreeViewEventArgs & {
|
||||
export type ThreeViewMouseEventArgs = ThreeViewEventArgs & {
|
||||
hitTest: HitTest,
|
||||
}
|
||||
|
||||
export type ThreeViewProps = {
|
||||
sceneHelper: SceneHelper,
|
||||
onTick?: (event: ThreeViewTickEventArgs) => void,
|
||||
onMouseMove?: (event: ThreeViewMouseMoveEventArgs) => void,
|
||||
onClick?: (event: ThreeViewMouseEventArgs) => void,
|
||||
onMouseMove?: (event: ThreeViewMouseEventArgs) => void,
|
||||
onDispose: (event: ThreeViewEventArgs) => void,
|
||||
}
|
||||
|
||||
|
|
@ -67,7 +67,8 @@ export const ThreeView = function (props: ThreeViewProps) {
|
|||
const canvasRef = useRef<HTMLCanvasElement | null>(null);
|
||||
const cameraRef = useRef<THREE.PerspectiveCamera | null>(null);
|
||||
|
||||
let handleHover: (e: InteractionMouseMoveEventArgs) => void;
|
||||
let handleClick: (e: InteractionMouseEventArgs) => void;
|
||||
let handleHover: (e: InteractionMouseEventArgs) => void;
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
|
|
@ -100,7 +101,7 @@ export const ThreeView = function (props: ThreeViewProps) {
|
|||
};
|
||||
window.addEventListener("resize", handleWindowResize);
|
||||
|
||||
handleHover = (e: InteractionMouseMoveEventArgs) => {
|
||||
handleHover = (e: InteractionMouseEventArgs) => {
|
||||
const hitTest = HitTestFactory.hitTest(
|
||||
props.sceneHelper,
|
||||
new THREE.Vector2(e.position.x, e.position.y),
|
||||
|
|
@ -114,6 +115,20 @@ export const ThreeView = function (props: ThreeViewProps) {
|
|||
});
|
||||
};
|
||||
|
||||
handleClick = (e: InteractionMouseEventArgs) => {
|
||||
const hitTest = HitTestFactory.hitTest(
|
||||
props.sceneHelper,
|
||||
new THREE.Vector2(e.position.x, e.position.y),
|
||||
camera,
|
||||
{ tolerancePixels: 3, cameraPixelSize: e.pixelSize }
|
||||
);
|
||||
props.onClick?.({
|
||||
camera,
|
||||
scene,
|
||||
hitTest,
|
||||
})
|
||||
};
|
||||
|
||||
// --- Animation loop ---
|
||||
let lastTime = performance.now();
|
||||
let animId: number;
|
||||
|
|
@ -153,6 +168,7 @@ export const ThreeView = function (props: ThreeViewProps) {
|
|||
|
||||
useInteraction(canvasRef, cameraRef, {
|
||||
onMouseMove: (e) => handleHover?.(e),
|
||||
onMouseClick: (e) => handleClick?.(e),
|
||||
});
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -1,14 +1,12 @@
|
|||
import { useState } from "react";
|
||||
import { useSceneHelper } from "../helpers/hooks/useSceneHelper";
|
||||
import { Point3dHelper } from "../helpers/point3dHelper";
|
||||
import { state } from "../state/root";
|
||||
import { ThreeView, type ThreeViewEventArgs, type ThreeViewMouseMoveEventArgs } from "./ThreeVIew";
|
||||
import { ThreeView, type ThreeViewEventArgs, type ThreeViewMouseEventArgs } from "./ThreeVIew";
|
||||
|
||||
export const Viewport = function () {
|
||||
|
||||
const sceneHelper = useSceneHelper();
|
||||
|
||||
function handleMouseMove(e: ThreeViewMouseMoveEventArgs) {
|
||||
function handleMouseMove(e: ThreeViewMouseEventArgs) {
|
||||
state.setHitTest(e.hitTest);
|
||||
|
||||
sceneHelper.clearPoints();
|
||||
|
|
@ -33,10 +31,15 @@ export const Viewport = function () {
|
|||
// throw new Error("Function not implemented.");
|
||||
}
|
||||
|
||||
function handleClick(e: ThreeViewMouseEventArgs): void {
|
||||
console.log(e);
|
||||
}
|
||||
|
||||
return (<>
|
||||
<ThreeView
|
||||
sceneHelper={sceneHelper}
|
||||
onMouseMove={handleMouseMove}
|
||||
onClick={handleClick}
|
||||
onDispose={handleDispose}
|
||||
/>
|
||||
</>);
|
||||
|
|
|
|||
|
|
@ -1,13 +1,16 @@
|
|||
import { useEffect, type RefObject } from "react";
|
||||
import * as THREE from "three";
|
||||
|
||||
export type InteractionMouseMoveEventArgs = {
|
||||
const CLICK_THRESHOLD = 2; // px
|
||||
|
||||
export type InteractionMouseEventArgs = {
|
||||
position: { x: number, y: number },
|
||||
pixelSize: { x: number, y: number },
|
||||
};
|
||||
|
||||
export type UseInteractionOptions = {
|
||||
onMouseMove?: (e: InteractionMouseMoveEventArgs) => void,
|
||||
onMouseClick?: (e: InteractionMouseEventArgs) => void,
|
||||
onMouseMove?: (e: InteractionMouseEventArgs) => void,
|
||||
}
|
||||
|
||||
export function useInteraction(
|
||||
|
|
@ -29,6 +32,7 @@ export function useInteraction(
|
|||
// --- Orbit Controls (manual implementation, no OrbitControls import needed) ---
|
||||
let isDragging = false;
|
||||
let isRightDrag = false;
|
||||
let startX = 0, startY = 0;
|
||||
let lastX = 0, lastY = 0;
|
||||
let theta = 0.8, phi = 0.9, radius = 8;
|
||||
let targetX = 0, targetY = 0;
|
||||
|
|
@ -44,12 +48,24 @@ export function useInteraction(
|
|||
const onMouseDown = (e: MouseEvent) => {
|
||||
isDragging = true;
|
||||
isRightDrag = e.button === 2;
|
||||
startX = e.clientX;
|
||||
startY = e.clientY;
|
||||
lastX = e.clientX;
|
||||
lastY = e.clientY;
|
||||
e.preventDefault();
|
||||
};
|
||||
|
||||
const onMouseUp = () => { isDragging = false; };
|
||||
const onMouseUp = (e: MouseEvent) => {
|
||||
isDragging = false;
|
||||
if ((e.clientX - startX < CLICK_THRESHOLD) && (e.clientY - startY < CLICK_THRESHOLD)) {
|
||||
const rect = target.getBoundingClientRect();
|
||||
const position = {
|
||||
x: ((e.clientX - rect.left) / rect.width) * 2 - 1,
|
||||
y: -((e.clientY - rect.top) / rect.height) * 2 + 1,
|
||||
};
|
||||
options.onMouseClick?.({ position, pixelSize: { x: 2 / rect.width, y: 2 / rect.height } });
|
||||
}
|
||||
};
|
||||
|
||||
const onMouseMove = (e: MouseEvent) => {
|
||||
if (!isDragging) return;
|
||||
|
|
|
|||
Loading…
Reference in New Issue