"use client" import { Canvas } from '@react-three/fiber' import { OrbitControls, Sphere } from '@react-three/drei' import { button, Leva, useControls } from 'leva' import { StrictMode, useRef, useState } from 'react' import * as THREE from 'three' export default function App() { return ( <StrictMode> <Leva flat /> <Experience /> </StrictMode> ) } export function Experience() { const [points, setPoints] = useState([]) const { showPoints } = useControls('Shape', { reset: button(() => setPoints([])), showPoints: true }) const shape = new THREE.Shape(); if (points.length > 0) { shape.moveTo(points[0].x, points[0].y) points.forEach(p => shape.lineTo(p.x, p.y)) shape.lineTo(points[0].x, points[0].y) } return <Canvas> <OrbitControls makeDefault /> <directionalLight position={[1, 2, 3]} intensity={1.5} /> <ambientLight intensity={0.5} /> <Pointer setPoints={setPoints} /> {showPoints && points.map((p, i) => <Point key={i} position={[...p, 0]} />)} <mesh> <shapeGeometry args={[shape]} /> <meshBasicMaterial color={'crimson'} transparent={false} opacity={1} depthTest={false} side={THREE.DoubleSide} /> </mesh> </Canvas> } //draw a plane and track the pointer position on it. export function Pointer({ setPoints }) { const pointerRef = useRef(); const planeRef = useRef(); return ( <mesh ref={planeRef} onPointerOver={() => pointerRef.current.visible = true} onPointerOut={() => pointerRef.current.visible = false} onPointerMove={(e) => pointerRef.current.position.copy(planeRef.current.worldToLocal(e.point))} onClick={(e) => setPoints((state) => [...state, planeRef.current.worldToLocal(e.point)])}> <planeGeometry args={[10, 10]} /> <meshBasicMaterial transparent={true} opacity={0.25} /> <Sphere args={[0.1]} ref={pointerRef} raycast={() => null} visible={false} material-color="orange" /> </mesh> ) } export function Point({ position, color = "black", args = [0.1], ...props }) { return ( <mesh position={position} {...props}> <sphereGeometry args={args} /> <meshBasicMaterial color={color} /> </mesh> ) }
Comments (0)
Loading comments...