From 5a0ede370e4b9a218a4c89f83fdfb3de51d42a56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A0=D0=B0=D1=81=D1=83=D0=BB?= Date: Tue, 5 Nov 2024 17:37:28 +0300 Subject: [PATCH] feat: fixed links, improved behaviour on hover/select --- .../Graph/Connections/LineComponent.tsx | 39 ++++++----- .../Universe/Graph/Connections/index.tsx | 64 ++++++++++++++++--- src/components/Universe/Graph/index.tsx | 6 +- src/components/Universe/constants.ts | 4 +- 4 files changed, 86 insertions(+), 27 deletions(-) diff --git a/src/components/Universe/Graph/Connections/LineComponent.tsx b/src/components/Universe/Graph/Connections/LineComponent.tsx index 42d778bc3..e563f6524 100644 --- a/src/components/Universe/Graph/Connections/LineComponent.tsx +++ b/src/components/Universe/Graph/Connections/LineComponent.tsx @@ -1,43 +1,48 @@ import { Line } from '@react-three/drei' import gsap from 'gsap' -import { memo, useEffect, useRef } from 'react' -import { Color, Vector3 } from 'three' +import { forwardRef, memo, useEffect } from 'react' +import { Vector3 } from 'three' import { Line2 } from 'three-stdlib' +import { LinkPosition } from '..' +import { LINE_WIDTH } from '../../constants' type LineComponentProps = { isSelected: boolean - lineWidth: number - visible: boolean + position: LinkPosition } const VECTOR = new Vector3(0, 0, 0) // eslint-disable-next-line no-underscore-dangle -export const _LineComponent = (props: LineComponentProps) => { - const { isSelected, lineWidth, visible } = props - const ref = useRef(null) - +const _LineComponent = forwardRef(({ isSelected, position }, ref) => { useEffect(() => { - const line = (ref as React.MutableRefObject).current + if (ref && (ref as React.MutableRefObject).current) { + const line = (ref as React.MutableRefObject).current - if (line) { gsap.fromTo( line.material, - { linewidth: 5 }, + { linewidth: LINE_WIDTH * 5 }, { - linewidth: isSelected ? 2 : lineWidth, + linewidth: LINE_WIDTH, duration: 1, }, ) } - }, [isSelected, lineWidth, ref]) - - const color = new Color(0xff0000) + }, [isSelected, ref]) return ( - + ) -} +}) _LineComponent.displayName = 'LineComponent' diff --git a/src/components/Universe/Graph/Connections/index.tsx b/src/components/Universe/Graph/Connections/index.tsx index 626308e72..277552f21 100644 --- a/src/components/Universe/Graph/Connections/index.tsx +++ b/src/components/Universe/Graph/Connections/index.tsx @@ -1,25 +1,73 @@ -import { memo } from 'react' +import gsap from 'gsap' +import { memo, useEffect, useRef } from 'react' +import { Line2 } from 'three-stdlib' import { useDataStore } from '~/stores/useDataStore' -import { useGraphStore, useSelectedNode } from '~/stores/useGraphStore' +import { useGraphStore, useHoveredNode, useSelectedNode } from '~/stores/useGraphStore' import { Link } from '~/types' +import { LinkPosition } from '..' +import { LINE_WIDTH } from '../../constants' import { LineComponent } from './LineComponent' -export const Connections = memo(() => { +type Props = { + linksPosition: LinkPosition[] +} + +const LINE_TRANSFORM_DURATION = 0.5 + +export const Connections = memo(({ linksPosition }: Props) => { const data = useDataStore((s) => s.dataInitial) const { showSelectionGraph } = useGraphStore((s) => s) const selectedNode = useSelectedNode() + const hoveredNode = useHoveredNode() + const lineRefs = useRef([]) + + useEffect(() => { + const activeNode = hoveredNode || selectedNode + + if (!activeNode) { + lineRefs.current.forEach((line) => { + if (line) { + gsap.to(line.material, { + linewidth: LINE_WIDTH, + duration: LINE_TRANSFORM_DURATION, + }) + } + }) + + return + } - console.log('connection') + lineRefs.current.forEach((line, index) => { + if (data?.links[index].source === activeNode?.ref_id || data?.links[index].target === activeNode?.ref_id) { + gsap.to(line.material, { + linewidth: LINE_WIDTH * 2, + duration: LINE_TRANSFORM_DURATION, + }) + } else { + gsap.to(line.material, { + linewidth: 0, + duration: LINE_TRANSFORM_DURATION, + }) + } + }) + }, [data?.links, hoveredNode, selectedNode]) return ( - - {data?.links.map((l: Link) => { + + {data?.links.map((l: Link, index: number) => { const isSelected = selectedNode?.ref_id === l.source || selectedNode?.ref_id === l.target - const lineWidth = selectedNode ? 0 : 1 + // eslint-disable-next-line no-nested-ternary return ( - + { + lineRefs.current[index] = el as Line2 + }} + isSelected={isSelected} + position={linksPosition[index]} + /> ) })} diff --git a/src/components/Universe/Graph/index.tsx b/src/components/Universe/Graph/index.tsx index 55e057f36..7a9776abe 100644 --- a/src/components/Universe/Graph/index.tsx +++ b/src/components/Universe/Graph/index.tsx @@ -110,6 +110,10 @@ export const Graph = () => { }) } + if (simulation.alpha() > 1) { + return + } + if (grConnections) { grConnections.children.forEach((r, i) => { const link = dataInitial?.links[i] @@ -174,7 +178,7 @@ export const Graph = () => { {(isLoadingNew || isFetching) && } - {graphStyle !== 'earth' && } + {graphStyle !== 'earth' && } ) diff --git a/src/components/Universe/constants.ts b/src/components/Universe/constants.ts index 2d5bf69ec..9ead991d8 100644 --- a/src/components/Universe/constants.ts +++ b/src/components/Universe/constants.ts @@ -3,9 +3,11 @@ import { Guests, NodeExtended } from '~/types' export const variableVector3 = new Vector3(0, 0, 0) +export const LINE_WIDTH = 0.5 + export const outlineEffectColor = 0xffffff -export const maxChildrenDisplayed = 20 +export const maxChildrenDisplayed = 50 export const nodesAreRelatives = (a: NodeExtended | null, b: NodeExtended | null) => { if (!a?.ref_id || !b?.ref_id) {