Use Cases
import React, { useRef, useEffect, useCallback } from 'react' // Simple point interface interface Point { x: number y: number } export default function PointCloudComponent(props) { // Get props with defaults const width = props.width || 800 const height = props.height || 600 const pointCount = props.pointCount || 100 const clusterRadius = props.clusterRadius || 60 const pointSize = props.pointSize || 2 const canvasRef = useRef(null) const pointsRef = useRef([]) const mouseRef = useRef({ x: -999, y: -999 }) // Generate points const generatePoints = useCallback(() => { const points = [] for (let i = 0; i < pointCount; i++) { points.push({ x: Math.random() * (width - 40) + 20, y: Math.random() * (height - 40) + 20 }) } pointsRef.current = points }, [width, height, pointCount]) // Draw function const draw = useCallback(() => { const canvas = canvasRef.current if (!canvas) return const ctx = canvas.getContext('2d') if (!ctx) return // Clear canvas ctx.fillStyle = '#000011' ctx.fillRect(0, 0, width, height) // Find nearby points const nearbyPoints = pointsRef.current.filter(point => { const dx = point.x - mouseRef.current.x const dy = point.y - mouseRef.current.y return Math.sqrt(dx * dx + dy * dy) <= clusterRadius }) // Draw connections ctx.strokeStyle = '#00ff88' ctx.lineWidth = 1 ctx.globalAlpha = 0.5 for (let i = 0; i < nearbyPoints.length; i++) { for (let j = i + 1; j < nearbyPoints.length; j++) { ctx.beginPath() ctx.moveTo(nearbyPoints[i].x, nearbyPoints[i].y) ctx.lineTo(nearbyPoints[j].x, nearbyPoints[j].y) ctx.stroke() } } // Draw points ctx.globalAlpha = 1 pointsRef.current.forEach(point => { const isNear = nearbyPoints.includes(point) ctx.fillStyle = isNear ? '#00ff88' : '#ffffff' ctx.beginPath() ctx.arc(point.x, point.y, pointSize, 0, Math.PI * 2) ctx.fill() }) }, [width, height, clusterRadius, pointSize]) // Mouse move handler const handleMouseMove = useCallback((e) => { const canvas = canvasRef.current if (!canvas) return const rect = canvas.getBoundingClientRect() mouseRef.current.x = e.clientX - rect.left mouseRef.current.y = e.clientY - rect.top draw() }, [draw]) // Initialize and setup useEffect(() => { generatePoints() draw() }, [generatePoints, draw]) return ( <canvas ref={canvasRef} width={width} height={height} style={{ cursor: 'crosshair' }} onMouseMove={handleMouseMove} /> ) }
FileMap
Collaborative File Manager