Thanks,
I have a question before I continue. I created a Canvas:
<Canvas orthographic>
<ZoomController zoom={50} />
<ambientLight intensity={0.5} />
{/* Zoom Layer */}
<OrbitControls enableZoom={true} zoomSpeed={2} enableRotate={false} />
{/* Moving Layer */}
<MovingImage geometry={geometry} texture={texture} isDraggable={isDraggable} setPosition={setOffset} />
{/* Drawing Layer */}
{!isDraggable && <DrawingLayer setLines={setLines} lines={lines} offset={offset} />}
{/* Lines Layer (Group all lines together) */}
<Lines lines={lines} position={offset} />
</Canvas>
I am loading an image and putting it in a and added logic in order to move it using the mouse:
const MovingImage: React.FC<{
geometry: number;
texture: THREE.Texture;
isDraggable: boolean;
setPosition: (position: THREE.Vector3) => void;
}> = ({ geometry, texture, isDraggable, setPosition }) => {
const { raycaster, camera, gl } = useThree();
const [dragging, setDragging] = useState(false);
const meshRef = useRef<THREE.Mesh>(null);
const [offset, setOffset] = useState(new THREE.Vector3());
const onPointerDown = (event: PointerEvent) => {
if (!meshRef.current || !isDraggable) return;
const rect = gl.domElement.getBoundingClientRect();
const mouseX = ((event.clientX - rect.left) / rect.width) * 2 - 1;
const mouseY = -((event.clientY - rect.top) / rect.height) * 2 + 1;
raycaster.setFromCamera(new THREE.Vector2(mouseX, mouseY), camera);
const planeIntersectPoint = new THREE.Vector3();
if (raycaster.ray.intersectPlane(new THREE.Plane(new THREE.Vector3(0, 0, 1), -0), planeIntersectPoint)) {
setDragging(true);
setOffset(meshRef.current.position.clone().sub(planeIntersectPoint));
}
};
const onPointerMove = (event: PointerEvent) => {
if (!dragging || !meshRef.current) return;
const rect = gl.domElement.getBoundingClientRect();
const mouseX = ((event.clientX - rect.left) / rect.width) * 2 - 1;
const mouseY = -((event.clientY - rect.top) / rect.height) * 2 + 1;
raycaster.setFromCamera(new THREE.Vector2(mouseX, mouseY), camera);
const planeIntersectPoint = new THREE.Vector3();
if (raycaster.ray.intersectPlane(new THREE.Plane(new THREE.Vector3(0, 0, 1), -0), planeIntersectPoint)) {
const position = planeIntersectPoint.add(offset);
meshRef.current.position.copy(position);
setPosition(position);
}
};
const onPointerUp = () => setDragging(false);
useEffect(() => {
gl.domElement.addEventListener("pointerdown", onPointerDown);
gl.domElement.addEventListener("pointermove", onPointerMove);
gl.domElement.addEventListener("pointerup", onPointerUp);
return () => {
gl.domElement.removeEventListener("pointerdown", onPointerDown);
gl.domElement.removeEventListener("pointermove", onPointerMove);
gl.domElement.removeEventListener("pointerup", onPointerUp);
};
}, [dragging, isDraggable]);
return (
<mesh ref={meshRef}>
<planeGeometry args={[geometry, geometry]} />
<meshBasicMaterial map={texture} />
</mesh>
);
};
Currently it works, but as you can see in the MovingImage I have to call back the offset, which I need to pass to the lines in order that the lines move along the image. Here the difference:
vs
I was wondering if I need to implement the movement by myself or if there is something built in (did not find it). Furhtermore, if there is a better way to move the lines layer along the background image.