diff --git a/src/components/App/SideBar/Relevance/Episode/index.tsx b/src/components/App/SideBar/Relevance/Episode/index.tsx index e11201624..7fd2635ef 100644 --- a/src/components/App/SideBar/Relevance/Episode/index.tsx +++ b/src/components/App/SideBar/Relevance/Episode/index.tsx @@ -71,7 +71,7 @@ export const Episode = ({ node, }: Props) => { const searchTerm = useAppStore((s) => s.currentSearch) - const { setHoveredNode } = useGraphStore((s) => s) + const setHoveredNode = useGraphStore((s) => s.setHoveredNode) const text = highlightSearchTerm(String(newText), searchTerm) as string const name = highlightSearchTerm(String(newName), searchTerm) as string const subtitleSource = type === 'show' ? '' : showTitle diff --git a/src/components/Universe/CursorTooltip/index.tsx b/src/components/Universe/CursorTooltip/index.tsx index 787408ee0..41b2a591f 100644 --- a/src/components/Universe/CursorTooltip/index.tsx +++ b/src/components/Universe/CursorTooltip/index.tsx @@ -13,9 +13,11 @@ export const CursorTooltip = () => { if (tooltipRef.current) { tooltipRef.current.style.display = node ? 'block' : 'none' } - }, [node, tooltipRef]) + }, [node]) useEffect(() => { + let animationFrameId: number + const handleMouseMove = (e: MouseEvent) => { const tooltip = tooltipRef.current @@ -23,36 +25,47 @@ export const CursorTooltip = () => { return } - tooltip.style.top = `${e.clientY + 10}px` - tooltip.style.left = `${e.clientX + 10}px` + // Hide tooltip if not hovering over canvas + const target = e.target as Element + + if (target.tagName !== 'CANVAS') { + tooltip.style.display = 'none' + + return + } + + tooltip.style.display = 'block' // Ensure tooltip is visible if hovering canvas - // Prevent clipping at screen edges const tooltipWidth = tooltip.offsetWidth const tooltipHeight = tooltip.offsetHeight const maxX = window.innerWidth - tooltipWidth - 10 const maxY = window.innerHeight - tooltipHeight - 10 - if (e.clientX + 10 + tooltipWidth > window.innerWidth) { - tooltip.style.left = `${maxX}px` - } + const x = Math.min(e.clientX + 10, maxX) + const y = Math.min(e.clientY + 10, maxY) - if (e.clientY + 10 + tooltipHeight > window.innerHeight) { - tooltip.style.top = `${maxY}px` - } + animationFrameId = requestAnimationFrame(() => { + tooltip.style.transform = `translate(${x}px, ${y}px)` + }) } window.addEventListener('mousemove', handleMouseMove) return () => { window.removeEventListener('mousemove', handleMouseMove) + cancelAnimationFrame(animationFrameId) } - }, []) // Empty array ensures the listener is added only once + }, []) return {node && } } const TooltipContainer = styled(Flex)` - position: fixed; + position: fixed; /* Fixed position for the tooltip */ + left: 0; + top: 0; + transform: translate(0, 0); /* Initial transform */ + will-change: transform; /* Optimize for transform changes */ background: ${colors.BG1}; color: white; padding: 5px; @@ -62,5 +75,6 @@ const TooltipContainer = styled(Flex)` white-space: nowrap; overflow: hidden; text-overflow: ellipsis; - display: none; /* Start hidden */ + display: none; /* Initially hidden */ + box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.2); /* Optional shadow for better visibility */ ` diff --git a/src/components/Universe/index.tsx b/src/components/Universe/index.tsx index 2ee57bdb2..efd0b8043 100644 --- a/src/components/Universe/index.tsx +++ b/src/components/Universe/index.tsx @@ -21,6 +21,7 @@ import { Flex } from '../common/Flex' import { outlineEffectColor } from './constants' import { Controls } from './Controls' import { initialCameraPosition, selectionGraphCameraPosition } from './Controls/CameraAnimations/constants' +import { CursorTooltip } from './CursorTooltip/index' import { Graph } from './Graph' import { Lights } from './Lights' import { Overlay } from './Overlay' @@ -135,26 +136,26 @@ const _Universe = () => {