Skip to content

Commit

Permalink
feat: update hoverednode
Browse files Browse the repository at this point in the history
  • Loading branch information
Rassl committed Dec 12, 2024
1 parent 62f5f0d commit 0742b38
Show file tree
Hide file tree
Showing 4 changed files with 199 additions and 179 deletions.
94 changes: 94 additions & 0 deletions src/components/Universe/Graph/Cubes/NodeWrapper/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import { useFrame } from '@react-three/fiber'
import gsap from 'gsap'
import { memo, useRef } from 'react'
import { Mesh, Vector3 } from 'three'
import { useGraphStore } from '~/stores/useGraphStore'
import { NodeExtended } from '~/types'
import { TextNode } from '../Text/index'

type Props = {
node: NodeExtended
color: string
scale: number
index: number
}

const offset = { x: 20, y: 20 }

export const NodeWrapper = memo(
(props: Props) => {
const { node, color, index } = props
const simulation = useGraphStore((s) => s.simulation)

const finishedSimulationCircle = useRef<boolean>(false)

const wrapperRef = useRef<Mesh | null>(null)

useFrame(({ camera, size }) => {
if (wrapperRef.current && simulation) {
const simulationNode = simulation.nodes()[index]

if (!simulationNode) {
return
}

if (!finishedSimulationCircle.current) {
// Define the NDC coordinates for the fixed position
const ndc = new Vector3(
-1 + (offset.x * 2) / size.width, // Adjust for left offset
1 - (offset.y * 2) / size.height, // Adjust for top offset
0, // Near clipping plane
)

// Convert NDC to world space
const worldPosition = ndc.unproject(camera)

// Maintain a fixed distance from the camera
const distanceFromCamera = 5
const direction = worldPosition.sub(camera.position).normalize()
const fixedPosition = camera.position.clone().add(direction.multiplyScalar(distanceFromCamera))

wrapperRef.current.position.copy(fixedPosition)

// Store the largest dimension as the "size" of the mesh

wrapperRef.current.scale.set(0.1, 0.1, 0.1)

wrapperRef.current.visible = false
}

if (simulationNode.fx && !finishedSimulationCircle.current) {
wrapperRef.current.visible = true
finishedSimulationCircle.current = true

gsap.to(wrapperRef.current.position, {
x: simulationNode.fx, // Destination X coordinate
y: simulationNode.fy, // Destination Y coordinate
z: simulationNode.fz, // Destination Z coordinate
duration: 4, // Animation duration in seconds
ease: 'power2.in', // Easing function
})

gsap.to(wrapperRef.current.scale, {
x: 1, // Destination X coordinate
y: 1, // Destination Y coordinate
z: 1, // Destination Z coordinate
duration: 4.5, // Animation duration in seconds
ease: 'power2.in', // Easing function
})
}
}
})

return (
<mesh key={node.ref_id} ref={wrapperRef} name="wr2" scale={node.scale || 1} userData={node}>
<boxGeometry args={[40, 40, 40]} />
<meshStandardMaterial opacity={0} transparent />
<TextNode key={node.ref_id} color={color} ignoreDistance={false} node={node} scale={node.scale || 1} />
</mesh>
)
},
(prevProps, nextProps) => prevProps.node.ref_id === nextProps.node.ref_id,
)

NodeWrapper.displayName = 'NodeWrapper'
12 changes: 2 additions & 10 deletions src/components/Universe/Graph/Cubes/SelectionDataNodes/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,17 +116,9 @@ export const SelectionDataNodes = memo(() => {
return (
<>
<group ref={groupRef} name="simulation-2d-group">
{selectionGraphData?.nodes.map((node, index) => (
{selectionGraphData?.nodes.map((node) => (
<mesh key={node.ref_id}>
<TextNode
key={node.ref_id || node.id}
color="white"
hide
ignoreDistance
index={index}
node={node}
scale={1}
/>
<TextNode key={node.ref_id || node.id} color="white" hide ignoreDistance node={node} scale={1} />
</mesh>
))}
</group>
Expand Down
Loading

0 comments on commit 0742b38

Please sign in to comment.