feat: 시그니처 이미지 등록 시 1:1 크롭 기능을 추가한다
This commit is contained in:
@@ -369,11 +369,50 @@
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</v-row>
|
||||
|
||||
<v-dialog
|
||||
v-model="show_cropper_dialog"
|
||||
max-width="800px"
|
||||
persistent
|
||||
>
|
||||
<v-card>
|
||||
<v-card-title>이미지 크롭 (1:1 비율)</v-card-title>
|
||||
<v-card-text>
|
||||
<div class="cropper-wrapper">
|
||||
<img
|
||||
ref="cropper_image"
|
||||
:src="cropper_image_url"
|
||||
alt="Cropper Image"
|
||||
class="cropper-image"
|
||||
>
|
||||
</div>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-spacer />
|
||||
<v-btn
|
||||
color="grey darken-1"
|
||||
text
|
||||
@click="cancelCropper"
|
||||
>
|
||||
취소
|
||||
</v-btn>
|
||||
<v-btn
|
||||
color="blue darken-1"
|
||||
text
|
||||
@click="cropImage"
|
||||
>
|
||||
크롭 완료
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as api from "@/api/signature";
|
||||
import Cropper from 'cropperjs';
|
||||
import 'cropperjs/dist/cropper.css';
|
||||
|
||||
export default {
|
||||
name: "SignatureManagement",
|
||||
@@ -399,6 +438,10 @@ export default {
|
||||
selected_signature_can: {},
|
||||
sort_type: 'NEWEST',
|
||||
|
||||
show_cropper_dialog: false,
|
||||
cropper_image_url: '',
|
||||
cropper: null,
|
||||
|
||||
headers: [
|
||||
{
|
||||
text: '캔',
|
||||
@@ -450,13 +493,70 @@ export default {
|
||||
imageAdd(payload) {
|
||||
const file = payload;
|
||||
if (file) {
|
||||
this.image_url = URL.createObjectURL(file)
|
||||
URL.revokeObjectURL(file)
|
||||
if (file._isCropped) return;
|
||||
|
||||
if (file.type === 'image/gif') {
|
||||
this.image = file
|
||||
this.image_url = URL.createObjectURL(file)
|
||||
return
|
||||
}
|
||||
|
||||
this.cropper_image_url = URL.createObjectURL(file)
|
||||
this.show_cropper_dialog = true
|
||||
this.$nextTick(() => {
|
||||
if (this.cropper) {
|
||||
this.cropper.destroy()
|
||||
}
|
||||
this.cropper = new Cropper(this.$refs.cropper_image, {
|
||||
aspectRatio: 1,
|
||||
viewMode: 1,
|
||||
})
|
||||
})
|
||||
} else {
|
||||
this.image_url = null
|
||||
this.image = null
|
||||
}
|
||||
},
|
||||
|
||||
cancelCropper() {
|
||||
this.show_cropper_dialog = false
|
||||
if (this.cropper) {
|
||||
this.cropper.destroy()
|
||||
this.cropper = null
|
||||
}
|
||||
this.cropper_image_url = ''
|
||||
this.image = null
|
||||
this.image_url = null
|
||||
},
|
||||
|
||||
cropImage() {
|
||||
const canvas = this.cropper.getCroppedCanvas()
|
||||
let finalCanvas = canvas
|
||||
|
||||
const MAX_WIDTH = 800
|
||||
if (canvas.width > MAX_WIDTH) {
|
||||
const height = MAX_WIDTH
|
||||
const resizeCanvas = document.createElement('canvas')
|
||||
resizeCanvas.width = MAX_WIDTH
|
||||
resizeCanvas.height = height
|
||||
const ctx = resizeCanvas.getContext('2d')
|
||||
ctx.drawImage(canvas, 0, 0, MAX_WIDTH, height)
|
||||
finalCanvas = resizeCanvas
|
||||
}
|
||||
|
||||
finalCanvas.toBlob((blob) => {
|
||||
const file = new File([blob], 'signature_image.png', {type: 'image/png'})
|
||||
file._isCropped = true
|
||||
this.image = file
|
||||
this.image_url = URL.createObjectURL(blob)
|
||||
this.show_cropper_dialog = false
|
||||
if (this.cropper) {
|
||||
this.cropper.destroy()
|
||||
this.cropper = null
|
||||
}
|
||||
}, 'image/png')
|
||||
},
|
||||
|
||||
showWriteDialog() {
|
||||
this.show_write_dialog = true
|
||||
},
|
||||
@@ -713,4 +813,14 @@ export default {
|
||||
font-weight: bold;
|
||||
color: #3bb9f1;
|
||||
}
|
||||
|
||||
.cropper-wrapper {
|
||||
max-height: 500px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.cropper-image {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user