diff --git a/src/views/SellerDashboard/BrandProfile/image-clip-dialog.vue b/src/views/SellerDashboard/BrandProfile/image-clip-dialog.vue index 9b46fd55..66c83d64 100644 --- a/src/views/SellerDashboard/BrandProfile/image-clip-dialog.vue +++ b/src/views/SellerDashboard/BrandProfile/image-clip-dialog.vue @@ -28,7 +28,7 @@ ref="imageClipRef" v-bind="$attrs" :ratio="data.ratio" - :fixedBox="type !== 'apparel'" + :fixedBox="data.isProduct ? type !== 'apparel' : false" :url="data.url" :type="type" @change="(v) => (data.preview_url = v)" @@ -47,7 +47,9 @@ Crop Preview - +
+ +
@@ -175,14 +177,21 @@ defineExpose({ display: flex; align-items: center; justify-content: center; + + .crop-wrapper { + width: 100%; + .tips { + text-align: center; + color: #585858; + font-size: 1.4rem; + font-weight: 400; + } + } &.is-product { column-gap: 18.6rem; - } - .tips { - text-align: center; - color: #585858; - font-size: 1.4rem; - font-weight: 400; + .crop-wrapper { + width: initial; + } } > .image-clip { flex: 1; @@ -194,11 +203,13 @@ defineExpose({ > .preview { margin-left: 6rem; width: 28rem; + height: 100%; display: flex; flex-direction: column; - justify-content: center; + justify-content: flex-start; align-items: center; gap: 2.4rem; + min-height: 0; > .title { display: flex; @@ -210,32 +221,42 @@ defineExpose({ font-size: 1.6rem; } } - > img { + > .preview-image { + width: 100%; + flex: 1; + min-height: 0; + display: flex; + align-items: center; + justify-content: center; + } + > .preview-image > img { width: 100%; height: auto; - margin-bottom: 3rem; + max-height: 100%; + } + > .submit { + margin-top: auto; + flex-shrink: 0; } &.is-product { margin-left: 0; - height: 100%; - - justify-content: flex-start; - img { + > .preview-image > img { width: 20.8rem; height: 36.7rem; - margin-bottom: 0; box-shadow: 4px 4px 16px 0px #0000000f; border: 1px solid #ededed; } &.is-cover { - img { + > .preview-image > img { // width: 29.7rem; height: 37.5rem; } } &.is-apparel { - img { + > .preview-image > img { + width: 100%; height: auto; + max-height: 100%; } } } diff --git a/src/views/SellerDashboard/BrandProfile/image-clip.vue b/src/views/SellerDashboard/BrandProfile/image-clip.vue index 501fe17d..f0009b42 100644 --- a/src/views/SellerDashboard/BrandProfile/image-clip.vue +++ b/src/views/SellerDashboard/BrandProfile/image-clip.vue @@ -7,15 +7,13 @@ crossOrigin="Anonymous" :autoCrop="true" :fixedNumber="ratio" - :fixed="type !== 'apparel'" + :fixed="type !== 'apparel' && isProduct" movable centerBox :fixedBox="fixedBox" @realTime="onChange" - v-bind="$attrs" outputType="png" - :autoCropWidth="type === 'cover' ? 297 : 242" - :autoCropHeight="autoCropHeight" + v-bind="bindProps" >
@@ -72,6 +70,17 @@ const autoCropHeight = computed(() => { return height }) +const bindProps = computed(() => { + // :autoCropWidth="isProduct ? undefined : type === 'cover' ? 297 : 242" + // :autoCropHeight="isProduct ? undefined : autoCropHeight" + if (props.isProduct) { + return { + autoCropHeight: autoCropHeight.value, + autoCropWidth: props.type === "cover" ? 297 : 242 + } + } +}) + const onChange = (data) => { if (attrs.onChange) { getCropUrl().then((url) => attrs.onChange(url)) @@ -95,8 +104,7 @@ const createCropLabel = ({ text, top, className }) => { label.textContent = text label.style.top = top label.style.left = className === "label-v" ? "50%" : "0" - label.style.transform = - className === "label-v" ? "translate(-50%, -50%)" : "translateY(-50%)" + label.style.transform = className === "label-v" ? "translate(-50%, -50%)" : "translateY(-50%)" return label } @@ -126,7 +134,6 @@ const injectCropLabel = () => { if (!cropperBox) return false clearCropLabels(cropperBox) - ;(cropLabelMap[props.type] || []).forEach((config) => { cropperBox.appendChild(createCropLabel(config)) }) @@ -273,75 +280,89 @@ defineExpose({ } } - &.is-product { + &.is-product { + .image-clip-body { + width: 45.7rem; + height: 45.7rem; + :deep(.cropper-modal) { + background: transparent; + } + :deep(.vue-cropper .cropper-view-box) { + position: relative; + overflow: visible !important; + /* 原有的蓝色边框(outline)由组件控制,这里不干涉 */ + } + + :deep(.vue-cropper .cropper-view-box::after) { + content: ""; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + pointer-events: none; + z-index: 9; /* 位于图片之上,但在控制点之下 */ + background-image: none; + background-repeat: no-repeat; + } + } + + &[data-crop-type="cover"] { .image-clip-body { - width: 45.7rem; - height: 45.7rem; - :deep(.cropper-modal) { - background: transparent; - } - :deep(.vue-cropper .cropper-view-box) { - position: relative; - overflow: visible !important; - /* 原有的蓝色边框(outline)由组件控制,这里不干涉 */ - } - :deep(.vue-cropper .cropper-view-box::after) { - content: ""; - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - pointer-events: none; - z-index: 9; /* 位于图片之上,但在控制点之下 */ - background-image: none; - background-repeat: no-repeat; + background-image: + linear-gradient(to right, #4ba5ff 50%, transparent 50%), + linear-gradient(to right, #4ba5ff 50%, transparent 50%), + linear-gradient(to right, #4ba5ff 50%, transparent 50%), + linear-gradient(to bottom, #4ba5ff 50%, transparent 50%); + background-repeat: repeat-x, repeat-x, repeat-x, repeat-y; + background-size: + 8px 1px, + 8px 1px, + 8px 1px, + 1px 8px; + background-position: + 0 2.67%, + 0 63.47%, + 0 92.8%, + 50% 0; } } + } - &[data-crop-type="cover"] { - .image-clip-body { - :deep(.vue-cropper .cropper-view-box::after) { - background-image: - linear-gradient(to right, #4ba5ff 50%, transparent 50%), - linear-gradient(to right, #4ba5ff 50%, transparent 50%), - linear-gradient(to right, #4ba5ff 50%, transparent 50%), - linear-gradient(to bottom, #4ba5ff 50%, transparent 50%); - background-repeat: repeat-x, repeat-x, repeat-x, repeat-y; - background-size: 8px 1px, 8px 1px, 8px 1px, 1px 8px; - background-position: 0 2.67%, 0 63.47%, 0 92.8%, 50% 0; - } + &[data-crop-type="mainProductImage"], + &[data-crop-type="sketch"] { + .image-clip-body { + :deep(.vue-cropper .cropper-view-box::after) { + background-image: + linear-gradient(to right, #4ba5ff 50%, transparent 50%), + linear-gradient(to right, #4ba5ff 50%, transparent 50%), + linear-gradient(to bottom, #4ba5ff 50%, transparent 50%); + background-repeat: repeat-x, repeat-x, repeat-y; + background-size: + 8px 1px, + 8px 1px, + 1px 8px; + background-position: + 0 2.67%, + 0 97.6%, + 50% 0; } } + } - &[data-crop-type="mainProductImage"], - &[data-crop-type="sketch"] { - .image-clip-body { - :deep(.vue-cropper .cropper-view-box::after) { - background-image: - linear-gradient(to right, #4ba5ff 50%, transparent 50%), - linear-gradient(to right, #4ba5ff 50%, transparent 50%), - linear-gradient(to bottom, #4ba5ff 50%, transparent 50%); - background-repeat: repeat-x, repeat-x, repeat-y; - background-size: 8px 1px, 8px 1px, 1px 8px; - background-position: 0 2.67%, 0 97.6%, 50% 0; - } - } - } - - &[data-crop-type="apparel"] { - .image-clip-body { - :deep(.vue-cropper .cropper-view-box::after) { - background-image: linear-gradient(to bottom, #4ba5ff 50%, transparent 50%); - background-repeat: repeat-y; - background-size: 1px 8px; - background-position: 50% 0; - } + &[data-crop-type="apparel"] { + .image-clip-body { + :deep(.vue-cropper .cropper-view-box::after) { + background-image: linear-gradient(to bottom, #4ba5ff 50%, transparent 50%); + background-repeat: repeat-y; + background-size: 1px 8px; + background-position: 50% 0; } } } } +}