From d2b2874f635910d8968c5d42c20df1d8998f4d12 Mon Sep 17 00:00:00 2001 From: Cloyd Lau <31238760+cloydlau@users.noreply.github.com> Date: Fri, 22 Dec 2023 14:40:18 +0800 Subject: [PATCH] fix(FaImageUpload): the output image does not conform to the crop box when the aspect ratio of crop box does not match the implied aspect ratio by input width and height --- src/components/ImageUpload/ImageEditor.vue | 43 ++++++++++++++++++++-- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/src/components/ImageUpload/ImageEditor.vue b/src/components/ImageUpload/ImageEditor.vue index 7edd22b..6769a56 100644 --- a/src/components/ImageUpload/ImageEditor.vue +++ b/src/components/ImageUpload/ImageEditor.vue @@ -144,7 +144,7 @@ export default { this.initSetting() // 大图会卡,加一个节流 - this.updateCropBox = throttle((arg) => { + this.rotateCropBox = throttle((arg) => { // 可能编辑器已关闭 if (this.cropper) { this.cropper.rotateTo(arg) @@ -155,6 +155,23 @@ export default { trailing: true, }) + this.onCropmove = throttle((e) => { + // 可能编辑器已关闭 + // 拖动裁剪框不执行 + if (this.cropper && !this.isAspectRatioLocked && e.detail.action !== 'all' && this.impliedAspectRatio) { + const { width, height } = this.cropper.getCropBoxData() + const newAspectRatio = width / height + if (newAspectRatio > this.impliedAspectRatio) { + this.inputHeight = Number.parseInt((this.inputWidth / newAspectRatio).toFixed(0)) + } else if (newAspectRatio < this.impliedAspectRatio) { + this.inputWidth = Number.parseInt((this.inputHeight * newAspectRatio).toFixed(0)) + } + } + }, this.Debounce, { + leading: false, + trailing: true, + }) + this.originalSizeLabel = sizeToLabel(this.binary.size) this.cropper.replace(this.localURL) // replace 后触发 initCropBox(参数为 Base64 类型才会触发) @@ -240,6 +257,25 @@ export default { this.loading = false } }, + // 针对没有锁定比例的情况 + updateCropBox() { + if (this.impliedAspectRatio) { + const { width, height, left, top } = this.cropper.getCanvasData() + // 高图 + if (this.impliedAspectRatio > width / height) { + this.cropper.setCropBoxData({ width, left }) + const { height: containerHeight } = this.cropper.getContainerData() + const cropBoxHeight = width / this.impliedAspectRatio + this.cropper.setCropBoxData({ height: cropBoxHeight, top: (containerHeight - cropBoxHeight) / 2 }) + // 扁图 + } else { + this.cropper.setCropBoxData({ height, top }) + const { width: containerWidth } = this.cropper.getContainerData() + const cropBoxWidth = height * this.impliedAspectRatio + this.cropper.setCropBoxData({ width: cropBoxWidth, left: (containerWidth - cropBoxWidth) / 2 }) + } + } + }, onWidthChange() { if (this.isAspectRatioSpecified && this.impliedAspectRatio !== this.specifiedAspectRatio) { this.inputHeight = (this.inputWidth ?? 0) / this.specifiedAspectRatio @@ -262,7 +298,7 @@ export default { }, onIsAspectRatioSpecifiedChange() { this.cropper.setAspectRatio(this.isAspectRatioLocked ? this.impliedAspectRatio : null) - this.initCropBox() + this.updateCropBox() }, onFullscreenChange(v) { this.fullscreen = v @@ -271,7 +307,7 @@ export default { }) }, onRotateDegreeChange(n) { - this.updateCropBox(n) + this.rotateCropBox(n) }, getSizeDiffText(before, after) { const diff = after - before @@ -552,6 +588,7 @@ export default { ref="cropper" :src="localURL" style="display: block; max-width: 100%" + @cropmove="onCropmove" >