"use client"; import { useEffect, useRef, useState } from "react"; import { COLORS, VizFrame } from "./common"; export function IoUDemo({ width = 720, height = 460, }: { width?: number; height?: number; }) { const W = width; const H = height; const [a, setA] = useState({ x: 120, y: 130, w: 240, h: 200 }); const [b, setB] = useState({ x: 280, y: 200, w: 240, h: 200 }); const [drag, setDrag] = useState<"a" | "b" | null>(null); const offset = useRef({ x: 0, y: 0 }); const inter = { x1: Math.max(a.x, b.x), y1: Math.max(a.y, b.y), x2: Math.min(a.x + a.w, b.x + b.w), y2: Math.min(a.y + a.h, b.y + b.h), }; const interW = Math.max(0, inter.x2 - inter.x1); const interH = Math.max(0, inter.y2 - inter.y1); const interA = interW * interH; const unionA = a.w * a.h + b.w * b.h - interA; const iou = unionA > 0 ? interA / unionA : 0; useEffect(() => { function onMove(e: PointerEvent) { if (!drag) return; const dx = e.movementX; const dy = e.movementY; const set = drag === "a" ? setA : setB; set((box) => ({ ...box, x: Math.max(0, Math.min(W - box.w, box.x + dx)), y: Math.max(0, Math.min(H - box.h, box.y + dy)), })); } function onUp() { setDrag(null); } window.addEventListener("pointermove", onMove); window.addEventListener("pointerup", onUp); return () => { window.removeEventListener("pointermove", onMove); window.removeEventListener("pointerup", onUp); }; }, [drag, W, H]); return (