From 666beff06a2a08b273d00bdc8f56ee35b10dedfe Mon Sep 17 00:00:00 2001 From: Phong Lam Date: Tue, 17 Oct 2023 21:34:05 -0600 Subject: [PATCH] add eraser and size --- src/components/Canvas.tsx | 133 +++++++++++++++++++++++++---------- src/components/ColorGrid.tsx | 31 +++----- 2 files changed, 103 insertions(+), 61 deletions(-) diff --git a/src/components/Canvas.tsx b/src/components/Canvas.tsx index 687d707..449ff6e 100644 --- a/src/components/Canvas.tsx +++ b/src/components/Canvas.tsx @@ -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 { @@ -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>(new Set()); + const [cursorSize, setCursorSize] = useState(CursorSizes.Small); const [color, setColor] = useState("#aabbcc"); const { mutate: signAndExecuteTransactionBlock } = useSignAndExecuteTransactionBlock(); @@ -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(); @@ -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]]), ], }); } @@ -99,6 +134,7 @@ const Canvas: React.FC = () => { { onSuccess: (tx) => { console.log(tx); + setDeltas(new Set()); client.waitForTransactionBlock({ digest: tx.digest }).then(() => { refetch(); }); @@ -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][] = []; @@ -139,17 +175,36 @@ const Canvas: React.FC = () => { return (
- - + { + setColor(color); + setCursorSize(CursorSizes.Small); + }} /> + + + + { + setCursorSize(value as CursorSizes); + }}> + + {cursorSelection.map(cursorSize => { + return ( + + + {cursorSize} + + + )})} + + + diff --git a/src/components/ColorGrid.tsx b/src/components/ColorGrid.tsx index 66dfcf7..3625388 100644 --- a/src/components/ColorGrid.tsx +++ b/src/components/ColorGrid.tsx @@ -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 = ({ 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 ( -
+
setIsDragging(!isDragging)} + onMouseLeave={() => setIsDragging(false)} + style={{ + cursor: isDragging ? 'crosshair' : 'pointer', + }} + > {colors.map((row, rowIndex) => (
{row.map((color, colIndex) => ( @@ -44,12 +35,8 @@ const ColorGrid: React.FC = ({ : color, width: "10px", height: "10px", - cursor: isDragging ? "grabbing" : "pointer", }} - onClick={() => handleSquareClick(rowIndex, colIndex)} - onMouseDown={onMouseDown} onMouseMove={(e) => onMouseMove(e, rowIndex, colIndex)} - onMouseUp={onMouseUp} >
))}