threejs react low poly 3d disco ball that is dragable in typescript

To create a low-poly 3D disco ball in React using Three.js and TypeScript, you can follow these steps:

  1. Install necessary packages:
index.ts
npm install three react-three-fiber @types/three @types/react-three-fiber
74 chars
2 lines
  1. Create a new React functional component called DiscoBall.
import * as React from 'react';
import { useRef } from 'react';
import { Canvas, useFrame } from 'react-three-fiber';
import { BoxBufferGeometry, DoubleSide, Mesh, MeshPhysicalMaterial, PerspectiveCamera, RepeatWrapping, TextureLoader } from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';

const DiscoBall: React.FC = () => {
  const discoBallRef = useRef<Mesh<BoxBufferGeometry, MeshPhysicalMaterial>>();
  const textureLoader = new TextureLoader();

  const onFrame = () => {
    if (discoBallRef.current) {
      discoBallRef.current.rotation.y += 0.003;
    }
  };

  useFrame(onFrame);

  const handleMouseDown = () => {
    document.body.style.cursor = 'grabbing';
  };

  const handleMouseUp = () => {
    document.body.style.cursor = 'default';
  };

  return (
    <mesh ref={discoBallRef} onClick={handleMouseDown} onDoubleClick={handleMouseUp}>
      <boxBufferGeometry args={[1.5, 1.5, 1.5]} />
      <meshPhysicalMaterial
        color="white"
        side={DoubleSide}
        clearcoat={1}
        clearcoatRoughness={0}
        metalness={1}
        roughness={0}
        envMap={textureLoader.load('/env_map.png')}
        map={textureLoader.load('/disco_ball_texture.png')}
        normalMap={textureLoader.load('/disco_ball_normal_map.png')}
        normalScale={[0.5, 0.5]}
        needsUpdate={true}
      />
    </mesh>
  );
};

1388 chars
47 lines

Note: Replace "/env_map.png", "disco_ball_texture.png", and "disco_ball_normal_map.png" with your own image files.

  1. Create a new React component called DiscoBallScene that renders the DiscoBall component.
import * as React from 'react';
import { Canvas } from 'react-three-fiber';
import { PerspectiveCamera } from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import DiscoBall from './DiscoBall';

const DiscoBallScene: React.FC = () => {
  return (
    <Canvas camera={{ position: [0, 0, 5], fov: 45 }}>
      <ambientLight intensity={0.3} />
      <pointLight position={[10, 10, 10]} />
      <DiscoBall />
      <OrbitControls />
    </Canvas>
  );
};

export default DiscoBallScene;

522 chars
20 lines
  1. Create a new React component called App that renders the DiscoBallScene component.
import * as React from 'react';
import DiscoBallScene from './DiscoBallScene';

const App: React.FC = () => {
  return (
    <div style={{ width: '100%', height: '100%', overflow: 'hidden' }}>
      <DiscoBallScene />
    </div>
  );
};

export default App;

259 chars
14 lines
  1. Create index.tsx that renders the App component.
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(<App />, document.getElementById('root'));

157 chars
7 lines

Now you can drag the disco ball using the mouse.

gistlibby LogSnag