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 (
-
-
-
-
-
-
+ <>
+
+
-
+
+
+
+ >
);
};