From 38ba177105e4a2ead0cc91a2ac16aa742ed78fbc Mon Sep 17 00:00:00 2001 From: osohyun0224 Date: Thu, 29 Jun 2023 21:52:26 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20imageselect=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20=EC=A0=84=EB=A9=B4=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.jsx | 2 - src/assets/images/Enter.png | Bin 0 -> 617 bytes src/components/LandingPage/Contents.jsx | 2 +- src/imageinput.jsx | 3 +- src/imageselect.jsx | 311 +++++++++++++++--------- 5 files changed, 197 insertions(+), 121 deletions(-) create mode 100644 src/assets/images/Enter.png diff --git a/src/App.jsx b/src/App.jsx index 486e50c..afea7d7 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -5,7 +5,6 @@ import LandingPage from "./pages/LandingPage"; import Header from "./components/Layout/Header"; import LoginPage from "./pages/LoginPage"; import SignupPage from "./pages/SignupPage"; -import ImageUpload from "./imageinput"; import ImageSelect from "./imageselect"; const StyledApp = styled.div` @@ -23,7 +22,6 @@ function App() { } /> } /> } /> - } /> } /> diff --git a/src/assets/images/Enter.png b/src/assets/images/Enter.png new file mode 100644 index 0000000000000000000000000000000000000000..347b75a36293fa746ee8c7c4f0bc73dc5a46884a GIT binary patch literal 617 zcmV-v0+#)WP)e$2^AUD8HZK7RDJwZ(GOmc&eGF51_Qpxus z%K(}TB78IOmSy+-_B|d8tl#hF>0k*kWr&G7v9l*Jk$z-k#!?2vb z!hXLW0NB8#iThJYl4hgP$Yc>DId(~>^?F?wH^?C(Q~@di@(N3f`RH^yPqYYjrnqRd z+wE^SdmoR-cc%shA|y@G*26~Vg0NBpD{f@7*`i2aoIuGXaz4kA-)uI@e-i>JouNw& zlTz-zaMCwN`kE}H!ba!=g-u@+AP)>y0D8fMCalRK2+j+54Ky?hULX$+L{v75Sy=cY zD5kOaU5!MRF}qyR!c5o~{iU1xRi00000NkvXXu0mjf DBBT2p literal 0 HcmV?d00001 diff --git a/src/components/LandingPage/Contents.jsx b/src/components/LandingPage/Contents.jsx index 95d3d53..964ab61 100644 --- a/src/components/LandingPage/Contents.jsx +++ b/src/components/LandingPage/Contents.jsx @@ -43,7 +43,7 @@ function Contents() { navigation("/user/imageinput")} + onClick={() => navigation("/user/imageselect")} >{`이미지 업로드 >>`} ); diff --git a/src/imageinput.jsx b/src/imageinput.jsx index 7648f2b..8f96813 100644 --- a/src/imageinput.jsx +++ b/src/imageinput.jsx @@ -24,7 +24,8 @@ const ImageUpload = () => { }; const handleSubmit = () => { - navigate("/user/imageselect"); // '/imageselect'로 이동 + + navigate("/user/imageselect"); }; const handleSelectImage = () => { diff --git a/src/imageselect.jsx b/src/imageselect.jsx index ae0beb9..1004dee 100644 --- a/src/imageselect.jsx +++ b/src/imageselect.jsx @@ -1,37 +1,19 @@ -import React, { useState, useRef } from 'react'; -import { Stage, Layer, Rect, Image, Line, Text } from 'react-konva'; +import React, { useState, useRef, useEffect } from "react"; +import { useNavigate } from "react-router-dom"; +import { Stage, Layer, Rect, Image, Line } from "react-konva"; +import EnterImage from "./assets/images/Enter.png"; const DrawingEditor = () => { const [image, setImage] = useState(null); const [lines, setLines] = useState([]); - const [text, setText] = useState(''); + const [text, setText] = useState(""); + const [imageSize, setImageSize] = useState({ width: 0, height: 0 }); const isDrawing = useRef(false); const stageRef = useRef(null); const imageRef = useRef(null); + const fileInputRef = useRef(null); + const navigate = useNavigate(); - - const saveDrawing = () => { - // 그림 데이터와 텍스트를 백엔드로 전송 - const payload = { - lines: lines, - prompt: text, // 백엔드에 'prompt'라는 변수로 텍스트 전송 - }; - - fetch('http://your-backend-server.com/api/save-drawing', { // 백엔드 API endpoint, 수정 필요 - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify(payload), - }) - .then((response) => response.json()) - .then((data) => console.log(data)) - .catch((error) => console.error('Error:', error)); - - console.log('그림 저장:', lines, text); - }; - - //마우스 위치가 이미지 내부인지 확인하는 함수 const isWithinImage = (x, y) => { if (!image) return false; @@ -48,39 +30,62 @@ const DrawingEditor = () => { ); }; - const handleImageChange = (event) => { - const file = event.target.files[0]; - const reader = new FileReader(); - - reader.onload = (e) => { + useEffect(() => { + if (image) { const img = new window.Image(); - img.src = e.target.result; - + img.src = image; img.onload = () => { - setImage(img); + imageRef.current.image(img); + imageRef.current.getLayer().batchDraw(); }; - }; - - reader.readAsDataURL(file); - }; - + } + }, [image]); const handleMouseDown = (event) => { - if (!image) return; // 이미지가 없을 경우 그리기 작업 중지 - isDrawing.current = true; const { offsetX, offsetY } = event.evt; - // 코드 수정: 이미지 내부에서만 그림 그리기 시작 + if (isWithinImage(offsetX, offsetY)) { - isDrawing.current = true; setLines([...lines, { points: [offsetX, offsetY] }]); } +}; + + const handleImageChange = (event) => { + const file = event.target.files[0]; + const reader = new FileReader(); + + reader.onload = (e) => { + setImage(e.target.result); + + // Create new image to get its size + const tempImg = new window.Image(); + tempImg.onload = () => { + const aspectRatio = tempImg.width / tempImg.height; + let imgWidth, imgHeight; + + if (tempImg.width > tempImg.height) { + imgWidth = 800; + imgHeight = imgWidth / aspectRatio; + } else { + imgHeight = 600; + imgWidth = imgHeight * aspectRatio; + } + + // Update image size state + setImageSize({ width: imgWidth, height: imgHeight }); + }; + tempImg.src = e.target.result; + }; + + reader.readAsDataURL(file); }; + const handleMouseMove = (event) => { if (!isDrawing.current) return; const { offsetX, offsetY } = event.evt; + if (isWithinImage(offsetX, offsetY)) { const updatedLines = [...lines]; const lastLine = updatedLines[updatedLines.length - 1]; @@ -89,10 +94,10 @@ const DrawingEditor = () => { setLines(updatedLines); } else { - // 이미지 영역 밖으로 나가면 그리기 중지 isDrawing.current = false; } }; + const handleMouseUp = () => { isDrawing.current = false; }; @@ -101,48 +106,21 @@ const DrawingEditor = () => { setText(event.target.value); }; - const handleImageLoad = () => { - const img = imageRef.current; - const stage = stageRef.current; + const handleTextSave = () => { + // 텍스트를 백엔드로 보내는 로직 구현 + const textToSend = text; + // 백엔드로 텍스트를 보내는 API 호출 또는 로직 구현 - const boxWidth = 2000; - const boxHeight = 800; - const stageWidth = stage.width(); - const stageHeight = stage.height(); - - let scaleX = stageWidth / img.width; - let scaleY = stageHeight / img.height; - - // 이미지를 박스 안에 맞추기 위한 스케일 팩터 계산 - const scaleFactor = Math.min(scaleX, scaleY); - - // 이미지의 새로운 크기 계산 - const newWidth = img.width * scaleFactor; - const newHeight = img.height * scaleFactor; - - // 이미지의 크기를 조정할 필요가 있는 경우에만 실행 - if (newWidth > boxWidth || newHeight > boxHeight) { - const scale = Math.min(boxWidth / newWidth, boxHeight / newHeight); - const adjustedWidth = newWidth * scale; - const adjustedHeight = newHeight * scale; - - img.width(adjustedWidth); - img.height(adjustedHeight); - } - - // 이미지를 박스 가운데로 위치시키기 위한 좌표 계산 - const newX = (stageWidth - img.width()) / 2; - const newY = (stageHeight - img.height()) / 2; - - // 이미지의 위치 업데이트 - img.position({ x: newX, y: newY }); - - // 스테이지의 크기를 이미지에 맞게 업데이트 - stage.width(img.width()); - stage.height(img.height()); - - // 스테이지를 다시 그려서 변경 사항을 반영 - stage.draw(); + // 텍스트 입력 초기화 + setText(""); + }; + + const handleSubmit = () => { + navigate("/user/imageselect"); + }; + + const handleSelectImage = () => { + fileInputRef.current.click(); }; return ( @@ -156,12 +134,11 @@ const DrawingEditor = () => { justifyContent: "center", }} > -
{ backgroundColor: "rgba(255, 255, 255, 0.01)", }} > - + + - - - - {image && ( - - )} - + height={600} + fill="rgba(255, 255, 255, 0.3)" + stroke="black" + /> + + {image && ( + + )} + {lines.map((line, index) => ( { tension={0.5} lineCap="round" globalCompositeOperation="source-over" - listening={false} // 이미지 위에서는 마우스 이벤트를 받지 않도록 설정 + listening={false} /> ))}
- - + +
+ +
+ +{image && ( + + + )} +
+ +
+ + ); }; -export default DrawingEditor; \ No newline at end of file +export default DrawingEditor;