Skip to content

Commit

Permalink
Merge pull request #1 from MystenLabs/plam-update
Browse files Browse the repository at this point in the history
add eraser and size
  • Loading branch information
healthydeve authored Oct 18, 2023
2 parents d6cf48b + 666beff commit 67414c8
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 61 deletions.
133 changes: 94 additions & 39 deletions src/components/Canvas.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useState, useEffect } from "react";
import { Button, Container } from "@radix-ui/themes";
import {Button, Container, Flex, RadioGroup, Text} from "@radix-ui/themes";
import { HexColorPicker } from "react-colorful";
import { TransactionBlock } from "@mysten/sui.js/transactions";
import {
Expand All @@ -10,9 +10,45 @@ import ColorGrid from "./ColorGrid";
import { useGetCanvas } from "../useGetCanvas";
import { SuiObjectData } from "@mysten/sui.js/client";

const cursorSizes = {
Small: 1,
Medium: 2,
Large: 3,
}

enum CursorSizes {
Small = 'Small',
Medium = 'Medium',
Large = 'Large',
}

const cursorSelection: CursorSizes[] = [CursorSizes.Small, CursorSizes.Medium, CursorSizes.Large];

function getCoords(size: CursorSizes, [x, y]: [number, number]) {
if (size === CursorSizes.Small) {
return [[x, y]];
}

const sizeToNum = cursorSizes[size];

const coords = [];
const gridSize = sizeToNum * 2 - 1
const halfGridSize = Math.floor(gridSize / 2);

for (let i = -halfGridSize; i <= halfGridSize; i++) {
for (let j = -halfGridSize; j <= halfGridSize; j++) {
coords.push([x + i, y + j]);
}
}

return coords;
}

const Canvas: React.FC = () => {
const client = useSuiClient();

const [deltas, setDeltas] = useState<Set<string>>(new Set());
const [cursorSize, setCursorSize] = useState(CursorSizes.Small);
const [color, setColor] = useState("#aabbcc");
const { mutate: signAndExecuteTransactionBlock } =
useSignAndExecuteTransactionBlock();
Expand All @@ -26,31 +62,26 @@ const Canvas: React.FC = () => {
// Dragging Mouse
const [isDragging, setIsDragging] = useState(false);

const handleMouseDown = (_e: React.MouseEvent) => {
if (!isDragging) {
setIsDragging(true);
}
};

const handleMouseMove = (
_e: React.MouseEvent,
rowIndex: number,
colIndex: number,
) => {
if (isDragging) {
const newColors = localGrid.map((row, rIndex) =>
row.map((old_color, cIndex) =>
rIndex === rowIndex && cIndex === colIndex ? color : old_color,
),
);
const coords = getCoords(cursorSize, [rowIndex, colIndex]);
const newColors = []
for (let row = 0; row < localGrid.length; row++) {
newColors.push(localGrid[row].slice());
}
for (const [x, y] of coords) {
newColors[x][y] = color;
}

setDeltas(new Set([...deltas, ...coords.map(([x, y]) => `${x},${y}`)]));
setLocalGrid(newColors);
}
};

const handleMouseUp = () => {
setIsDragging(false);
};

useEffect(() => {
const interval = setInterval(() => {
refetch();
Expand All @@ -68,25 +99,29 @@ const Canvas: React.FC = () => {
const newLocalGrid = Array.from({ length: currentCanvas.length }, () =>
Array(currentCanvas[0].length).fill("0"),
);

setLocalGrid(newLocalGrid);
}
}
}, [data, isLoading, error]);

const handleSubmitColors = async () => {
const deltas = getLocalDelta(localGrid);
const newDeltas = Array.from(deltas).map((delta) => {
const [x, y] = delta.split(",").map((x) => parseInt(x));
return [x, y];
});

let transactionBlock = new TransactionBlock();
for (const idx in deltas) {
for (const idx in newDeltas) {
transactionBlock.moveCall({
target: `0x3c5f9f43eccf2648855c6febf1143966d87541d47775b2b90c03f875da03cc71::board::update_single_pixel`,
arguments: [
transactionBlock.object(
"0xe3390ae6a360a076b708691b2a1c24981b931e009cbf4aa6531e559c93d1f28c",
),
transactionBlock.pure(deltas[idx][0]),
transactionBlock.pure(deltas[idx][1]),
transactionBlock.pure(localGrid[deltas[idx][0]][deltas[idx][1]]),
transactionBlock.pure(newDeltas[idx][0]),
transactionBlock.pure(newDeltas[idx][1]),
transactionBlock.pure(localGrid[newDeltas[idx][0]][newDeltas[idx][1]]),
],
});
}
Expand All @@ -99,6 +134,7 @@ const Canvas: React.FC = () => {
{
onSuccess: (tx) => {
console.log(tx);
setDeltas(new Set());
client.waitForTransactionBlock({ digest: tx.digest }).then(() => {
refetch();
});
Expand All @@ -110,17 +146,17 @@ const Canvas: React.FC = () => {
);
};

const getLocalDelta = (localState: string[][]) => {
const deltaIndices: [number, number][] = [];
for (let row = 0; row < localState.length; row++) {
for (let col = 0; col < localState[row].length; col++) {
if (localState[row][col] !== "0") {
deltaIndices.push([row, col]);
}
}
}
return deltaIndices;
};
// const getLocalDelta = (localState: string[][]) => {
// const deltaIndices: [number, number][] = [];
// for (let row = 0; row < localState.length; row++) {
// for (let col = 0; col < localState[row].length; col++) {
// if (localState[row][col] !== "0") {
// deltaIndices.push([row, col]);
// }
// }
// }
// return deltaIndices;
// };

// const getDelta = (initial: string[][], grid: string[][]) => {
// const deltaIndices: [number, number][] = [];
Expand All @@ -139,17 +175,36 @@ const Canvas: React.FC = () => {
return (
<div>
<Container>
<HexColorPicker color={color} onChange={setColor} />
<Button onClick={handleSubmitColors}> Submit Txn </Button>
<HexColorPicker color={color} onChange={(color) => {
setColor(color);
setCursorSize(CursorSizes.Small);
}} />
<Flex gap="2" direction="row">
<Button onClick={handleSubmitColors}> Submit Txn </Button>
<Button onClick={() => {
setColor('#ffffff');
setCursorSize(CursorSizes.Medium);
}}>Eraser &#9003;</Button>
<RadioGroup.Root defaultValue={cursorSize} value={cursorSize} onValueChange={(value) => {
setCursorSize(value as CursorSizes);
}}>
<Flex gap="2" direction="column">
{cursorSelection.map(cursorSize => {
return (
<Text as="label" size="2" key={cursorSize}>
<Flex gap="2">
<RadioGroup.Item value={cursorSize} /> {cursorSize}
</Flex>
</Text>
)})}
</Flex>
</RadioGroup.Root>
</Flex>
<ColorGrid
colors={gridColors}
selectedColor={color}
localColorGrid={localGrid}
onColorChange={setLocalGrid}
onMouseDown={handleMouseDown}
setIsDragging={setIsDragging}
onMouseMove={handleMouseMove}
onMouseUp={handleMouseUp}
// selectedArea={selectedArea}
isDragging={isDragging}
/>
</Container>
Expand Down
31 changes: 9 additions & 22 deletions src/components/ColorGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,26 @@ import React from "react";
interface ColorGridProps {
colors: string[][];
localColorGrid: string[][];
selectedColor: string;
onColorChange: (x: string[][]) => void;
onMouseDown: (event: React.MouseEvent) => void;
setIsDragging: (isDragging: boolean) => void;
onMouseMove: (event: React.MouseEvent, x: number, y: number) => void;
onMouseUp: () => void;
isDragging: boolean;
}

const ColorGrid: React.FC<ColorGridProps> = ({
colors,
selectedColor,
localColorGrid,
onColorChange,
onMouseDown,
onMouseMove,
onMouseUp,
isDragging,
setIsDragging,
}) => {
const handleSquareClick = (rowIndex: number, colIndex: number) => {
const newColors = colors.map((row, rIndex) =>
row.map((color, cIndex) =>
rIndex === rowIndex && cIndex === colIndex ? selectedColor : color,
),
);
onColorChange(newColors);
};

return (
<div>
<div
onMouseDown={() => setIsDragging(!isDragging)}
onMouseLeave={() => setIsDragging(false)}
style={{
cursor: isDragging ? 'crosshair' : 'pointer',
}}
>
{colors.map((row, rowIndex) => (
<div key={rowIndex} style={{ display: "flex" }}>
{row.map((color, colIndex) => (
Expand All @@ -44,12 +35,8 @@ const ColorGrid: React.FC<ColorGridProps> = ({
: color,
width: "10px",
height: "10px",
cursor: isDragging ? "grabbing" : "pointer",
}}
onClick={() => handleSquareClick(rowIndex, colIndex)}
onMouseDown={onMouseDown}
onMouseMove={(e) => onMouseMove(e, rowIndex, colIndex)}
onMouseUp={onMouseUp}
></div>
))}
</div>
Expand Down

0 comments on commit 67414c8

Please sign in to comment.