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