Merge pull request #21 from outis1one/claude/automate-sam-download-mzpRs

Claude/automate sam download mzp rs
This commit is contained in:
outis1one
2026-01-26 11:44:35 -05:00
committed by GitHub
2 changed files with 93 additions and 23 deletions
+27 -5
View File
@@ -12,7 +12,33 @@
display: block; display: block;
} }
/* Selection hint */ .canvas-controls {
position: absolute;
bottom: 10px;
left: 10px;
right: 10px;
display: flex;
justify-content: space-between;
align-items: center;
z-index: 10;
pointer-events: none;
}
.canvas-controls > * {
pointer-events: auto;
}
.clear-selection-btn {
background-color: #ff4444;
color: white;
padding: 8px 16px;
border-radius: 4px;
}
.clear-selection-btn:hover {
background-color: #cc0000;
}
.selection-hint { .selection-hint {
position: absolute; position: absolute;
bottom: 40px; bottom: 40px;
@@ -49,16 +75,12 @@
/* Zoom controls */ /* Zoom controls */
.zoom-controls { .zoom-controls {
position: absolute;
bottom: 10px;
right: 10px;
display: flex; display: flex;
align-items: center; align-items: center;
gap: 4px; gap: 4px;
background-color: rgba(0, 0, 0, 0.8); background-color: rgba(0, 0, 0, 0.8);
padding: 6px 10px; padding: 6px 10px;
border-radius: 4px; border-radius: 4px;
z-index: 10;
} }
.zoom-controls button { .zoom-controls button {
+66 -18
View File
@@ -6,17 +6,23 @@ const ImageCanvas = forwardRef(({
imageUrl, imageUrl,
onSelectionChange, onSelectionChange,
selectionMode, selectionMode,
activeTool, advancedToolMode,
onAdvancedToolClick,
zoom = 100, zoom = 100,
onSmartSelect, onZoomChange,
externalSelection,
isProcessing isProcessing
}, ref) => { }, ref) => {
const canvasRef = useRef(null); const canvasRef = useRef(null);
const fabricCanvasRef = useRef(null); const fabricCanvasRef = useRef(null);
const [currentSelection, setCurrentSelection] = useState(null); const [currentSelection, setCurrentSelection] = useState(null);
const [currentZoom, setCurrentZoom] = useState(1);
const currentSelectionRef = useRef(null); const currentSelectionRef = useRef(null);
const lassoPoints = useRef([]); const lassoPoints = useRef([]);
const onZoomChangeRef = useRef(onZoomChange); const onZoomChangeRef = useRef(onZoomChange);
const imageRef = useRef(null);
const baseScaleRef = useRef(1);
const isDrawingRef = useRef(false);
// Keep ref updated // Keep ref updated
useEffect(() => { useEffect(() => {
@@ -200,23 +206,23 @@ const ImageCanvas = forwardRef(({
canvas.off('object:moving'); canvas.off('object:moving');
canvas.off('object:scaling'); canvas.off('object:scaling');
// Set up handlers based on selection mode // Set up handlers based on selection mode or advanced tool mode
if (selectionMode === 'rectangle') { if (advancedToolMode === 'smart-select') {
setupSmartSelectMode(canvas);
} else if (advancedToolMode === 'color-select') {
setupColorSelectMode(canvas);
} else if (selectionMode === 'rectangle') {
setupRectangleMode(canvas); setupRectangleMode(canvas);
} else if (selectionMode === 'ellipse') { } else if (selectionMode === 'ellipse') {
setupEllipseMode(canvas); setupEllipseMode(canvas);
} else if (selectionMode === 'lasso') { } else if (selectionMode === 'lasso') {
setupLassoMode(canvas); setupLassoMode(canvas);
} else if (selectionMode === 'smart') { } else if (selectionMode === 'move') {
setupSmartSelectMode(canvas);
} else if (selectionMode === 'color') {
setupColorSelectMode(canvas);
} else if (activeTool === 'move') {
setupMoveMode(canvas); setupMoveMode(canvas);
} else if (activeTool === 'pan') { } else if (selectionMode === 'pan') {
setupPanMode(canvas); setupPanMode(canvas);
} }
}, [selectionMode, activeTool, onSmartSelect]); }, [selectionMode, advancedToolMode, onAdvancedToolClick, isProcessing]);
const setupMoveMode = (canvas) => { const setupMoveMode = (canvas) => {
// In move mode, allow selecting and moving selection objects // In move mode, allow selecting and moving selection objects
@@ -283,7 +289,7 @@ const ImageCanvas = forwardRef(({
// Check if click is within image bounds // Check if click is within image bounds
if (x >= 0 && x < img.width && y >= 0 && y < img.height) { if (x >= 0 && x < img.width && y >= 0 && y < img.height) {
onSmartSelect?.(x, y); onAdvancedToolClick?.(x, y, null);
} }
}); });
@@ -294,9 +300,38 @@ const ImageCanvas = forwardRef(({
canvas.on('mouse:down', (e) => { canvas.on('mouse:down', (e) => {
if (isProcessing) return; if (isProcessing) return;
// TODO: Get pixel color at click position
const pointer = canvas.getPointer(e.e); const pointer = canvas.getPointer(e.e);
console.log('Color select at:', pointer); const img = imageRef.current;
if (!img) return;
// Convert to image coordinates
const imgScale = img.scaleX;
const imgLeft = img.left;
const imgTop = img.top;
const x = Math.round((pointer.x - imgLeft) / imgScale);
const y = Math.round((pointer.y - imgTop) / imgScale);
// Check if click is within image bounds
if (x >= 0 && x < img.width && y >= 0 && y < img.height) {
// Get pixel color from canvas
const ctx = canvas.getContext('2d');
if (ctx) {
// Calculate actual canvas position accounting for viewport transform
const vpt = canvas.viewportTransform;
const canvasX = pointer.x * vpt[0] + vpt[4];
const canvasY = pointer.y * vpt[3] + vpt[5];
const pixelData = ctx.getImageData(canvasX, canvasY, 1, 1).data;
const color = {
r: pixelData[0],
g: pixelData[1],
b: pixelData[2]
};
onAdvancedToolClick?.(x, y, color);
}
}
}); });
canvas.setCursor('crosshair'); canvas.setCursor('crosshair');
@@ -690,10 +725,23 @@ const ImageCanvas = forwardRef(({
return ( return (
<div className="canvas-container"> <div className="canvas-container">
<canvas ref={canvasRef} /> <canvas ref={canvasRef} />
{currentSelection && ( <div className="canvas-controls">
<button className="clear-selection-btn" onClick={clearSelection}> <div className="zoom-controls">
Clear <button onClick={handleZoomOut} title="Zoom Out"></button>
</button> <span className="zoom-level">{Math.round(currentZoom * 100)}%</span>
<button onClick={handleZoomIn} title="Zoom In">+</button>
<button onClick={handleZoomReset} title="Reset Zoom"></button>
</div>
{currentSelection && (
<button className="clear-selection-btn" onClick={clearSelection}>
Clear Selection
</button>
)}
</div>
{(advancedToolMode === 'smart-select' || advancedToolMode === 'color-select') && (
<div className="tool-mode-indicator">
{advancedToolMode === 'smart-select' ? 'Click on an object to select it' : 'Click on a color to select similar pixels'}
</div>
)} )}
</div> </div>
); );