| 386 | } |
| 387 | |
| 388 | const handleMouseMove = (e: React.MouseEvent<HTMLCanvasElement>) => { |
| 389 | if (!isDrawing || drawMode === 'none' || isPanning) return |
| 390 | |
| 391 | const canvas = canvasRef.current |
| 392 | if (!canvas) return |
| 393 | |
| 394 | const rect = canvas.getBoundingClientRect() |
| 395 | const x = (e.clientX - rect.left) / scale |
| 396 | const y = (e.clientY - rect.top) / scale |
| 397 | |
| 398 | if ((drawMode === 'rect' || drawMode === 'arrow') && startPoint) { |
| 399 | // 矩形和箭头模式:实时预览 |
| 400 | const ctx = canvas.getContext('2d') |
| 401 | if (!ctx) return |
| 402 | |
| 403 | // 恢复历史状态 |
| 404 | if (currentHistoryIndex >= 0) { |
| 405 | ctx.putImageData(history[currentHistoryIndex].imageData, 0, 0) |
| 406 | } |
| 407 | |
| 408 | if (drawMode === 'rect') { |
| 409 | // 绘制预览矩形 |
| 410 | ctx.strokeStyle = drawColor |
| 411 | ctx.lineWidth = 3 |
| 412 | const width = x - startPoint.x |
| 413 | const height = y - startPoint.y |
| 414 | ctx.strokeRect(startPoint.x, startPoint.y, width, height) |
| 415 | } else if (drawMode === 'arrow') { |
| 416 | // 绘制预览箭头 |
| 417 | drawArrow(ctx, startPoint.x, startPoint.y, x, y, drawColor, 3) |
| 418 | } |
| 419 | return |
| 420 | } |
| 421 | |
| 422 | draw(x, y, false) |
| 423 | } |
| 424 | |
| 425 | const handleMouseUp = (e: React.MouseEvent<HTMLCanvasElement>) => { |
| 426 | if (!isDrawing) return |