Compare commits
100 Commits
test
...
17ff1b817d
| Author | SHA1 | Date | |
|---|---|---|---|
| 17ff1b817d | |||
| 6769d8d485 | |||
| 860b3c7bab | |||
| 7d694a4c36 | |||
| cae9e9a430 | |||
| f90f8f6250 | |||
| abb15cb2c7 | |||
| b26837f258 | |||
| f42602886e | |||
| b8373829f0 | |||
| 2769c3c9f0 | |||
| 648d4d3a97 | |||
| 4baf253b7e | |||
| e0c63df2a6 | |||
| 892923becc | |||
| d3ea703204 | |||
| 70298b8f8f | |||
| 9fa9f3e699 | |||
| d82531583c | |||
| 6240a285c2 | |||
| f577ab575e | |||
| 0c3e3fc3fd | |||
| 6886c372aa | |||
| 8dd3dcb770 | |||
| 1a435b6074 | |||
| 492859dae3 | |||
| 18b59b5598 | |||
| 5fcdd7f06d | |||
| 1e149f7e41 | |||
| aca3767a24 | |||
| d51655f15e | |||
| 47dd32939f | |||
| 2e1891ab08 | |||
| 99d70cc8f7 | |||
| 9f1675e82d | |||
| c2838be2ed | |||
| b5c2941c0d | |||
| d5c01d8d23 | |||
| 7118b0649a | |||
| 8f5346581e | |||
| e43f2e30be | |||
| 397fd267e0 | |||
| fe4b88350b | |||
| 537474e162 | |||
| b5abdf3cf5 | |||
| a2e457b5e8 | |||
| 05ddd417cd | |||
| e70426af68 | |||
| 81b33e1322 | |||
| 588fcfbe90 | |||
| ff2c126382 | |||
| 702daca29f | |||
| 8e9008a3c1 | |||
| 5c0c00aad4 | |||
| e0949c6d73 | |||
| 0449bac8d5 | |||
| d412c15c9d | |||
| ed16a6ddad | |||
| f06e2d41e0 | |||
| 7505269db3 | |||
| 15eeb6943d | |||
| 7e7ed46cea | |||
| fd01786649 | |||
| c48c1c2f09 | |||
| 9bcf3a3cdb | |||
| 4c5b987d98 | |||
| f168403048 | |||
| 82ee1584e7 | |||
| 65cb918389 | |||
| 784baf9a2f | |||
| 7a85ac41cc | |||
| 9d4c9437cf | |||
| 68845aeae1 | |||
| bbdca29337 | |||
| c14c041daa | |||
| a515a144eb | |||
| 54a6773905 | |||
| d97087b4e9 | |||
| ddb2449053 | |||
| 8aca07cdf7 | |||
| 0ba845d95a | |||
| 64b1fd5395 | |||
| 639bea70fa | |||
| 6a89ba059b | |||
| ff83041585 | |||
| e660be0bf4 | |||
| 62cdd57069 | |||
| f8346ed5ef | |||
| 9656b9a9d1 | |||
| 97a58266bb | |||
| 8fc0cfa345 | |||
| 22f9c2287d | |||
| 9284f7d5c3 | |||
| e6f27a4529 | |||
| 6a33d1c024 | |||
| 3b83789c15 | |||
| 55f0ab9af3 | |||
| 9b168a6112 | |||
| c47937933e | |||
| 4744fe7d9a |
@@ -290,47 +290,6 @@
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
|
||||
<!-- 이미지 크롭 다이얼로그 (CropperJS) -->
|
||||
<v-dialog
|
||||
v-model="show_crop_dialog"
|
||||
max-width="900px"
|
||||
persistent
|
||||
>
|
||||
<v-card class="cropper-card">
|
||||
<v-card-title>
|
||||
이미지 크롭 (1:1)
|
||||
</v-card-title>
|
||||
<v-card-text class="cropper-card-text">
|
||||
<div class="cropper-canvas-wrap">
|
||||
<img
|
||||
v-if="crop_src"
|
||||
ref="cropperImage"
|
||||
:src="crop_src"
|
||||
alt="crop"
|
||||
class="cropper-dialog-img"
|
||||
>
|
||||
</div>
|
||||
</v-card-text>
|
||||
<v-card-actions v-show="!is_loading">
|
||||
<v-spacer />
|
||||
<v-btn
|
||||
color="blue darken-1"
|
||||
text
|
||||
@click="handleCropCancel"
|
||||
>
|
||||
취소
|
||||
</v-btn>
|
||||
<v-btn
|
||||
color="blue darken-1"
|
||||
text
|
||||
@click="handleCropConfirm"
|
||||
>
|
||||
확인
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
|
||||
<v-dialog
|
||||
v-model="show_delete_confirm_dialog"
|
||||
max-width="400px"
|
||||
@@ -366,7 +325,6 @@
|
||||
<script>
|
||||
import Draggable from "vuedraggable";
|
||||
import debounce from "lodash/debounce";
|
||||
import Cropper from 'cropperjs'
|
||||
|
||||
import * as seriesApi from "@/api/audio_content_series"
|
||||
import * as memberApi from "@/api/member";
|
||||
@@ -385,11 +343,6 @@ export default {
|
||||
is_modify: false,
|
||||
show_write_dialog: false,
|
||||
show_delete_confirm_dialog: false,
|
||||
// 이미지 크롭용 상태
|
||||
show_crop_dialog: false,
|
||||
cropper: null,
|
||||
crop_src: null,
|
||||
selected_file_for_crop: null,
|
||||
selected_banner: {},
|
||||
banner: {type: 'CREATOR', tab_id: 1, lang: 'ko'},
|
||||
banners: [],
|
||||
@@ -433,101 +386,14 @@ export default {
|
||||
},
|
||||
|
||||
methods: {
|
||||
async imageAdd(payload) {
|
||||
imageAdd(payload) {
|
||||
const file = payload;
|
||||
// 파일 해제 시 초기화
|
||||
if (!file) {
|
||||
if (this.banner.thumbnail_image_url) {
|
||||
URL.revokeObjectURL(this.banner.thumbnail_image_url)
|
||||
}
|
||||
this.banner.thumbnail_image = null
|
||||
if (file) {
|
||||
this.banner.thumbnail_image_url = URL.createObjectURL(file)
|
||||
URL.revokeObjectURL(file)
|
||||
} else {
|
||||
this.banner.thumbnail_image_url = null
|
||||
return
|
||||
}
|
||||
|
||||
// CropperJS 다이얼로그 오픈 흐름
|
||||
if (this.crop_src) {
|
||||
URL.revokeObjectURL(this.crop_src)
|
||||
}
|
||||
this.selected_file_for_crop = file
|
||||
this.crop_src = URL.createObjectURL(file)
|
||||
this.show_crop_dialog = true
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.initCropper()
|
||||
})
|
||||
},
|
||||
|
||||
initCropper() {
|
||||
const imageEl = this.$refs.cropperImage
|
||||
if (!imageEl) return
|
||||
// 기존 인스턴스 제거
|
||||
if (this.cropper) {
|
||||
this.cropper.destroy()
|
||||
this.cropper = null
|
||||
}
|
||||
this.cropper = new Cropper(imageEl, {
|
||||
aspectRatio: 1,
|
||||
viewMode: 1,
|
||||
autoCropArea: 1,
|
||||
movable: true,
|
||||
zoomable: true,
|
||||
scalable: false,
|
||||
rotatable: false,
|
||||
responsive: true,
|
||||
background: false,
|
||||
})
|
||||
},
|
||||
|
||||
destroyCropper() {
|
||||
if (this.cropper) {
|
||||
this.cropper.destroy()
|
||||
this.cropper = null
|
||||
}
|
||||
},
|
||||
|
||||
async handleCropConfirm() {
|
||||
if (!this.cropper || !this.selected_file_for_crop) return
|
||||
try {
|
||||
this.is_loading = true
|
||||
const mime = this.selected_file_for_crop.type && /^image\//.test(this.selected_file_for_crop.type)
|
||||
? this.selected_file_for_crop.type
|
||||
: 'image/png'
|
||||
const canvas = this.cropper.getCroppedCanvas()
|
||||
await new Promise((resolve, reject) => {
|
||||
canvas.toBlob((blob) => {
|
||||
if (!blob) return reject(new Error('크롭된 이미지를 생성할 수 없습니다.'))
|
||||
const croppedFile = new File([blob], this.selected_file_for_crop.name || 'image.png', { type: mime })
|
||||
// 기존 미리보기 URL 해제
|
||||
if (this.banner.thumbnail_image_url) {
|
||||
URL.revokeObjectURL(this.banner.thumbnail_image_url)
|
||||
}
|
||||
this.banner.thumbnail_image = croppedFile
|
||||
this.banner.thumbnail_image_url = URL.createObjectURL(croppedFile)
|
||||
resolve()
|
||||
}, mime)
|
||||
})
|
||||
this.show_crop_dialog = false
|
||||
} catch (e) {
|
||||
this.notifyError('이미지 크롭 중 오류가 발생했습니다. 다시 시도해 주세요.')
|
||||
} finally {
|
||||
this.is_loading = false
|
||||
this.cleanupCropDialog()
|
||||
}
|
||||
},
|
||||
|
||||
handleCropCancel() {
|
||||
this.show_crop_dialog = false
|
||||
this.cleanupCropDialog()
|
||||
},
|
||||
|
||||
cleanupCropDialog() {
|
||||
this.destroyCropper()
|
||||
if (this.crop_src) {
|
||||
URL.revokeObjectURL(this.crop_src)
|
||||
this.crop_src = null
|
||||
}
|
||||
this.selected_file_for_crop = null
|
||||
},
|
||||
|
||||
cancel() {
|
||||
@@ -952,30 +818,3 @@ export default {
|
||||
margin-top: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style>
|
||||
/* CropperJS 기본 스타일 */
|
||||
@import '~cropperjs/dist/cropper.css';
|
||||
|
||||
.cropper-card {
|
||||
max-height: 80vh; /* 뷰포트 대비 제한하여 하단 버튼이 항상 보이도록 */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.cropper-card-text {
|
||||
flex: 1;
|
||||
overflow: auto; /* 내부 스크롤로 이미지만 스크롤되게 함 */
|
||||
}
|
||||
|
||||
.cropper-canvas-wrap {
|
||||
width: 100%;
|
||||
height: 60vh; /* 이미지 표시 영역 고정 */
|
||||
}
|
||||
|
||||
.cropper-dialog-img {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user