Skip to content

Commit

Permalink
Merge pull request #40 from melanke/place-pixel
Browse files Browse the repository at this point in the history
Place pixel
  • Loading branch information
phipsae authored Dec 20, 2024
2 parents 38d30fc + b2e7b78 commit 1aee1e7
Showing 1 changed file with 76 additions and 19 deletions.
95 changes: 76 additions & 19 deletions packages/nextjs/components/PixelCanvas.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useScaffoldReadContract } from "~~/hooks/scaffold-eth";
import { useEffect, useState } from "react";
import { useScaffoldReadContract, useScaffoldWriteContract } from "~~/hooks/scaffold-eth";

const ColorMap = {
0: "#FFFFFF", // WHITE
Expand All @@ -12,12 +13,48 @@ const ColorMap = {
};

const PixelCanvas = () => {
const { data: canvasData } = useScaffoldReadContract({
const [placingCoordinates, setPlacingCoordinates] = useState<{ x: bigint; y: bigint } | null>(null);
const [placingColor, setPlacingColor] = useState<number | null>(null);

const { data: canvasData, refetch: refetchCanvas } = useScaffoldReadContract({
contractName: "PixelCanvas",
functionName: "getFullCanvas",
watch: true,
});

const { writeContractAsync, isSuccess } = useScaffoldWriteContract("PixelCanvas");

useEffect(() => {
if (isSuccess) {
refetchCanvas();
}
}, [isSuccess, refetchCanvas]);

const save = async () => {
if (!placingCoordinates || placingColor === null) return;
await writeContractAsync({
functionName: "placePixel",
args: [placingCoordinates?.x, placingCoordinates?.y, placingColor],
});
setPlacingCoordinates(null);
setPlacingColor(null);
};

const isSelected = (x: number, y: number) => {
return BigInt(x) === placingCoordinates?.x && BigInt(y) === placingCoordinates?.y;
};

const getPixelColor = (x: number, y: number) => {
if (placingColor !== null && isSelected(x, y)) {
return ColorMap[placingColor as keyof typeof ColorMap];
}
if (!canvasData) {
return "#FFFFFF";
}
const pixel = canvasData[x][y];
return ColorMap[pixel.color as keyof typeof ColorMap];
};

if (!canvasData?.length) {
return <div className="animate-pulse">Loading canvas...</div>;
}
Expand All @@ -26,23 +63,43 @@ const PixelCanvas = () => {
const height = canvasData[0].length;

return (
<div
className="grid gap-0 border border-base-300"
style={{ gridTemplateColumns: `repeat(${height}, minmax(0, 1fr))` }}
>
{Array.from({ length: height }, (_, y) =>
Array.from({ length: width }, (_, x) => {
const pixel = canvasData[x][y];
return (
<div
key={`${x}-${y}`}
className="w-3 h-3 cursor-pointer outline-white hover:outline hover:z-10 hover:brightness-90"
style={{ backgroundColor: ColorMap[pixel.color as keyof typeof ColorMap] }}
title={`Author: ${pixel.author}\nTimestamp: ${new Date(Number(pixel.timestamp) * 1000).toLocaleString()}`}
/>
);
}),
).flat()}
<div className="flex flex-col gap-4">
<div
className="grid gap-0 border border-base-300"
style={{ gridTemplateColumns: `repeat(${height}, minmax(0, 1fr))` }}
>
{Array.from({ length: height }, (_, y) =>
Array.from({ length: width }, (_, x) => {
const pixel = canvasData[x][y];
return (
<div
key={`${x}-${y}`}
onClick={() => setPlacingCoordinates({ x: BigInt(x), y: BigInt(y) })}
className={`w-3 h-3 cursor-pointer outline-white hover:outline hover:z-10 hover:brightness-90 ${isSelected(x, y) && "z-10 outline outline-red-500"}`}
style={{ backgroundColor: getPixelColor(x, y) }}
title={`Author: ${pixel.author}\nHorário: ${new Date(Number(pixel.timestamp) * 1000).toLocaleString()}`}
/>
);
}),
).flat()}
</div>
{placingCoordinates && (
<div className="flex gap-4">
<div className="grid grid-cols-4 gap-1">
{Object.values(ColorMap).map((color, index) => (
<div
key={index}
className={`w-6 h-6 cursor-pointer ${placingColor === index && "outline outline-red-500"}`}
style={{ backgroundColor: color }}
onClick={() => setPlacingColor(index)}
/>
))}
</div>
<button className="mt-2 p-2 bg-blue-500 text-white rounded" onClick={save}>
Save Pixel
</button>
</div>
)}
</div>
);
};
Expand Down

0 comments on commit 1aee1e7

Please sign in to comment.