Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

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

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

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

@pmndrs pmndrs locked and limited conversation to collaborators Aug 10, 2024
@CodyJasonBennett CodyJasonBennett converted this issue into discussion #3330 Aug 10, 2024

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants