Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

touch action similar to model viewer #3263

Open
dhruvadhia1 opened this issue May 11, 2024 · 1 comment
Open

touch action similar to model viewer #3263

dhruvadhia1 opened this issue May 11, 2024 · 1 comment

Comments

@dhruvadhia1
Copy link

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

@HoseinKhanBeigi
Copy link

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 };

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants