Skip to content

Commit

Permalink
fix UI: crop image; width full
Browse files Browse the repository at this point in the history
  • Loading branch information
jongwony committed Oct 17, 2024
1 parent b673e49 commit df9510f
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 34 deletions.
64 changes: 41 additions & 23 deletions src/app/form/Profile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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('선택된 파일이 없습니다')
}
}

Expand Down Expand Up @@ -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 () => {
Expand All @@ -104,7 +122,6 @@ export default function ProfilePictureUpload() {

return (
<div className="space-y-2">
<label htmlFor="primaryField" className="m-2 text-sm font-medium">사진</label>
<button
type="button"
onClick={() => setIsOpen(true)}
Expand Down Expand Up @@ -145,7 +162,7 @@ export default function ProfilePictureUpload() {
type="file"
ref={fileInputRef}
onChange={handleFileChange}
accept="image/*"
accept="image/jpeg,image/png,image/heic,image/heif,image/webp"
className="hidden"
/>
</div>
Expand Down Expand Up @@ -205,6 +222,7 @@ export default function ProfilePictureUpload() {
</div>
</div>
)}
<small>heic, heif 등 아이폰 전용 이미지는 Safari 브라우저에서만 보일 수 있습니다.</small>
</div>

<div className="flex justify-end p-4 border-t">
Expand Down
22 changes: 11 additions & 11 deletions src/app/form/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ const DisplayCroppedImage = ({ setFormData }: { setFormData: React.Dispatch<Reac
}, [croppedImage]);

return (
<div>
<div className="relative justify-center items-center w-full h-full">
{croppedImage && (
<div>
<Image src={croppedImage} alt="Cropped" width={180} height={180} className="rounded-full" />
<Image src={croppedImage} alt="Cropped" width={180} height={180} className="relative"/>
</div>
)}
</div>
Expand Down Expand Up @@ -84,9 +84,9 @@ const FormPage: React.FC = () => {

return (
<div className="flex min-h-screen bg-zinc-900 text-zinc-100">
<div className="flex-1 flex items-center justify-center">
<form onSubmit={sendFormData}>
<div className="w-full max-w-md justify-between space-y-4">
<div className="flex-1 flex items-center justify-center p-4">
<form onSubmit={sendFormData} className="w-full max-w-md">
<div className="space-y-4">
<button type="button" onClick={() => router.back()}>
<ChevronLeft />
</button>
Expand All @@ -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"
/>
</div>
<div className="space-y-2">
Expand All @@ -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"
/>
</div>
<div className="space-y-2">
Expand All @@ -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"
/>
</div>
<div className="space-y-2">
Expand All @@ -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"
/>
</div>
<div className="space-y-2">
Expand All @@ -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"
/>
</div>
<div className="flex justify-between">
<button
className="px-4 py-2 text-white bg-blue-500 rounded-md hover:bg-blue-600 transition-colors"
className="mt-2 px-4 py-2 text-white bg-blue-500 rounded-md hover:bg-blue-600 transition-colors"
type="submit"
>
결정
Expand Down

0 comments on commit df9510f

Please sign in to comment.