Add a visual preview of the next pixel placement
Implement a pixel preview feature on hover, showing the selected color before committing the pixel placement. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 0385ea33-cde8-4bbd-8fce-8d192d30eb41 Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/870d08ce-da3b-4822-9874-c2fe2b7628b1/0385ea33-cde8-4bbd-8fce-8d192d30eb41/ZegP3fv
This commit is contained in:
parent
83fc03b313
commit
f017853c09
@ -25,6 +25,7 @@ export function Canvas({
|
||||
const [zoom, setZoom] = useState(1);
|
||||
const [pixelSize, setPixelSize] = useState(8);
|
||||
const [mouseCoords, setMouseCoords] = useState<{x: number, y: number} | null>(null);
|
||||
const [previewPixel, setPreviewPixel] = useState<{x: number, y: number} | null>(null);
|
||||
|
||||
// Create pixel map for O(1) lookup
|
||||
const pixelMap = new Map<string, string>();
|
||||
@ -39,10 +40,14 @@ export function Canvas({
|
||||
|
||||
const handlePixelMouseEnter = (x: number, y: number) => {
|
||||
setMouseCoords({ x, y });
|
||||
if (!cooldownActive) {
|
||||
setPreviewPixel({ x, y });
|
||||
}
|
||||
};
|
||||
|
||||
const handlePixelMouseLeave = () => {
|
||||
setMouseCoords(null);
|
||||
setPreviewPixel(null);
|
||||
};
|
||||
|
||||
const handleZoomIn = () => {
|
||||
@ -136,19 +141,24 @@ export function Canvas({
|
||||
{Array.from({ length: canvasHeight }, (_, y) =>
|
||||
Array.from({ length: canvasWidth }, (_, x) => {
|
||||
const pixelColor = pixelMap.get(`${x},${y}`) || "#FFFFFF";
|
||||
const isPreview = previewPixel && previewPixel.x === x && previewPixel.y === y;
|
||||
const previewColor = isPreview && !cooldownActive ? selectedColor : pixelColor;
|
||||
|
||||
return (
|
||||
<div
|
||||
key={`${x}-${y}`}
|
||||
className={cn(
|
||||
"pixel cursor-pointer hover:scale-110 hover:z-10 absolute",
|
||||
cooldownActive && "cursor-not-allowed"
|
||||
cooldownActive && "cursor-not-allowed",
|
||||
isPreview && !cooldownActive && "pixel-preview"
|
||||
)}
|
||||
style={{
|
||||
backgroundColor: pixelColor,
|
||||
backgroundColor: previewColor,
|
||||
width: `${pixelSize}px`,
|
||||
height: `${pixelSize}px`,
|
||||
left: `${x * pixelSize}px`,
|
||||
top: `${y * pixelSize}px`
|
||||
top: `${y * pixelSize}px`,
|
||||
opacity: isPreview && !cooldownActive ? 0.7 : 1
|
||||
}}
|
||||
onClick={() => handlePixelClick(x, y)}
|
||||
onMouseEnter={() => handlePixelMouseEnter(x, y)}
|
||||
@ -178,6 +188,11 @@ export function Canvas({
|
||||
Mouse: ({mouseCoords.x}, {mouseCoords.y})
|
||||
</div>
|
||||
)}
|
||||
{previewPixel && !cooldownActive && (
|
||||
<div className="text-xs text-blue-400 mt-1">
|
||||
Vorschau: {selectedColor}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Zoom Controls */}
|
||||
|
||||
@ -148,7 +148,7 @@
|
||||
|
||||
/* Optimierte Pixel-Hover-Effekte */
|
||||
.pixel {
|
||||
transition: transform 0.15s ease-out, box-shadow 0.15s ease-out;
|
||||
transition: transform 0.15s ease-out, box-shadow 0.15s ease-out, opacity 0.1s ease-out;
|
||||
}
|
||||
|
||||
.pixel:hover {
|
||||
@ -158,6 +158,18 @@
|
||||
box-shadow: 0 0 8px rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
/* Pixel-Vorschau */
|
||||
.pixel-preview {
|
||||
border: 2px solid rgba(255, 255, 255, 0.8);
|
||||
box-shadow: 0 0 12px rgba(255, 255, 255, 0.5);
|
||||
animation: previewPulse 1s ease-in-out infinite alternate;
|
||||
}
|
||||
|
||||
@keyframes previewPulse {
|
||||
0% { box-shadow: 0 0 12px rgba(255, 255, 255, 0.5); }
|
||||
100% { box-shadow: 0 0 20px rgba(255, 255, 255, 0.8); }
|
||||
}
|
||||
|
||||
/* Toast animations */
|
||||
.toast-enter {
|
||||
animation: slideInRight 0.3s ease-out;
|
||||
|
||||
1
exports/canvas-2025-08-18T12-40-19-350Z.svg
Normal file
1
exports/canvas-2025-08-18T12-40-19-350Z.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg"><rect width="100%" height="100%" fill="#FFFFFF"/></svg>
|
||||
|
After Width: | Height: | Size: 120 B |
1
exports/canvas-2025-08-18T12-41-19-351Z.svg
Normal file
1
exports/canvas-2025-08-18T12-41-19-351Z.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg"><rect width="100%" height="100%" fill="#FFFFFF"/></svg>
|
||||
|
After Width: | Height: | Size: 120 B |
Loading…
Reference in New Issue
Block a user