Skip to content

Commit

Permalink
canvas general viewing
Browse files Browse the repository at this point in the history
  • Loading branch information
instructr13 committed Oct 19, 2024
1 parent 9c4c1df commit 0d4a17f
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 32 deletions.
52 changes: 38 additions & 14 deletions apps/frontend/src/app/components/pattern/Pattern.tsx
Original file line number Diff line number Diff line change
@@ -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) => (
<Grid templateColumns={`repeat(${pattern.width}, 1fr)`} style={style}>
{pattern.cells.map((row, rowIndex) =>
row.split("").map((cell, colIndex) => {
if (!isCell(cell)) throw new Error(`Invalid cell: ${cell}`);

return <BoardCell key={`${rowIndex}-${colIndex}-${cell}`} cell={cell} size="2rem" />;
}),
)}
</Grid>
);
export const Pattern = ({ pattern, size = 192, style }: Props) => {
const canvasRef = useRef<HTMLCanvasElement>(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 <canvas ref={canvasRef} width={size} height={size} style={style} />;
};
30 changes: 12 additions & 18 deletions apps/frontend/src/app/components/pattern/PatternList.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,28 @@
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<HTMLDivElement>(null);

const virtualizer = useVirtualizer({
horizontal: true,
gap: 12,
count: patterns.length,
getScrollElement: () => scrollRef.current,
estimateSize: (i) => patterns[i].width * 32,
estimateSize: (i) => 192,
paddingEnd: 12,
overscan: 2,
});

return (
<ScrollArea ref={scrollRef} innerProps={{ as: CardBody }} minH="200px">
<ScrollArea ref={scrollRef} innerProps={{ as: CardBody }} minH="256px">
<Box width={`${virtualizer.getTotalSize()}px`} h="100%" position="relative">
{virtualizer.getVirtualItems().map((virtualItem) => {
const pattern = patterns[virtualItem.index];
Expand All @@ -33,6 +31,7 @@ export const PatternListInner = ({ patterns }) => {
<Fragment key={virtualItem.key}>
<Pattern
pattern={pattern}
size={192}
style={{
position: "absolute",
top: 0,
Expand All @@ -49,19 +48,14 @@ export const PatternListInner = ({ patterns }) => {
};

export const PatternList = ({ patterns }: Props) => {
const [patternType, setPatternType] = useState<PatternType>("general");

return (
<HStack w="100vw">
<FormControl label="Type" w="15vw">
<Select value={patternType} onChange={(value) => setPatternType(value as PatternType)}>
<Option value={"general" satisfies PatternType}>General</Option>
<Option value={"fixed" satisfies PatternType}>Fixed</Option>
</Select>
</FormControl>
<Card variant="outline" w="75vw">
<PatternListInner patterns={patternType === "general" ? patterns : fixedPatterns.slice(0, 7)} />
<>
<Card variant="outline" w="100%">
<PatternListInner patterns={patterns} />
</Card>
</HStack>
<FormControl mt={8} label="Memo">
<Textarea autosize />
</FormControl>
</>
);
};

0 comments on commit 0d4a17f

Please sign in to comment.