From df9510f56c2212da829b84734dfb2dd305af4e20 Mon Sep 17 00:00:00 2001 From: jongwony Date: Thu, 17 Oct 2024 10:42:13 +0900 Subject: [PATCH] fix UI: crop image; width full --- src/app/form/Profile.tsx | 64 +++++++++++++++++++++++++--------------- src/app/form/page.tsx | 22 +++++++------- 2 files changed, 52 insertions(+), 34 deletions(-) diff --git a/src/app/form/Profile.tsx b/src/app/form/Profile.tsx index ea5912f..8f7e0aa 100644 --- a/src/app/form/Profile.tsx +++ b/src/app/form/Profile.tsx @@ -18,8 +18,29 @@ export default function ProfilePictureUpload() { const file = event.target.files?.[0] if (file) { const reader = new FileReader() - reader.onload = (e) => setImage(e.target?.result as string) + const validImageTypes = [ + 'image/jpeg', + 'image/png', + 'image/heic', + 'image/heif', + 'image/webp', + ] + if (!validImageTypes.includes(file.type)) { + alert('지원하지 않는 이미지 형식입니다.') + return + } + reader.onload = (e) => { + const result = e.target?.result + if (typeof result === 'string') { + setImage(result) + } + } + reader.onerror = (error) => { + console.error('파일을 읽는 중 오류가 발생했습니다:', error) + } reader.readAsDataURL(file) + } else { + console.log('선택된 파일이 없습니다') } } @@ -59,34 +80,31 @@ export default function ProfilePictureUpload() { return '' } - const maxSize = Math.max(image.width, image.height) - const safeArea = 2 * ((maxSize / 2) * Math.sqrt(2)) + const { width, height, x, y } = pixelCrop - canvas.width = safeArea - canvas.height = safeArea + // 캔버스 크기를 크롭할 영역으로 설정 + canvas.width = width + canvas.height = height - ctx.translate(safeArea / 2, safeArea / 2) + // 캔버스 중심으로 이동 + ctx.translate(width / 2, height / 2) ctx.rotate((rotation * Math.PI) / 180) - ctx.translate(-safeArea / 2, -safeArea / 2) + ctx.translate(-width / 2, -height / 2) + + // 원형 클리핑 경로 설정 + ctx.beginPath() + ctx.arc(width / 2, height / 2, Math.min(width, height) / 2, 0, 2 * Math.PI) + ctx.closePath() + ctx.clip() + // 이미지를 캔버스에 그림 ctx.drawImage( image, - safeArea / 2 - image.width * 0.5, - safeArea / 2 - image.height * 0.5 - ) - - const data = ctx.getImageData(0, 0, safeArea, safeArea) - - canvas.width = pixelCrop.width - canvas.height = pixelCrop.height - - ctx.putImageData( - data, - 0 - safeArea / 2 + image.width * 0.5 - pixelCrop.x, - 0 - safeArea / 2 + image.height * 0.5 - pixelCrop.y + x, y, width, height, + 0, 0, width, height ) - return canvas.toDataURL('image/jpeg') + return canvas.toDataURL('image/png') } const handleCrop = useCallback(async () => { @@ -104,7 +122,6 @@ export default function ProfilePictureUpload() { return (
-
@@ -205,6 +222,7 @@ export default function ProfilePictureUpload() { )} + heic, heif 등 아이폰 전용 이미지는 Safari 브라우저에서만 보일 수 있습니다.
diff --git a/src/app/form/page.tsx b/src/app/form/page.tsx index b80dc2e..efe3675 100644 --- a/src/app/form/page.tsx +++ b/src/app/form/page.tsx @@ -25,10 +25,10 @@ const DisplayCroppedImage = ({ setFormData }: { setFormData: React.Dispatch +
{croppedImage && (
- Cropped + Cropped
)}
@@ -84,9 +84,9 @@ const FormPage: React.FC = () => { return (
-
-
-
+
+ +
@@ -102,7 +102,7 @@ const FormPage: React.FC = () => { name="name" value={formData.name} onChange={handleChange} - className="p-2 rounded-md bg-zinc-800 border-zinc-700 text-zinc-100" + className="w-full p-2 rounded-md bg-zinc-800 border-zinc-700 text-zinc-100" />
@@ -112,7 +112,7 @@ const FormPage: React.FC = () => { name="role" value={formData.role} onChange={handleChange} - className="p-2 rounded-md bg-zinc-800 border-zinc-700 text-zinc-100" + className="w-full p-2 rounded-md bg-zinc-800 border-zinc-700 text-zinc-100" />
@@ -122,7 +122,7 @@ const FormPage: React.FC = () => { name="company" value={formData.company} onChange={handleChange} - className="p-2 rounded-md bg-zinc-800 border-zinc-700 text-zinc-100" + className="w-full p-2 rounded-md bg-zinc-800 border-zinc-700 text-zinc-100" />
@@ -132,7 +132,7 @@ const FormPage: React.FC = () => { name="joinDate" value={formData.joinDate} onChange={handleChange} - className="p-2 rounded-md bg-zinc-800 border-zinc-700 text-zinc-100" + className="w-full p-2 rounded-md bg-zinc-800 border-zinc-700 text-zinc-100" />
@@ -142,12 +142,12 @@ const FormPage: React.FC = () => { name="code" value={formData.code} onChange={handleChange} - className="p-2 rounded-md bg-zinc-800 border-zinc-700 text-zinc-100" + className="w-full p-2 rounded-md bg-zinc-800 border-zinc-700 text-zinc-100" />