Closed dhruvadhia1 closed 3 months ago
i think To achieve the desired touch interaction using react-three-fiber, you need to combine the library with the drei library for orbit controls and handle touch events to distinguish between horizontal and vertical swipes. Below is a detailed guide on how to implement this in a react-three-fiber application. Step 1: Set Up Your Project Ensure you have react-three-fiber and drei installed. If not, you can install them using: Step 2: Create Your React Component App Component:
import React, { useRef, useState } from 'react';
import { Canvas } from '@react-three/fiber';
import { OrbitControls } from '@react-three/drei';
import { Box } from './Box'; // Assume Box is a simple 3D box component
const App = () => {
const controlsRef = useRef();
const [isHorizontalPan, setIsHorizontalPan] = useState(false);
const handleTouchStart = (event) => {
const touch = event.touches[0];
controlsRef.current.startX = touch.clientX;
controlsRef.current.startY = touch.clientY;
controlsRef.current.moved = false;
};
const handleTouchMove = (event) => {
const touch = event.touches[0];
const deltaX = touch.clientX - controlsRef.current.startX;
const deltaY = touch.clientY - controlsRef.current.startY;
if (Math.abs(deltaX) > Math.abs(deltaY)) {
setIsHorizontalPan(true);
controlsRef.current.moved = true;
// Prevent vertical scrolling when interacting with the model
event.preventDefault();
} else if (!controlsRef.current.moved) {
setIsHorizontalPan(false);
}
};
const handleTouchEnd = () => {
controlsRef.current.moved = false;
};
return (
<Canvas
onTouchStart={handleTouchStart}
onTouchMove={handleTouchMove}
onTouchEnd={handleTouchEnd}
>
<ambientLight />
<pointLight position={[10, 10, 10]} />
<Box position={[-1.2, 0, 0]} />
<Box position={[1.2, 0, 0]} />
<OrbitControls ref={controlsRef} enablePan={isHorizontalPan} />
</Canvas>
);
};
export default App;
Box Component:
import React from 'react';
import { useFrame } from '@react-three/fiber';
const Box = (props) => {
const mesh = React.useRef();
useFrame(() => {
mesh.current.rotation.x += 0.01;
mesh.current.rotation.y += 0.01;
});
return (
<mesh {...props} ref={mesh}>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color={'orange'} />
</mesh>
);
};
export { Box };
Hi There,
I am wondering if there is a way to achieve touch-action: pan-y effect for mobile interaction, so if I first drag horizontally then i can interact with 3d model using orbit controls, otherwise i can scroll the page. It feels intuitive and can allow for both.
the examples on model viewer site on mobile works perfect.
https://modelviewer.dev/
i also tried applying the same css property on canvas, but no luck so far