import React, { useEffect, useRef, useState } from 'react'; import { Stage, Layer, Image as KonvaImage, Circle, Rect, Path, Group } from 'react-konva'; import useImage from 'use-image'; interface CanvasAreaProps { activeTool: string; } export function CanvasArea({ activeTool }: CanvasAreaProps) { const containerRef = useRef(null); const [stageSize, setStageSize] = useState({ width: 800, height: 600 }); const [scale, setScale] = useState(1); const [position, setPosition] = useState({ x: 0, y: 0 }); const [points, setPoints] = useState<{ x: number, y: number, type: 'pos'|'neg' }[]>([]); const [cursorPos, setCursorPos] = useState({ x: 0, y: 0 }); // We load a mock image representing a frame const [image] = useImage('https://images.unsplash.com/photo-1549317661-bd32c8ce0be2?q=80&w=2070&auto=format&fit=crop'); useEffect(() => { const handleResize = () => { if (containerRef.current) { setStageSize({ width: containerRef.current.clientWidth, height: containerRef.current.clientHeight, }); } }; handleResize(); window.addEventListener('resize', handleResize); return () => window.removeEventListener('resize', handleResize); }, []); const handleWheel = (e: any) => { e.evt.preventDefault(); const scaleBy = 1.1; const stage = e.target.getStage(); const oldScale = stage.scaleX(); const mousePointTo = { x: stage.getPointerPosition().x / oldScale - stage.x() / oldScale, y: stage.getPointerPosition().y / oldScale - stage.y() / oldScale, }; const newScale = e.evt.deltaY < 0 ? oldScale * scaleBy : oldScale / scaleBy; setScale(newScale); setPosition({ x: -(mousePointTo.x - stage.getPointerPosition().x / newScale) * newScale, y: -(mousePointTo.y - stage.getPointerPosition().y / newScale) * newScale, }); }; const handleMouseMove = (e: any) => { const stage = e.target.getStage(); if (!stage) return; const pos = stage.getPointerPosition(); if (pos) { // Convert to image coordinates const imageX = (pos.x - position.x) / scale; const imageY = (pos.y - position.y) / scale; setCursorPos({ x: imageX, y: imageY }); } }; const handleStageClick = (e: any) => { if (activeTool === 'move') return; if (activeTool === 'point_pos' || activeTool === 'point_neg') { const stage = e.target.getStage(); const pos = stage.getRelativePointerPosition(); setPoints([...points, { x: pos.x, y: pos.y, type: activeTool === 'point_pos' ? 'pos' : 'neg' }]); } }; return (
{/* Background Image Layer */} {image && ( )} {/* Mock Instance Mask overlapping */} {/* AI Prompts Point Regions */} {points.map((p, i) => ( ))}
光标: {cursorPos.x.toFixed(2)}, {cursorPos.y.toFixed(2)} 当前图层树: OBJECT_VEHICLE_01 缩放比: {(scale * 100).toFixed(0)}%
); }