Something went wrong. Try again.
Starship Simulator Controls thoriumsim.com
Something went wrong. Try again.
2.3 kB · 86 lines
TSX
at develop
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687import { Line, Text } from "@react-three/drei";import { type ThreeElements, useFrame } from "@react-three/fiber";import { type FC, useMemo, useRef } from "react";import { EllipseCurve, type Group, type Mesh, type OrthographicCamera } from "three";import type { Line2 } from "three-stdlib";
import FONT_URL from "./Teko-Light.ttf";
export const DistanceCircle: FC< { radius?: number; color?: string | number; label?: string; } & ThreeElements["object3D"]> = ({ radius = 1, color = 0x6666666, label }) => { const points = useMemo(() => { const curve = new EllipseCurve( 0, 0, // ax, aY radius, radius, 0, Math.PI * 2, false, 0, );
const points = curve.getPoints(100); return points.map(({ x, y }) => [x, y, 0] as [number, number, number]); }, [radius]);
const groupRef = useRef<Group>(null); const lineRef = useRef<Line2>(null); const textRef = useRef<Mesh>(null);
useFrame((props) => { const camera = props.camera as OrthographicCamera; const dx = (camera.right - camera.left) / (2 * camera.zoom); if (textRef.current) { if (groupRef.current) { if (dx > radius * 4) { groupRef.current.visible = false; } else if (dx < radius) { groupRef.current.visible = false; } else { const opacity = Math.max(0, Math.min(1, Math.abs(1 - (dx - radius * 3) / radius))); if (!Array.isArray(textRef.current.material)) { textRef.current.material.transparent = true; textRef.current.material.opacity = opacity; } if (lineRef.current) { lineRef.current.material.transparent = true; lineRef.current.material.opacity = opacity; } groupRef.current.visible = true; } } textRef.current.scale.setScalar(dx); } }); return ( <group ref={groupRef} rotation={[-Math.PI / 2, 0, 0]}> <Text color={color} // default anchorX="center" // default anchorY="bottom-baseline" // default fontSize={0.075} font={FONT_URL} position={[0, radius * 1.03, 0]} ref={textRef} > {label ? label : radius < 1 ? `${(radius * 1000).toLocaleString()}m` : `${radius.toLocaleString()}km`} </Text> <Line ref={lineRef} points={points} // Array of points color={color} // Default lineWidth={1} // In pixels (default) /> </group> );};