Fix hover preview to show single bounding rectangle instead of per-square borders
This commit is contained in:
parent
e10c5d2b3d
commit
0cdcfe3a2e
2 changed files with 26 additions and 20 deletions
|
|
@ -207,21 +207,6 @@ const ChessboardRepaintPuzzle: React.FC<ChessboardRepaintPuzzleProps> = ({ showS
|
||||||
const isRightmostCol = col === 7;
|
const isRightmostCol = col === 7;
|
||||||
const isBottomRight = row === 7 && col === 7;
|
const isBottomRight = row === 7 && col === 7;
|
||||||
|
|
||||||
// Get bounding box for hover preview
|
|
||||||
const boundingBox = hoveredSquare ? getBoundingBox(getAffectedSquares(hoveredSquare.row, hoveredSquare.col)) : null;
|
|
||||||
|
|
||||||
// Check if this square is on the outer perimeter of the bounding box
|
|
||||||
const isOnPerimeter = boundingBox && (
|
|
||||||
// Top edge (only if not also bottom edge)
|
|
||||||
(row === boundingBox.minRow && col >= boundingBox.minCol && col <= boundingBox.maxCol && boundingBox.minRow !== boundingBox.maxRow) ||
|
|
||||||
// Bottom edge (only if not also top edge)
|
|
||||||
(row === boundingBox.maxRow && col >= boundingBox.minCol && col <= boundingBox.maxCol && boundingBox.minRow !== boundingBox.maxRow) ||
|
|
||||||
// Left edge (only if not also right edge)
|
|
||||||
(col === boundingBox.minCol && row >= boundingBox.minRow && row <= boundingBox.maxRow && boundingBox.minCol !== boundingBox.maxCol) ||
|
|
||||||
// Right edge (only if not also left edge)
|
|
||||||
(col === boundingBox.maxCol && row >= boundingBox.minRow && row <= boundingBox.maxRow && boundingBox.minCol !== boundingBox.maxCol)
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={`${row}-${col}`}
|
key={`${row}-${col}`}
|
||||||
|
|
@ -242,7 +227,6 @@ const ChessboardRepaintPuzzle: React.FC<ChessboardRepaintPuzzleProps> = ({ showS
|
||||||
w-12 h-12 border border-gray-300 flex items-center justify-center cursor-pointer
|
w-12 h-12 border border-gray-300 flex items-center justify-center cursor-pointer
|
||||||
transition-all duration-200 hover:scale-105
|
transition-all duration-200 hover:scale-105
|
||||||
${isBlack ? 'bg-gray-800' : 'bg-gray-100'}
|
${isBlack ? 'bg-gray-800' : 'bg-gray-100'}
|
||||||
${isOnPerimeter ? 'border-2 border-red-500' : ''}
|
|
||||||
`}
|
`}
|
||||||
title={isBottomRight ? `Hover for 3s to switch mode (current: ${bottomRightMode})` : undefined}
|
title={isBottomRight ? `Hover for 3s to switch mode (current: ${bottomRightMode})` : undefined}
|
||||||
/>
|
/>
|
||||||
|
|
@ -309,6 +293,30 @@ const ChessboardRepaintPuzzle: React.FC<ChessboardRepaintPuzzleProps> = ({ showS
|
||||||
row.map((square, colIndex) => renderSquare(rowIndex, colIndex))
|
row.map((square, colIndex) => renderSquare(rowIndex, colIndex))
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Bounding rectangle overlay */}
|
||||||
|
{hoveredSquare && (() => {
|
||||||
|
const boundingBox = getBoundingBox(getAffectedSquares(hoveredSquare.row, hoveredSquare.col));
|
||||||
|
if (!boundingBox) return null;
|
||||||
|
|
||||||
|
const squareSize = 48; // w-12 = 48px
|
||||||
|
const left = boundingBox.minCol * squareSize;
|
||||||
|
const top = boundingBox.minRow * squareSize;
|
||||||
|
const width = (boundingBox.maxCol - boundingBox.minCol + 1) * squareSize;
|
||||||
|
const height = (boundingBox.maxRow - boundingBox.minRow + 1) * squareSize;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="absolute pointer-events-none border-2 border-red-500 bg-red-500 bg-opacity-10"
|
||||||
|
style={{
|
||||||
|
left: `${left}px`,
|
||||||
|
top: `${top}px`,
|
||||||
|
width: `${width}px`,
|
||||||
|
height: `${height}px`,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})()}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,12 +17,10 @@ const Layout = ({ children }: LayoutProps) => {
|
||||||
<footer className="bg-surface border-t border-outline py-8 px-4 mt-auto">
|
<footer className="bg-surface border-t border-outline py-8 px-4 mt-auto">
|
||||||
<div className="max-w-6xl mx-auto text-center">
|
<div className="max-w-6xl mx-auto text-center">
|
||||||
<p className="text-muted-foreground">
|
<p className="text-muted-foreground">
|
||||||
© 2024 Interactives. Educational tools for enhanced learning experiences.
|
© 2025 Interactives. Interactives for enhanced learning experiences and pure joy.
|
||||||
</p>
|
</p>
|
||||||
<div className="mt-4 flex justify-center gap-6 text-sm text-muted-foreground">
|
<div className="mt-4 flex justify-center gap-6 text-sm text-muted-foreground">
|
||||||
<span>Made with ❤️ for education</span>
|
<span>Made with ❤️ and help from friends and LLMs. More detailed acks coming soon!</span>
|
||||||
<span>•</span>
|
|
||||||
<span>Explore • Learn • Discover</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue