Vue 3에서 사용하는 이미지 크롭 도구
Vue 3 프로젝트에서 이미지 크롭 기능을 구현하려면 vue-cropper 라이브러리가 매우 유용합니다. 이 라이브러리는 직관적인 인터페이스와 다양한 기능을 제공합니다.
설치 방법
npm install vue-cropper@next
기본 사용법
컴포넌트 임포트
import 'vue-cropper/dist/index.css'
import { VueCropper } from 'vue-cropper'
템플릿 구조
<template>
<div class="cropper-container">
<vue-cropper
ref="cropperRef"
:img="cropOption.sourceImage"
:outputSize="cropOption.quality"
:outputType="cropOption.format"
autoCrop
:centerBox="true"
:canMove="true"
@realTime="handlePreview"
/>
<div class="preview-section">
<img :src="previewData.url" :style="previewData.img" />
</div>
<div class="controls">
<input type="file" @change="handleFileSelect" accept="image/*" />
<button @click="zoomIn">확대</button>
<button @click="zoomOut">축소</button>
<button @click="rotateLeft">좌회전</button>
<button @click="rotateRight">우회전</button>
<button @click="handleUpload" :disabled="isUploading">
{{ isUploading ? '업로드 중...' : '업로드' }}
</button>
</div>
</div>
</template>
스크립트 구현
<script setup>
import { ref, reactive } from 'vue'
import 'vue-cropper/dist/index.css'
import { VueCropper } from 'vue-cropper'
import axios from 'axios'
// 크롭 옵션 설정
const cropOption = reactive({
sourceImage: '',
quality: 1,
format: 'png'
})
// 컴포넌트 참조
const cropperRef = ref(null)
const isUploading = ref(false)
const previewData = ref({ url: '', img: {} })
// 실시간 미리보기 처리
const handlePreview = (data) => {
previewData.value = {
url: data.url,
img: data.img,
div: data.div
}
}
// 파일 선택 처리
const handleFileSelect = (event) => {
const file = event.target.files[0]
if (!file) return
const validTypes = ['image/jpeg', 'image/png', 'image/gif']
if (!validTypes.includes(file.type)) {
alert('지원하는 이미지 형식: jpeg, png, gif')
return
}
const reader = new FileReader()
reader.onload = (e) => {
cropOption.sourceImage = e.target.result
}
reader.readAsDataURL(file)
}
// 확대/축소 기능
const zoomIn = () => cropperRef.value?.changeScale(1)
const zoomTo = (ratio) => cropperRef.value?.changeScale(ratio)
// 회전 기능
const rotateLeft = () => cropperRef.value?.rotateLeft()
const rotateRight = () => cropperRef.value?.rotateRight()
// 이미지 업로드
const handleUpload = () => {
if (!cropperRef.value) return
isUploading.value = true
cropperRef.value.getCropBlob(async (blob) => {
const formData = new FormData()
formData.append('image', blob, `image.${cropOption.format}`)
try {
const response = await axios.post('/api/upload', formData, {
headers: { 'Content-Type': 'multipart/form-data' }
})
if (response.data.code === 200) {
alert('이미지 업로드 성공')
}
} catch (error) {
alert('업로드 실패: ' + error.message)
} finally {
isUploading.value = false
}
})
}
</script>
스타일 정의
<style scoped>
.cropper-container {
width: 100%;
max-width: 600px;
margin: 0 auto;
}
.preview-section {
margin-top: 20px;
border: 1px solid #ddd;
min-height: 200px;
}
.controls {
display: flex;
gap: 10px;
margin-top: 15px;
flex-wrap: wrap;
}
.controls button {
padding: 8px 16px;
border: none;
border-radius: 4px;
background-color: #409eff;
color: white;
cursor: pointer;
}
.controls button:disabled {
background-color: #ccc;
cursor: not-allowed;
}
.controls input[type="file"] {
margin-right: 10px;
}
</style>
주요 옵션 설명
| 속성 | 설명 | 기본값 |
|---|---|---|
| img | 크롭할 이미지 URL | - |
| outputSize | 출력 이미지 품질 (0.1 ~ 1) | 1 |
| outputType | 출력 포맷 (jpeg, png, webp) | png |
| autoCrop | 자동 크롭 영역 생성 | false |
| centerBox | 크롭 박스를 이미지에 맞춤 | false |
| canMove | 이미지 이동 가능 여부 | true |
| fixed | 크롭 박스 비율 고정 | false |
사용 시 주의사항
- 로컬 mock 서버가 실행 중이면 이미지 변환 시 오류가 발생할 수 있으므로 종료 후 사용하세요
- 반드시 외層 컨테이너를 만들고 크기를 설정해야 합니다
- 마우스 휠로 이미지 확대/축소 가능
- 크롭 영역 테두리를 드래그하여 크기 조절 가능
vue-cropper는 Vue 3 환경에서 이미지 크롭 기능을 쉽게 구현할 수 있도록 도와주는 강력한 도구입니다. 위에 설명된 기본 사용법과 옵션들을 활용하면 다양한 요구사항에 맞는 이미지 크롭 기능을 구현할 수 있습니다.