diff --git a/src/components/ThreeScene.tsx b/src/components/ThreeScene.tsx index cf53102..9adef07 100644 --- a/src/components/ThreeScene.tsx +++ b/src/components/ThreeScene.tsx @@ -51,6 +51,7 @@ const [labelPositions, setLabelPositions] = useState< const defaultLineOpacity = 0.1; let outlineMesh: THREE.Mesh | null = null; let previouslyHoveredSphere: THREE.Mesh | null = null; + let highlightedLines: THREE.Line[] = []; type OverlayInfo = { overlay: HTMLDivElement, node: THREE.Object3D }; let neighborOverlays: OverlayInfo[] = []; @@ -166,6 +167,7 @@ const [labelPositions, setLabelPositions] = useState< const sphereGroup = new THREE.Group(); const lineGroup = new THREE.Group(); const nodeMap: { [key: string]: THREE.Vector3 } = {}; + const sphereByLabel = new Map(); data.nodes.forEach((node) => { //const material = new THREE.MeshNormalMaterial(); @@ -192,6 +194,7 @@ const [labelPositions, setLabelPositions] = useState< sphere.userData.displayUrl = `https://scrapbox.io/${projectName}/${node.text}`; sphere.userData.label = node.text; sphereGroup.add(sphere); + sphereByLabel.set(node.text, sphere); /* sphereGroup.add(sphere); @@ -218,10 +221,10 @@ const [labelPositions, setLabelPositions] = useState< opacity: defaultLineOpacity }); const line = new THREE.Line(lineGeometry, lineMaterial); - lineGroup.add(line) + lineGroup.add(line); - const sourceSphere = sphereGroup.children.find(o => o.userData.displayUrl?.endsWith(link.source)); - const targetSphere = sphereGroup.children.find(o => o.userData.displayUrl?.endsWith(link.target)); + const sourceSphere = sphereByLabel.get(link.source); + const targetSphere = sphereByLabel.get(link.target); if (sourceSphere && targetSphere) { const sourceWorldPos = new THREE.Vector3(); sourceSphere.getWorldPosition(sourceWorldPos); @@ -331,11 +334,13 @@ const [labelPositions, setLabelPositions] = useState< ); const urlDisplay = urlDisplayRef.current; - lineGroup.children.forEach(line => { - if ((line as THREE.Line).material instanceof THREE.LineBasicMaterial) { - ((line as THREE.Line).material as THREE.LineBasicMaterial).opacity = defaultLineOpacity; + // Reset only previously highlighted lines instead of all lines + highlightedLines.forEach(line => { + if (line.material instanceof THREE.LineBasicMaterial) { + (line.material as THREE.LineBasicMaterial).opacity = defaultLineOpacity; } }); + highlightedLines = []; if (outlineMesh) { scene.remove(outlineMesh); @@ -426,6 +431,7 @@ const [labelPositions, setLabelPositions] = useState< lines.forEach((line) => { const mat = line.material as THREE.LineBasicMaterial; mat.opacity = 1.0; + highlightedLines.push(line); }); } }