import {useRef, useEffect} from 'react'; import * as THREE from 'three'; import {extend} from '@react-three/fiber'; import ThreeMeshUI from 'three-mesh-ui'; import ThreeMeshUIText, {ThreeMeshUITextType} from './ThreeMeshUIText'; import {Interactive} from '@react-three/xr'; /** * Using `?url` at the end of this import tells vite this is a static asset, and * provides us a URL to the hashed version of the file when the project is built. * See: https://vitejs.dev/guide/assets.html#explicit-url-imports */ import robotoFontFamilyJson from '../assets/RobotoMono-Regular-msdf.json?url'; import robotoFontTexture from '../assets/RobotoMono-Regular.png'; extend(ThreeMeshUI); /** * Button component that renders as a three-mesh-ui block */ export default function Button({ onClick, content, width, height, fontSize, borderRadius, padding, }) { const button = useRef(); const textRef = useRef(); useEffect(() => { if (textRef.current != null) { textRef.current.set({content}); } }, [textRef, content]); useEffect(() => { if (!button.current) { return; } button.current.setupState({ state: 'hovered', attributes: { offset: 0.002, backgroundColor: new THREE.Color(0x607b8f), fontColor: new THREE.Color(0xffffff), }, }); button.current.setupState({ state: 'idle', attributes: { offset: 0.001, backgroundColor: new THREE.Color(0x465a69), fontColor: new THREE.Color(0xffffff), }, }); button.current.setupState({ state: 'selected', attributes: { offset: 0.005, backgroundColor: new THREE.Color(0x000000), fontColor: new THREE.Color(0xffffff), }, }); button.current.setState('idle'); }, []); const args = [ { width, height, fontSize, padding, justifyContent: 'end', textAlign: 'center', alignItems: 'center', borderRadius, fontFamily: robotoFontFamilyJson, fontTexture: robotoFontTexture, backgroundOpacity: 1, backgroundColor: new THREE.Color(0x779092), fontColor: new THREE.Color(0x000000), }, ]; return ( { onClick(); }} onHover={() => button.current.setState('hovered')} onBlur={() => button.current.setState('idle')} onSelectStart={() => button.current.setState('selected')} onSelectEnd={() => button.current.setState('idle')}> button.current.setState('hovered')} onPointerLeave={() => button.current.setState('idle')} onPointerDown={() => button.current.setState('selected')} onPointerUp={() => { button.current.setState('hovered'); onClick(); }}> ); }