mirror of
https://github.com/exogen/t2-mapper.git
synced 2026-04-29 00:05:51 +00:00
add debug labels and some missing shapes
This commit is contained in:
parent
7557d2c48e
commit
878c798bcd
21 changed files with 385 additions and 147 deletions
58
src/components/FloatingLabel.tsx
Normal file
58
src/components/FloatingLabel.tsx
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
import { ReactNode, useEffect, useRef, useState } from "react";
|
||||
import { Object3D } from "three";
|
||||
import { useDistanceFromCamera } from "./useDistanceFromCamera";
|
||||
import { useFrame } from "@react-three/fiber";
|
||||
import { Html } from "@react-three/drei";
|
||||
|
||||
const DEFAULT_POSITION = [0, 0, 0] as [x: number, y: number, z: number];
|
||||
|
||||
export function FloatingLabel({
|
||||
children,
|
||||
color = "white",
|
||||
position = DEFAULT_POSITION,
|
||||
}: {
|
||||
children: ReactNode;
|
||||
color?: string;
|
||||
position?: [x: number, y: number, z: number];
|
||||
}) {
|
||||
const groupRef = useRef<Object3D>(null);
|
||||
const distanceRef = useDistanceFromCamera(groupRef);
|
||||
const [isVisible, setIsVisible] = useState(false);
|
||||
const labelRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
// Initialize opacity when label ref is attached
|
||||
useEffect(() => {
|
||||
if (labelRef.current && distanceRef.current != null) {
|
||||
const opacity = Math.max(0, Math.min(1, 1 - distanceRef.current / 200));
|
||||
labelRef.current.style.opacity = opacity.toString();
|
||||
}
|
||||
}, [isVisible]);
|
||||
|
||||
useFrame(() => {
|
||||
const distance = distanceRef.current;
|
||||
const shouldBeVisible = distance != null && distance < 200;
|
||||
|
||||
// Update visibility state only when crossing threshold
|
||||
if (isVisible !== shouldBeVisible) {
|
||||
setIsVisible(shouldBeVisible);
|
||||
}
|
||||
|
||||
// Update opacity directly on DOM element (no re-render)
|
||||
if (labelRef.current && shouldBeVisible) {
|
||||
const opacity = Math.max(0, Math.min(1, 1 - distance / 200));
|
||||
labelRef.current.style.opacity = opacity.toString();
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<group ref={groupRef}>
|
||||
{isVisible ? (
|
||||
<Html position={position} center>
|
||||
<div ref={labelRef} className="StaticShapeLabel" style={{ color }}>
|
||||
{children}
|
||||
</div>
|
||||
</Html>
|
||||
) : null}
|
||||
</group>
|
||||
);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue