From d2c579dc6b59052570eb5bd367a586e224c170bd Mon Sep 17 00:00:00 2001 From: RUNFUNRUN Date: Wed, 24 Jul 2024 23:59:13 +0900 Subject: [PATCH 1/2] feat: add drag mode --- src/app/_components/canvas.tsx | 25 ++++- src/app/_components/oekaki-chat.tsx | 13 ++- src/app/_components/piece.tsx | 33 +++++- src/app/_components/setting.tsx | 159 ++++++++++++++++++---------- src/types.ts | 4 +- 5 files changed, 167 insertions(+), 67 deletions(-) diff --git a/src/app/_components/canvas.tsx b/src/app/_components/canvas.tsx index 0a9ae17..25428ef 100644 --- a/src/app/_components/canvas.tsx +++ b/src/app/_components/canvas.tsx @@ -1,5 +1,5 @@ -import type { AsciiData, Height } from '@/types'; -import type { Dispatch, SetStateAction } from 'react'; +import type { AsciiData, DrawingMode, Height } from '@/types'; +import { useEffect, useState, type Dispatch, type SetStateAction } from 'react'; import { Piece } from './piece'; export const Canvas = ({ @@ -7,12 +7,30 @@ export const Canvas = ({ setAsciiData, width, height, + drawingMode, }: { asciiData: AsciiData; setAsciiData: Dispatch>; width: number; height: Height; + drawingMode: DrawingMode; }) => { + const [isMouseDown, setIsMouseDown] = useState(false); + + useEffect(() => { + if (drawingMode === 'drag') { + const handleWindowMouseUp = () => { + setIsMouseDown(false); + }; + + window.addEventListener('mouseup', handleWindowMouseUp); + + return () => { + window.removeEventListener('mouseup', handleWindowMouseUp); + }; + } + }, [drawingMode]); + return (
{asciiData.map((row, i) => { @@ -33,6 +51,9 @@ export const Canvas = ({ yIndex={i} asciiData={asciiData} setAsciiData={setAsciiData} + isMouseDown={isMouseDown} + setIsMouseDown={setIsMouseDown} + drawingMode={drawingMode} /> ); })} diff --git a/src/app/_components/oekaki-chat.tsx b/src/app/_components/oekaki-chat.tsx index c3d5d3e..1e01785 100644 --- a/src/app/_components/oekaki-chat.tsx +++ b/src/app/_components/oekaki-chat.tsx @@ -1,6 +1,6 @@ 'use client'; -import type { AsciiData, Height, Resolution } from '@/types'; +import type { AsciiData, DrawingMode, Height, Resolution } from '@/types'; import { useState } from 'react'; import { Buttons } from './buttons'; import { Canvas } from './canvas'; @@ -8,9 +8,9 @@ import { Setting } from './setting'; export const OekakiChat = () => { const fullhdWidth = 26; - const stretchWidth = 27; + const stretchedWidth = 27; - const maxW = fullhdWidth > stretchWidth ? fullhdWidth : stretchWidth; + const maxW = fullhdWidth > stretchedWidth ? fullhdWidth : stretchedWidth; const maxH = 13; const defaultAsciiData = (): AsciiData => { const data = new Array(maxH); @@ -25,6 +25,7 @@ export const OekakiChat = () => { const [asciiData, setAsciiData] = useState(defaultAsciiData()); const [resolution, setResolution] = useState('fullhd'); + const [drawingMode, setDrawingMode] = useState('click'); const [height, setHeight] = useState(7); return ( @@ -33,17 +34,19 @@ export const OekakiChat = () => { setResolution={setResolution} height={height} setHeight={setHeight} + setDrawingMode={setDrawingMode} />
diff --git a/src/app/_components/piece.tsx b/src/app/_components/piece.tsx index a87639c..200be06 100644 --- a/src/app/_components/piece.tsx +++ b/src/app/_components/piece.tsx @@ -1,4 +1,4 @@ -import type { AsciiData } from '@/types'; +import type { AsciiData, DrawingMode } from '@/types'; import { useTheme } from 'next-themes'; import { type Dispatch, type SetStateAction, useEffect, useState } from 'react'; @@ -8,12 +8,18 @@ export const Piece = ({ yIndex, asciiData, setAsciiData, + isMouseDown, + setIsMouseDown, + drawingMode, }: { active: boolean; xIndex: number; yIndex: number; asciiData: AsciiData; setAsciiData: Dispatch>; + isMouseDown: boolean; + setIsMouseDown: Dispatch; + drawingMode: DrawingMode; }) => { const { theme, systemTheme } = useTheme(); const [currentTheme, setCurrentTheme] = useState( @@ -28,12 +34,31 @@ export const Piece = ({ } }, [theme, systemTheme]); - const handleClick = () => { + const toggleAsciiData = () => { const newAsciiData = [...asciiData]; newAsciiData[yIndex][xIndex] = !newAsciiData[yIndex][xIndex]; setAsciiData(newAsciiData); }; + const handleClick = () => { + if (drawingMode === 'click') { + toggleAsciiData(); + } + }; + + const handleMouseDown = () => { + if (drawingMode === 'drag') { + setIsMouseDown(true); + toggleAsciiData(); + } + }; + + const handleMouseEnter = () => { + if (drawingMode === 'drag' && isMouseDown) { + toggleAsciiData(); + } + }; + if (active) { return (