From 0d4a17ff5a1aafbf979ed79b77d583c402353019 Mon Sep 17 00:00:00 2001 From: Mido Date: Sun, 20 Oct 2024 06:49:39 +0900 Subject: [PATCH] canvas general viewing --- .../src/app/components/pattern/Pattern.tsx | 52 ++++++++++++++----- .../app/components/pattern/PatternList.tsx | 30 +++++------ 2 files changed, 50 insertions(+), 32 deletions(-) diff --git a/apps/frontend/src/app/components/pattern/Pattern.tsx b/apps/frontend/src/app/components/pattern/Pattern.tsx index 317bf32..db2c484 100644 --- a/apps/frontend/src/app/components/pattern/Pattern.tsx +++ b/apps/frontend/src/app/components/pattern/Pattern.tsx @@ -1,21 +1,45 @@ import type { Pattern as PatternSchema } from "@data-maki/schemas"; -import { Grid } from "@yamada-ui/react"; -import type { CSSProperties } from "react"; -import { BoardCell, isCell } from "../board/Cell"; +import { type CSSProperties, useEffect, useRef } from "react"; +import { isCell } from "../board/Cell"; type Props = Readonly<{ pattern: PatternSchema; + size?: number; style?: CSSProperties; }>; -export const Pattern = ({ pattern, style }: Props) => ( - - {pattern.cells.map((row, rowIndex) => - row.split("").map((cell, colIndex) => { - if (!isCell(cell)) throw new Error(`Invalid cell: ${cell}`); - - return ; - }), - )} - -); +export const Pattern = ({ pattern, size = 192, style }: Props) => { + const canvasRef = useRef(null); + + useEffect(() => { + if (!canvasRef.current) return; + + const canvas = canvasRef.current; + const ctx = canvas.getContext("2d"); + + if (!ctx) return; + + const { width, height, cells } = pattern; + + const cellHeight = size / height; + const cellWidth = size / width; + + for (let i = 0; i < height; i++) { + for (let j = 0; j < width; j++) { + const cell = cells[i][j]; + + if (isCell(cell)) { + if (cell === "1") { + ctx.fillStyle = "#000"; + } else { + ctx.fillStyle = "#fff"; + } + + ctx.fillRect(j * cellWidth, i * cellHeight, cellWidth, cellHeight); + } + } + } + }, [pattern, size]); + + return ; +}; diff --git a/apps/frontend/src/app/components/pattern/PatternList.tsx b/apps/frontend/src/app/components/pattern/PatternList.tsx index f8868af..375347c 100644 --- a/apps/frontend/src/app/components/pattern/PatternList.tsx +++ b/apps/frontend/src/app/components/pattern/PatternList.tsx @@ -1,16 +1,14 @@ import { type Pattern as PatternSchema, fixedPatterns } from "@data-maki/schemas"; import { useVirtualizer } from "@tanstack/react-virtual"; -import { Box, Card, CardBody, FormControl, HStack, Option, ScrollArea, Select } from "@yamada-ui/react"; +import { Box, Card, CardBody, FormControl, HStack, Option, ScrollArea, Select, Textarea } from "@yamada-ui/react"; import { Fragment, useRef, useState } from "react"; import { Pattern } from "./Pattern"; -type PatternType = "general" | "fixed"; - type Props = Readonly<{ patterns: PatternSchema[]; }>; -export const PatternListInner = ({ patterns }) => { +export const PatternListInner = ({ patterns }: Props) => { const scrollRef = useRef(null); const virtualizer = useVirtualizer({ @@ -18,13 +16,13 @@ export const PatternListInner = ({ patterns }) => { gap: 12, count: patterns.length, getScrollElement: () => scrollRef.current, - estimateSize: (i) => patterns[i].width * 32, + estimateSize: (i) => 192, paddingEnd: 12, overscan: 2, }); return ( - + {virtualizer.getVirtualItems().map((virtualItem) => { const pattern = patterns[virtualItem.index]; @@ -33,6 +31,7 @@ export const PatternListInner = ({ patterns }) => { { }; export const PatternList = ({ patterns }: Props) => { - const [patternType, setPatternType] = useState("general"); - return ( - - - - - - + <> + + - + +