布局修改 部分bug修复

This commit is contained in:
X1627315083
2025-08-22 10:27:48 +08:00
parent 141821a843
commit 594bf5ce0a
275 changed files with 5675 additions and 13049 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,720 +0,0 @@
<template>
<div class="detail_modal_body_result">
<div v-show="type_ == 1" class="result_apparel_print">
<div class="upload_title result_apparel" v-show="type_ == 1">
<i class="color_edit fi fi-bs-comments"></i>
<span>{{ $t('DesignDetailEnd.NewApparel') }}</span>
</div>
<div class="result_apparel_print_img">
<img v-show="type_==1" class="result_appare_img" :src="sketchImg?.path?sketchImg?.path:current?.path" :title="current?.type">
<!-- <div v-show="type_==2" class="result_print_img" @click="setPrint" :title="current?.type">
<img v-for="item in current?.layersObject" :src="item.imageUrl" alt="">
</div> -->
</div>
</div>
<div v-show="type_ == 2" class="result_apparel_elements">
<div class="upload_title result_apparel">
<i class="color_edit fi fi-bs-comments"></i>
<span>{{ $t('DesignDetailEnd.NewPrint') }}</span>
</div>
<div class="modal_img">
<div class="modal_img_item" v-for="item,index in exhibitionList.print" :key="item" >
<!-- <div class="modal_img_item" v-for="item,index in current.printObject.prints" :key="item" > -->
<img v-lazy="item.path" alt="">
<sketchCategory :disignTypeList="designTypeList" :generateList="exhibitionList.print" :item="item" :isSpread="true" :isSetSketchCategory="true"></sketchCategory>
<!-- <div
class="delete_file_block"
@click="deleteSelectptints(item,index)"
>
<span class="icon iconfont icon-shanchu"></span>
</div> -->
</div>
<div class="modal_img_item" v-for="item,index in printsList" :key="item" >
<img v-lazy="item.path" alt="">
<sketchCategory :disignTypeList="designTypeList" :generateList="printsList" :item="item" :isSpread="true" :isSetSketchCategory="true"></sketchCategory>
<div
class="delete_file_block"
@click="deleteptints(item,index)"
>
<span class="icon iconfont icon-shanchu"></span>
</div>
</div>
</div>
</div>
<div v-show="type_ == 3">
<div class="result_color upload_title">
<i class="color_edit fi fi-bs-comments"></i>
<span>{{ $t('DesignDetailEnd.NewColor') }}</span>
</div>
<div class="modal_img">
<div class="modal_img_item" v-for="color,index in colorList" :key="color" >
<div :title="color?.name?color?.name:''" @click="selectColorItem(index,color)" @dblclick="setSelectColorItem(color)" :class="['upload_color',selectIndex === index ? 'select_upload_color' : '',]" :style="{background:`rgba(${color?.r},${color?.g},${color?.b},${color?.a})`}">
<div v-if="!color?.gradient" class="color_content" :style="{'background-color':`rgba(${color.rgba?.r},${color.rgba?.g},${color.rgba?.b},${color.rgba?.a})`}">
</div>
<div class="color_content" v-else :style="{height:'100%','background-image':color?.gradient?`linear-gradient(${color?.gradient.angle}deg,${setGradient(color?.gradient)}`:'none'}"></div>
<div v-if="!color?.gradient" class="color_content_body" :style="{'text-align':color?.name?'left':'center'}">
<div class="color_des">{{color.tcx}}</div>
<div class="color_des">{{ color.name }}</div>
</div>
</div>
</div>
</div>
</div>
<div v-show="type_ == 4" class="result_apparel_elements">
<div class="upload_title result_apparel">
<i class="color_edit fi fi-bs-comments"></i>
<span>New Elements</span>
</div>
<div class="modal_img">
<!-- <div class="modal_img_item" v-for="item,index in current.trims.prints" :key="item" > -->
<div class="modal_img_item" v-for="item,index in exhibitionList.elements" :key="item" >
<img v-lazy="item.path" alt="">
<div
class="delete_file_block"
@click="deleteSelectElements(item,index)"
>
<span class="icon iconfont icon-shanchu"></span>
</div>
</div>
<div class="modal_img_item" v-for="item,index in elementsList" :key="item" >
<img v-lazy="item.url" alt="">
<div
class="delete_file_block"
@click="deleteElements(item,index)"
>
<span class="icon iconfont icon-shanchu"></span>
</div>
</div>
</div>
</div>
<div v-show="type_ == 1 || type_ == 3" @click.stop="setPreview" class="subitOkPreviewBtn" :class="[ !sketchImg?.id?!current?.id?'active':'':'' ]">{{ $t('DesignDetailEnd.preview') }}</div>
<div v-if="type_ == 2 && (current?.printObject?.prints?.length != 0 || exhibitionList.print.length != 0)" @click.stop="setPreview('clearPrint')" class="subitOkPreviewBtn clear">{{ $t('Habit.Clear') }}</div>
<div v-if="type_ == 2 && (current?.printObject?.prints?.length != 0 || printsList.length != 0 || exhibitionList.print.length != 0)" @click.stop="setPrint" class="subitOkPreviewBtn Guide_1_23">{{ $t('DesignDetailEnd.Layout') }}</div>
<!-- <div v-else-if="type_ == 2 && designItemDetail?.clothes?.[currentIndex]?.printObject?.prints?.[0]?.path != null && current?.printObject?.prints?.[0]?.path == null" @click.stop="setPreview" class="subitOkPreviewBtn">{{ $t('DesignDetailEnd.preview') }}</div> -->
<div v-if="type_ == 4 && (elementsList.length != 0 || exhibitionList.elements.length != 0)" @click.stop="setElemets" class="subitOkPreviewBtn">{{ $t('DesignDetailEnd.Layout') }}</div>
<DesignPrintOperation ref="DesignPrintOperation"></DesignPrintOperation>
<DesignElementsOperation ref="DesignElementsOperation"></DesignElementsOperation>
</div>
<div class="mark_loading" v-show="loadingShow">
<a-spin size="large" />
</div>
</template>
<script>
import { defineComponent,computed,ref, nextTick,h ,inject} from 'vue'
import Draggable from 'vuedraggable'
import { Https } from "@/tool/https";
import { useStore } from "vuex";
import { Sketch} from '@ans1998/vue3-color'
import DesignPrintOperation from './DesignPrintOperation.vue';
import DesignElementsOperation from './DesignElements.vue';
import { message,Upload} from 'ant-design-vue';
import { openGuide,driverObj__ } from "@/tool/guide";
import {isMoible,setGradual} from '@/tool/util'
import { useI18n } from 'vue-i18n';
import sketchCategory from "@/component/HomePage/sketchCategory.vue";
export default defineComponent({
props: ["msg"],
components:{
Draggable,Sketch,DesignPrintOperation,
DesignElementsOperation,sketchCategory
},
setup(prop) {
const store = useStore();
let type_ = ref(0);
let current = inject('current')//父组件传过来的数据
let setRevocation = inject('setRevocation')//父组件传过来的数据
let sketchImg = ref({})
let driver__ = inject('driver__')//父组件传过来的数据
let moible = inject('moible')//父组件传过来的数据
let designItemDetail = inject('designItemDetail')//父组件传过来的数据
let currentIndex = inject('currentIndex')//父组件传过来的数据
let designTypeList = inject('designTypeList')//父组件传过来的数据
let previewShow = ref(false)
//印花
//颜色
// let colorList = ref([{}])
// let colorList = ref([{},{},{},{},{},{},{},{},{}])
let colorList = inject('colorList')//父组件传过来的数据
let selectIndex = inject('selectIndex')//父组件传过来的数据
//加载中
let loadingShow = ref(false)
let exhibitionList = inject('exhibitionList')
let {t} = useI18n()
let printsList = ref([])
let elementsList = ref([
])
return{
store,
current,
setRevocation,
sketchImg,
driver__,
moible,
designItemDetail,
currentIndex,
designTypeList,
previewShow,
type_,
colorList,
selectIndex,
loadingShow,
exhibitionList,
t,
printsList,
elementsList,
}
},
data(){
return{
//颜色
getRGBA:{},
selectColor:{},
}
},
computed:{
setGradient(){
return (gradient)=>{
let gradientStr = ''
gradient.gradientList.sort((a, b) => {
let aArr = a.left.split('%')[0]
let bArr = b.left.split('%')[0]
return aArr - bArr;
});
gradient.gradientList.forEach((item,index)=>{
let str = ','
if(gradient.gradientList.length == index+1)str = ''
gradientStr += `rgba(${item.rgba.r},${item.rgba.g},${item.rgba.b},${item.rgba.a}) ${item.left}${str}`
})
return `${gradientStr}`
}
}
},
watch: {
'exhibitionList.print':{
handler(newVal,oldVal){
this.printsList = this.printsList.filter(objA => {
return !newVal.some(objB => objB.minIOPath === objA.minIOPath);
});
this.setExhibitionType('print')
}
},
'exhibitionList.elements':{
handler(newVal,oldVal){
this.elementsList = this.elementsList.filter(objA => {
return !newVal.some(objB => objB.minIOPath === objA.minIOPath);
});
this.setExhibitionType('elements')
}
}
},
methods:{
//点击判断
init(num){
// this.current = JSON.parse(JSON.stringify(this.currentItem))
this.type_ = num
this.colorList[this.selectIndex] = this.$parent.selectColor
if(num == 2){
this.setExhibitionType('print')
}else if(num == 4){
this.setExhibitionType('elements')
}
},
clearModal(){
this.elementsList = []
this.printsList = []
},
//模型
setSketchImg(v){
this.sketchImg.id_ = v.id
this.sketchImg.id = v.id
this.sketchImg.path = v.url
this.sketchImg.minIOPath = v.minIOPath
this.sketchImg.type = v.level2Type
this.sketchImg.designType = v.designType
},
//印花
setExhibitionType(str){
this.exhibitionList[str].forEach((item,index)=>{
if(!item.categoryValue){
this.designTypeList.forEach((typeItem)=>{
if(item.level2Type == typeItem.value){
item.categoryValue = typeItem.value
item.category = typeItem.name
}
})
}
})
},
setPrint(){
// if(this.current?.printObject?.prints?.[0]?.path){
let DesignPrintOperation = this.$refs.DesignPrintOperation
DesignPrintOperation.init()
if(this.driver__.driver){
nextTick().then(()=>{
driverObj__.moveNext();
})
}
// }else{
// message.info(this.t('DesignDetailEnd.jsContent1'));
// }
},
deleteFile(){
this.current.printObject = {}
},
//颜色
selectColorItem(index,color){
this.selectIndex = index
// if(this.$parent.selectColor?.rgba?.r == color?.rgba?.r && this.$parent.selectColor.rgba.g == color?.rgba?.g && this.$parent.selectColor.rgba.b == color?.rgba?.b){
// return
// }
if(color.rgba?.r){
this.$parent.selectColor = color
}else{
this.$parent.selectColor.isClick = {}
}
//判断是否对一个颜色重复点击
// this.$parent.selectColor.tcxColor = ''
// this.$parent.selectColor.pantongName = ''
},
setSelectColorItem(color){
let designItemDetail = this.store.state.DesignDetailModule.designItemDetail
let string = `${color.rgba.r},${color.rgba.g},${color.rgba.b}`
this.current.color = string
designItemDetail.clothes.forEach((element,index) => {
if(element.id == this.current.id){
designItemDetail.clothes[index] = this.current
}
});
},
hasDuplicateId(arr) {
const set = new Set();
for (let i = 0; i < arr.length; i++) {
const id = arr[i].id;
if (set.has(id)) {
return true;
}
set.add(id);
}
return false;
},
soleId(arr,index){
let randomNum = Math.floor(100 + Math.random() * 900);
// if(this.sketchImg.id_){
if(this.sketchImg.id){
if(this.sketchImg.id == this.sketchImg.id_){
arr[index].id = Number(this.sketchImg.id_+(randomNum+""))
arr[index].changed = true
if(this.hasDuplicateId(arr)){
this.sketchImg.id_ = this.sketchImg.id
this.soleId(arr,index)
}
}else{
arr[index].id = this.sketchImg.id_
}
}else{
arr[index].id = this.current.id
}
// arr[index].id = this.sketchImg.id_? this.sketchImg.id_:this.current.id
return arr
},
deleteptints(item,index){
this.printsList.splice(index,1)
},
deleteSelectptints(item,index){
this.exhibitionList.print.splice(index,1)
},
deleteElements(item,index){
this.elementsList.splice(index,1)
},
deleteSelectElements(item,index){
this.exhibitionList.elements.splice(index,1)
},
setElemets(){
if(this.current.trims.prints && this.current.trims.prints.length == 0 && this.elementsList.length == 0)return message.info('请选择至少一张element')
let DesignElementsOperation = this.$refs.DesignElementsOperation
DesignElementsOperation.init()
},
//提交
async setPreview(str){
let designItemDetail = JSON.parse(JSON.stringify(this.store.state.DesignDetailModule.designItemDetail))
let index
let data = JSON.parse(JSON.stringify(this.store.state.DesignDetailModule.designPreviewData))
// let bor = false
let zIndex = 10
designItemDetail.clothes.forEach((v,ind)=>{
if(v.id == this.current.id){
index = ind
// bor = true
}
if(v.priority){
if(zIndex < v.priority){
zIndex = v.priority
}
}
})
index = index? index:0
if(!this.current.id){
if(index && data?.designSingleItemDTOList){
data.designSingleItemDTOList[index].priority = zIndex+=1
}
}
if(this.type_ == 1){
if(data.designSingleItemDTOList[index].path != this.sketchImg.minIOPath && this.sketchImg.id_){
data.designSingleItemDTOList[index].offset = [0,0]
data.designSingleItemDTOList[index].scale = [1,1]
}
data.designSingleItemDTOList = this.soleId(data.designSingleItemDTOList,index)
this.sketchImg.id_ = data.designSingleItemDTOList[index].id
data.designSingleItemDTOList[index].path =this.sketchImg.minIOPath? this.sketchImg.minIOPath: this.current.minIOPath
data.designSingleItemDTOList[index].type =this.sketchImg.type? this.sketchImg.type: this.current.type
}else if(this.type_ == 2){
if(str == 'clearPrint'){
data.designSingleItemDTOList[index].printObject.prints = []
}
}else if(this.type_ == 3){
if(this.colorList[this.selectIndex]?.rgba?.r == undefined){
message.info(this.t('DesignDetailEnd.jsContent2'))
return
}
let color = `${this.colorList[this.selectIndex].rgba.r} ${this.colorList[this.selectIndex].rgba.g} ${this.colorList[this.selectIndex].rgba.b}`
data.designSingleItemDTOList[index].color = color
}else if(this.type_ == 4){
data.designSingleItemDTOList[index].trims = this.current.trims
}
if(this.colorList[this.selectIndex].gradient){
let gradient = this.colorList[this.selectIndex].gradient
gradient.colorImg = await setGradual(gradient,320,700)
data.designSingleItemDTOList[index].gradient = gradient
}else{
delete data.designSingleItemDTOList[index].gradient
}
data.designSingleItemDTOList[index].designType = this.sketchImg.designType?this.sketchImg.designType:this.current.designType
data.timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone
this.loadingShow = true
Https.axiosPost(Https.httpUrls.designSingle, data).then(
(rv) => {
let bor = false
rv.clothes.forEach((item)=>{
if(item.type != 'body'){
if(item.id == designItemDetail.clothes[index].id || item.id == this.sketchImg.id_){
designItemDetail.clothes[index].color = item.color
if(item.gradient){
designItemDetail.clothes[index].gradient = item.gradient
}else{
delete designItemDetail.clothes[index].gradient
}
designItemDetail.clothes[index].designType = item.designType
designItemDetail.clothes[index].trims = item.trims
designItemDetail.clothes[index].layersObject = item.layersObject
designItemDetail.clothes[index].minIOPath = item.minIOPath
designItemDetail.clothes[index].path = item.path
designItemDetail.clothes[index].id = item.id
designItemDetail.clothes[index].changed = item.changed?item.changed:false
designItemDetail.clothes[index].type = item.type
designItemDetail.clothes[index].printObject = item.printObject
designItemDetail.clothes[index].undividedLayer = item?.undividedLayer
bor = true
}else{
}
if(!this.current.id ){
designItemDetail.clothes[index].priority = zIndex
}
}
})
designItemDetail.currentFullBodyView = rv.currentFullBodyView
designItemDetail.ifSubmit = true
designItemDetail.clothes.forEach((item,index)=>{
let a
if(item.layersObject[0].imageCategory.indexOf("back") == -1){
a = item.layersObject[0]
item.layersObject[0] = item.layersObject[1]
item.layersObject[1] = a
}
item.layersObject[0].id = designItemDetail.clothes[index].layersObject[0].id
item.layersObject[1].id = designItemDetail.clothes[index].layersObject[1].id
})
this.loadingShow = false
this.store.commit("setDesignItemDetail", designItemDetail);
this.store.commit("setDesignPreviewData", data);
this.setRevocation(designItemDetail,data)
}
).catch(res=>{
this.loadingShow = false
});
}
}
})
</script>
<style lang="less" scoped>
.detail_modal_body_result{
width: 26%;
position: relative;
i{
font-size: var(--aida-fsize1-8);
display: flex;
align-items: center;
}
.upload_title{
display: flex;
margin-bottom: calc(1rem*1.2);
margin-top: calc(1rem*1.2);
&.upload_title:nth-child(1){
margin-top: 0;
}
span{
margin-left: calc(1rem*1.2);
font-size: var(--aida-fsize1-8);
color: #000000;
}
}
//模型和印花
.result_apparel_print{
height: 100%;
display: flex;
flex-direction: column;
.result_apparel_print_img{
position: relative;
flex: 1;
text-align: center;
img{
max-width: 100%;
max-height: 100%;
width: auto;
height: auto;
max-height: calc(35rem*1.2);
margin-top: calc(2rem*1.2);
width: 100%;
object-fit: contain;
}
.result_print_img{
transform: scale(.85);
transform-origin: center top;
cursor: pointer;
img:nth-child(1){
position: absolute;
}
}
}
}
//印花
.result_print{
display: flex;
justify-content: space-between;
height: calc(14rem*1.2);
>div{
display: flex;
flex-direction: column;
.print_left,.print_right{
display: flex;
flex: 1;
align-items: center;
align-items: flex-start;
}
}
.print_left{
position: relative;
img{
width: auto;
height: calc(8rem*1.2);
margin: auto;
display: block;
}
.delete_file_block{
display: none;
width: calc(3.2rem*1.2);
height: calc(3.2rem*1.2);
background: rgba(0,0,0,0.6);
border-radius: calc(0.4rem*1.2);
position: absolute;
top: calc(0.9rem*1.2);
right: calc(0.9rem*1.2);
text-align: center;
line-height: calc(3.2rem*1.2);
left: auto;
.icon-shanchu{
font-size: calc(1.6rem*1.2);
color: #fff;
}
}
&:hover .delete_file_block{
display: block;
}
}
.print_right{
.habit_Overal_Single {
display: flex;
align-items: center;
justify-content: center;
// margin: 2rem*1.2) 0;
transform: scale(.8);
// margin: 3rem*1.2) 0;
.habit_Overal_Single_text {
font-weight: 600;
color: rgba(0, 0, 0, 0.5);
&.active {
color: rgba(0, 0, 0, 0.7);
// font-weight: 900;
transform: scale(1.2);
}
}
:deep(.ant-switch) {
margin: 0 calc(1rem*1.2);
background-color: #efefef;
}
:deep(.ant-switch-checked) {
background-color: #000;
}
}
.habit_System_Designer {
margin-top: calc(4rem*1.2);
transform: scale(.8);
:deep(.ant-slider-track),
:deep(.ant-slider-rail) {
height: calc(.6rem*1.2);
background-color: #e1e1e1;
border-radius: calc(0.5rem*1.2);
}
:deep(.ant-slider .ant-slider-handle:not(.ant-tooltip-open)),
:deep(.ant-slider-handle) {
background-color: #2d2e76 !important;
border: none !important;
}
:deep(.ant-slider-handle:hover) {
box-shadow: 0 0 0 5px rgba(45, 46, 118, 0.2);
}
}
}
}
//颜色
.modal_img{
width: 100%;
overflow-x: hidden;
display: flex;
flex-wrap: wrap;
padding-left: calc(2rem*1.2);
align-content: flex-start;
&.modal_img::-webkit-scrollbar {
display: none;
}
.modal_img_item{
margin: 0 calc(1rem*1.2) calc(1rem*1.2) 0;
position: relative;
// cursor: pointer;
border: calc(0.1rem*1.2) solid #DCDCEC;
//放8个
height: calc(8.5rem*1.2);
width: calc(7rem*1.2);
// height: 32rem*1.2);
// width: 25rem*1.2);
overflow: hidden;
@media screen and (max-width: 1440px) {
&.modal_img_item {
line-height: 1.2;
}
}
box-sizing: border-box;
.color_content{
width: 100%;
//放8个
height: calc(4rem*1.2);
// height: 25rem*1.2);
}
.color_content_body{
.color_des{
// font-size: 1.8rem*1.2);
font-weight: 600;
white-space: nowrap;
width: 100%;
overflow: hidden;
text-overflow:ellipsis;
}
}
.select_upload_color{
border: calc(0.1rem*1.2) solid #000;
}
.upload_color{
width: 100%;
height: 100%;
}
}
}
//elements
.result_apparel_elements{
height: 85%;
// height: 100%;
.modal_img{
height: calc(100%);
overflow-y: auto;
}
.modal_img_item{
display: flex;
justify-content: center;
align-items: center;
position: relative;
// height: auto;
border: none;
img{
width: 100%;
object-fit: contain;
}
.delete_file_block{
display: none;
width: calc(3.2rem*1.2);
height: calc(3.2rem*1.2);
background: rgba(0,0,0,0.6);
border-radius: calc(0.4rem*1.2);
position: absolute;
top: calc(0.9rem*1.2);
right: calc(0.9rem*1.2);
text-align: center;
line-height: calc(3.2rem*1.2);
left: auto;
cursor: pointer;
.icon-shanchu{
font-size: calc(1.6rem*1.2);
color: #fff;
}
}
&:hover .delete_file_block{
display: block;
}
}
}
.subitOkPreviewBtn{
bottom: calc(3rem*1.2);
position: absolute;
&.clear{
bottom: calc(7rem);
}
&.active{
opacity: .5;
pointer-events:none;
}
}
}
</style>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,117 +0,0 @@
<template>
<a-modal class="hsitory_detail_modal_component"
v-model:visible="hsitoryDetailShow"
:footer="null"
:title="collectionName"
width="80%"
:maskClosable="false"
:keyboard="false"
:centered="true"
>
<template #closeIcon>
<div class="close_icon" @click.stop="changeDetailShow()"><span class="icon iconfont icon-guanbi"></span></div>
</template>
<div class="history_detail_content scroll_style">
<div class="history_img_block" v-for="img in groupDetails" :key="img">
<div class="history_img_item" >
<img class="element_img" :src="img.url">
</div>
</div>
</div>
</a-modal>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
props:{
groupDetails:{
default:{},
},
collectionName:{
default:''
}
},
setup() {
},
data(){
return{
hsitoryDetailShow:false,
}
},
methods:{
changeDetailShow(){
this.hsitoryDetailShow = !this.hsitoryDetailShow
}
}
})
</script>
<style lang="less">
.hsitory_detail_modal_component{
.ant-modal-close{
width: 3.6rem;
height: 3.6rem;
position: absolute;
top: -1.8rem;
right: -1.8rem;
}
.ant-modal-header{
background: #F7F7F7;
}
.ant-modal-body{
background: #F2F3FB;
height: 80vh;
min-height: 72rem;
overflow-y: hidden;
padding: 0;
}
.close_icon{
width: 3.6rem;
height: 3.6rem;
background: #000000;
border-radius: 50%;
line-height: 3.6rem;
text-align: center;
.icon-guanbi{
font-size: 2rem;
color: #ffffff;
}
}
.history_detail_content{
padding: 2.6rem 2.0rem 2.6rem 3.7rem;
height: 100%;
width: 100%;
overflow-y:auto;
background: #FFFFFF;
.history_img_block{
width: 16.5rem;
height: 16.5rem;
border: 0.1rem solid #000;
margin: 0 1.7rem 1.7rem 0;
display: inline-block;
.history_img_item{
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
}
.element_img{
max-width: 100%;
max-height: 100%;
}
}
}
}
</style>

View File

@@ -17,7 +17,7 @@
>
<div class="generalModel_btn">
<div class="generalModel_closeIcon" @click.stop="cancelDsign()">
<svg width="46" height="46" viewBox="0 0 46 46" fill="none" xmlns="http://www.w3.org/2000/svg">
<svg width="100%" height="100%" viewBox="0 0 46 46" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="23" cy="23" r="23" fill="white" fill-opacity="0.3"/>
<rect x="32.5063" y="12" width="3" height="29" rx="1.5" transform="rotate(45 32.5063 12)" fill="#000"/>
<rect x="34.6274" y="32.5059" width="3" height="29" rx="1.5" transform="rotate(135 34.6274 32.5059)" fill="#000"/>

View File

@@ -0,0 +1,468 @@
<template>
<div class="canvasBox">
<!-- designDetailShow -->
<!-- :class="[driver__.driver?'hideEvents':'']" -->
<div class="canvasContent" ref="canvasContent">
<div class="content-bottom" ref="canvasContent">
<div class="contet">
<div class="canvas" v-if="currentView === 'canvasEditor'" @click.stop>
<editCanvas v-if="canvasLoad" :config="canvasConfig"
@canvasInit="canvasInit"
@changeCanvas="changeCanvas"
:clothingImageUrl="selectDetail.undividedLayer"
showFixedLayer
:canvasJSON="canvasJSON"
:clothing-image-opts="{
imageMode:'contains',
}"
ref="editCanvas">
<template #customTools="{ toolButtonProps }">
<!-- 也可以直接使用普通的按钮 -->
<div class="custom-tool-btn" :class="{active:currentView === 'redGreenExample'}" @click="editFront('redGreenExample')">
<i class="fi fi-sr-layers"></i>
<div class="tool-tooltip">Edit the front and back sections</div>
</div>
</template>
</editCanvas>
<!-- <canvasContent ref="canvasContent"></canvasContent> -->
</div>
<div class="editFrontBack" v-if="currentView === 'redGreenExample'" @click.stop>
<!-- <editFrontBack
:patchData="frontBack"
:imgDomIndex="imgDomIndex"
ref="editFrontBack">
</editFrontBack> -->
<editCanvas v-if="canvasLoad" :config="canvasConfig"
:enabledRedGreenMode="true"
:clothingImageUrl="selectDetail.path"
:redGreenImageUrl="frontBack.front[imgDomIndex].maskUrl"
@trigger-red-green-mouseup="frontBackChange"
:clothing-image-opts="{
imageMode:'contains',
}"
ref="editCanvasBackFront">
<template #customTools="{ toolButtonProps }">
<div class="custom-tool-btn" :class="{active:currentView === 'redGreenExample'}" @click="editFront('canvasEditor')">
<i class="fi fi-sr-layers"></i>
<div class="tool-tooltip">Edit the front and back sections</div>
</div>
</template>
</editCanvas>
</div>
</div>
<!-- <div class="Finish">
<div class="gallery_btn" @click="privewDetail">Finish</div>
</div> -->
</div>
</div>
<div class="mark_loading" v-show="isShowMark">
<a-spin size="large" />
</div>
</div>
</template>
<script lang="ts">
import { defineComponent,computed,onBeforeUnmount,provide,nextTick,watch,toRefs, reactive} from 'vue'
import { Https } from "@/tool/https";
import { Modal,message } from 'ant-design-vue';
import {getUploadUrl,isMoible,setGradual} from '@/tool/util'
import { useStore } from "vuex";
import { useI18n } from 'vue-i18n'
import editCanvas from "@/component/Canvas/CanvasEditor/index.vue";
import { formatTime,segmentImage,getMinioUrl } from "@/tool/util";
export default defineComponent({
components:{
editCanvas
},
props:{
},
setup(props,{emit}) {
const store = useStore();
const {t} = useI18n();
const detailDom = reactive({
editFrontBack:null as any,
model:null,
editCanvas:null as any,
editCanvasBackFront:null as any,
canvasContent:null as any,
})
const userDetail = computed(()=>{
return store.state.UserHabit.userDetail
})
const detailData = reactive({
isShowMark:false,
liquefactionData:null as any,
liquefaction:null as any,
canvasType:'export',
imgDomIndex:-1,
selectDetail:computed(()=>store.state.DesignDetail.selectDetail),
designDetail:computed(()=>store.state.DesignDetail.designDetail),
frontBack:computed(()=>store.state.DesignDetail.frontBack),
canvasLoad:false,
canvasConfig:{
} as any,
currentView:'canvasEditor',
getCanvasIfEdit:inject('getCanvasIfEdit')as any,
canvasInstance:null as any,
canvasJSON:'',
})
watch(()=>detailData.selectDetail,(newValue,oldValue)=>{
detailData.imgDomIndex = detailData.frontBack.front.findIndex((item:any)=>item.id == newValue.id)
// privewDetail(oldValue)
},{immediate: true})
provide('isShowMark',detailData.isShowMark)
provide('canvasType',detailData.canvasType)
const editFront = (str:any)=>{//编辑前后片
let canvasJSON = '' as any
if(detailData.currentView === 'canvasEditor'){
sessionStorage.setItem('sketchEdit',detailDom.editCanvas.getJSON())
canvasJSON = sessionStorage.getItem('frontBackEdit');
}else{
sessionStorage.setItem('frontBackEdit',detailDom.editCanvasBackFront.getJSON())
canvasJSON = sessionStorage.getItem('sketchEdit');
}
detailData.canvasLoad = false
detailData.currentView = str
if(canvasJSON){
detailData.canvasLoad = true
nextTick(()=>{
if(detailData.currentView === 'redGreenExample'){
detailDom.editCanvas.loadJSON(canvasJSON)
}else{
detailDom.editCanvasBackFront.loadJSON(canvasJSON)
}
})
}else{
if(detailData.currentView === 'redGreenExample'){
nextTick(()=>{
setCanvas(detailData.selectDetail.undividedLayer).then(()=>{
detailData.canvasLoad = true
})
})
}else{
nextTick(()=>{
setCanvas(detailData.frontBack.front[detailData.imgDomIndex].maskUrl).then(()=>{
detailData.canvasLoad = true
})
})
}
}
}
const privewDetail = async (oldSelectDetail = detailData.selectDetail)=>{
if(!detailDom.editCanvas)return
return new Promise((res,reject)=>{
detailDom.editCanvas.exportImage({isContainBg:false,isContainFixed:true}).then((rv)=>{
if(oldSelectDetail?.partialDesign)oldSelectDetail.partialDesign.partialDesignBase64 = rv
res('')
})
})
}
const setFrontBackColor = (data:any)=>{
detailDom.editFrontBack.setBackground(data)
}
const setCanvas = (url:any)=>{
return new Promise((res,rev)=>{
let img = new Image()
img.onload = ()=>{
let wH = [1,1]
let domHeight = detailDom.canvasContent.offsetHeight - 200
let imgHeight = img.height
wH = [1,domHeight/imgHeight]
detailData.canvasConfig.width = img.width * wH[1]
detailData.canvasConfig.height = domHeight
res('')
}
img.src = url
})
}
const frontBackChange = (value:any)=>{
let full = detailData.frontBack.front[detailData.imgDomIndex].undividedLayer
let size = {
...detailData.canvasConfig,
}
segmentImage(value,full,size).then((rv)=>{
let front = detailData.frontBack.front[detailData.imgDomIndex]
let back = detailData.frontBack.back[detailData.imgDomIndex]
if(!front?.oldImageUrl)front.oldImageUrl = front.imageUrl
if(!front?.oldMaskUrl)front.oldMaskUrl = front.imageUrl
if(!back?.oldImageUrl)back.oldImageUrl = back.imageUrl
if(!front?.oldMaskUrl)store.commit('DesignDetail/updataDetailItem',{maskUrl:front.oldMaskUrl})
front.imageUrl = rv.targetFrontUrl
front.maskUrl = value
back.imageUrl = rv.targetBackUrl
store.commit('DesignDetail/updataDetailItem',{maskUrl:value})
})
}
const canvasInit = (value:any)=>{
// detailDom.editCanvas.addImageToLayer(detailData.selectDetail.undividedLayer,{layerId:value.layers.value[0].id,imageMode:'contains',undoable:false})
detailData.canvasInstance = value
detailData.getCanvasIfEdit.fun = getCanvasLength
detailData.isShowMark = false
}
const getCanvasLength = ()=>{
return detailData.canvasInstance?.commandManager?.undoStack?.length
}
const saveCanvas = async (type:string = '')=>{
if(type !== 'auto'){
detailData.isShowMark = true
}
const index = detailData.designDetail.clothes.findIndex(item => item.id === detailData.selectDetail.id);
console.log(index,detailData.selectDetail.id)
await new Promise<void>((resolve, reject) => {
let canvasJSON = detailDom.editCanvas.getJSON()
let canvasData = JSON.parse(canvasJSON)
if(!canvasData)return
canvasData.canvas.objects.forEach((objectsItem:any) => {
if(objectsItem.type == 'image')objectsItem.minioUrl = getMinioUrl(objectsItem.src)
});
let blob = new Blob([JSON.stringify(canvasData)], { type: "application/json" });
let formData = new FormData();
formData.append("file", blob, "data.json");
formData.append("designItemDetailId", detailData.selectDetail.id);
formData.append("module", "designItemDetail");
let config = {
headers: { "Content-Type": "multipart/form-data", Accept: "*/*" },
};
Https.axiosPost(Https.httpUrls.exportSave, formData, config).then(
(rv) => {
if(index>-1)detailData.designDetail.clothes[index].canvasId = rv
// detailData.selectDetail.canvasId = rv
detailData.isShowMark = false
resolve()
}
).catch(()=>{
detailData.isShowMark = false
resolve()
});
})
}
let time = null as any
const changeCanvas = ()=>{
clearTimeout(time)
time = setTimeout(()=>{
saveCanvas('auto')
},3000)
}
onBeforeUnmount(()=>{
let front = detailData.frontBack.front[detailData.imgDomIndex]
let back = detailData.frontBack.back[detailData.imgDomIndex]
if(front?.oldImageUrl)front.imageUrl = front.oldImageUrl
if(front?.oldMaskUrl)front.maskUrl = front.oldMaskUrl
if(back?.oldImageUrl)back.imageUrl = back.oldImageUrl
if(front?.oldMaskUrl)store.commit('DesignDetail/updataDetailItem',{maskUrl:front.oldMaskUrl})
sessionStorage.removeItem('frontBackEdit');
sessionStorage.removeItem('sketchEdit');
detailData.canvasLoad = false
privewDetail()
})
onMounted(()=>{
nextTick(async ()=>{
console.log(JSON.parse(JSON.stringify(detailData.selectDetail)))
detailData.isShowMark = true
if(detailData.selectDetail.canvasId){
await new Promise((resolve, reject) => {
let value = {
module:'designItemDetail',
id:detailData.selectDetail.canvasId,
}
Https.axiosPost(Https.httpUrls.exportSearch, value)
.then((rv) => {
detailData.canvasJSON = rv
resolve('')
})
.catch((rv) => {
resolve(null)
});
})
}
setCanvas(detailData.selectDetail.undividedLayer).then(()=>{
detailData.canvasLoad = true
})
})
})
return{
...toRefs(detailDom),
...toRefs(detailData),
editFront,
privewDetail,
setFrontBackColor,
frontBackChange,
canvasInit,
saveCanvas,
changeCanvas,
}
},
provide() {
return {
}
},
mounted(){
},
})
</script>
<style lang="less" scoped>
.canvasBox{
flex: 1;
overflow: hidden;
// top: -100%;
display: flex;
align-items: center;
.tool-box{
width: 4rem;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
}
.Finish{
margin-top: auto;
> .gallery_btn{
cursor: pointer;
}
}
.argument-box{
height: 4rem;
width: 100%;
margin-bottom: 3rem;
margin-left: 4rem;
}
.argument-box,
.content-bottom,
.detail-box{
:deep(i){
font-size: 2.5rem;
cursor: pointer;
width: 3.5rem;
height: 3.5rem;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
transition: all .3s;
margin-bottom: .5rem;
&.active{
border: 1px solid;
border-radius: .4rem;
}
&.icon-xiala{
transform: rotate(-90deg);
}
&.icon-xialaActive{
transform: rotate(90deg);
}
&.eventNone{
cursor: no-drop;
border: none;
opacity: .5;
}
}
}
.canvasContent{
height: 100%;
// height: 70rem;
width: 100%;
border: 2px solid #000;
border-radius: 3rem;
padding: 4rem;
display: flex;
flex-direction: column;
}
.content-bottom{
flex: 1;
overflow: hidden;
display: flex;
> .contet{
flex: 1;
overflow: hidden;
position: relative;
.canvas,.editFrontBack{
width: 100%;
height: 100%;
}
.editFrontBack{
z-index: 2;
position: absolute;
top: 0;
left: 0;
}
}
}
}
.custom-tool-btn {
position: relative;
width: 3.6rem;
height: 3.6rem;
display: flex;
align-items: center;
justify-content: center;
background: none;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 1.6rem;
color: #333;
transition: all 0.2s ease;
&.active{
background-color: #e6f7ff;
color: #1890ff;
}
}
.custom-tool-btn:hover {
background-color: #f0f0f0;
&.active{
background-color: #e6f7ff;
color: #1890ff;
}
}
.custom-tool-btn:hover .tool-tooltip {
display: block;
}
.tool-tooltip {
display: none;
position: absolute;
left: 100%;
top: 50%;
transform: translateY(-50%);
background-color: rgba(0, 0, 0, 0.7);
color: white;
padding: .4rem .8rem;
border-radius: .4rem;
margin-left: .8rem;
white-space: nowrap;
font-size: 1.2rem;
z-index: 10;
}
.tool-tooltip:before {
content: "";
position: absolute;
top: 50%;
right: 100%;
margin-top: -.5rem;
border-width: .5rem;
border-style: solid;
border-color: transparent rgba(0, 0, 0, 0.7) transparent transparent;
}
</style>

View File

@@ -0,0 +1,416 @@
<template>
<div class="color">
<div class="detailText">{{$t('DesignPrintOperation.CurrentColor')}}</div>
<div class="pallet">
<pallet :selectColor="selectColor" @selectUplpadColor="selectUplpadColor"></pallet>
</div>
<div class="detailText">{{$t('DesignPrintOperation.Colorpelette')}}</div>
<div class="colorBox">
<div v-for="item,index in colorList.list[selectDetail.id]" @click="setSelectColor(item,index)" class="colorBoxItem" :class="{active:colorList.index == index}">
<div v-if="item" class="box">
<div v-show="!item.gradient" class="background" :style="{'background-color':item.hex}"></div>
<div v-show="!item.gradient" class="text">{{ item.hex }}</div>
<div v-show="!item.gradient" class="text">{{ item.name }}</div>
<div v-show="item.gradient" class="backgroundImg" :style="{'background-image':`linear-gradient(${item.gradient?.angle}deg,${setGradient(item.gradient)})`}"></div>
</div>
</div>
</div>
<div class="detailText">{{$t('DesignPrintOperation.Colorfromimage')}}</div>
<div class="uploadImage">
<upload @selectUplpadColor="selectUplpadColor"></upload>
</div>
<div class="detailText">{{$t('DesignPrintOperation.ColorCode')}}</div>
<div class="colorCode">
<div class="generalModel_state">
<div class="generalModel_state_item">
<input class="search_input" placeholder="Tcx valuee.g:19-4052)" v-model="tcxToColor" style="width: 100%;" @keydown.enter="getTcxColor()">
<i class="fi fi-br-search" @click="getTcxColor"></i>
</div>
</div>
<!-- <div class="getTcxColorBtn" @click="getTcxColor">{{$t('DesignPrintOperation.ExtractColor')}}</div> -->
</div>
</div>
</template>
<script lang="ts">
import { defineComponent,computed,ref,watch,nextTick,toRefs, reactive, onMounted} from 'vue'
// import setDesignItem from '@/component/Detail/setDesignItem2.vue'
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { useStore } from "vuex";
import { Https } from "@/tool/https";
import { useI18n } from 'vue-i18n'
import { rgbaToHex,rgbToHsv } from "@/tool/util"
import { message,Upload} from 'ant-design-vue';
import upload from './upload.vue'
import pallet from './pallet.vue'
export default defineComponent({
components:{
upload,pallet
},
setup(props,{emit}) {
const store = useStore();
const {t} = useI18n();
const colorData = reactive({
selectTitle:'current',
selectDetail:computed(()=>store.state.DesignDetail.selectDetail),
allBoardData:computed(()=>store.state.UploadFilesModule.allBoardData),
currentDetailType:computed(()=>store.state.DesignDetail.currentDetailType),
colorList:{
list:{},
index:-1,
} as any,
selectColor:{} as any,
setGradient:computed(()=>{
return (gradient:any)=>{
let gradientStr = ''
if(!gradient?.gradientList)return
gradient.gradientList.sort((a:any, b:any) => {
let aArr = a.left.split('%')[0]
let bArr = b.left.split('%')[0]
return aArr - bArr;
});
gradient.gradientList.forEach((item:any,index:any)=>{
let str = ','
if(gradient.gradientList.length == index+1)str = ''
gradientStr += `rgba(${item.rgba.r},${item.rgba.g},${item.rgba.b},${item.rgba.a}) ${item.left}${str}`
})
return `${gradientStr}`
}
}),
tcxToColor:'',
})
watch(()=>colorData.selectColor,async (newVal,oldVal)=>{
if(newVal.rgba && newVal.rgba?.r){
let data:any = await getColorName(newVal.rgba)
newVal.name = data.name
newVal.tcx = data.tcx
colorData.colorList.list[colorData.selectDetail.id][colorData.colorList.index] = newVal
let value = {
data:newVal,
str:'color'
}
store.commit('DesignDetail/setNewDetail',value)
}else{
let value = {
data:{},
str:'color'
}
store.commit('DesignDetail/setNewDetail',value)
}
})
watch(()=>colorData.selectDetail.id,(newVal,oldVal)=>{
if(!newVal)return
if(!colorData.colorList?.list?.[newVal]){
colorData.colorList.list[newVal] = []
}else{
return
}
let isNoSelect = false
let pushIndex = 0
for (let index = 0; index < 9; index++) {
colorData.allBoardData.colorBoards
let item:any = {}
item = colorData.allBoardData.colorBoards[index]
let color = colorData.allBoardData.colorBoards?.[index]
if(!color?.rgba && color?.rgbValue)color.rgba = color.rgbValue
if(
colorData.allBoardData.colorBoards?.[index] &&
colorData.selectDetail.color.rgba?.r == color?.rgba?.r &&
colorData.selectDetail.color.rgba?.g == color?.rgba?.g &&
colorData.selectDetail.color.rgba?.b == color?.rgba?.b &&
JSON.stringify(colorData.selectDetail.color.gradient) == JSON.stringify(color?.gradient)
&& colorData.selectDetail.color.rgba?.r
){
isNoSelect = true
colorData.selectColor = item
colorData.colorList.index = index
}else if(color?.rgba?.r){
pushIndex = index
item = {
hex:rgbaToHex([color?.rgba.r,color?.rgba.g,color?.rgba.b]),
id:color?.id,
rgba:{
r:color?.rgba.r,
g:color?.rgba.g,
b:color?.rgba.b,
},
tcx:color?.tcx,
name:color?.name,
}
if(color?.gradient){
item.gradient = color?.gradient
}
colorData.colorList.index = index
colorData.selectColor = item
}
colorData.colorList.list[newVal].push(item)
}
if(!isNoSelect){
if(!colorData.selectDetail.color?.rgba?.r)return
let item = {
hex:rgbaToHex([colorData.selectDetail.color.rgba.r,colorData.selectDetail.color.rgba.g,colorData.selectDetail.color.rgba.b]),
id:colorData.selectDetail.color.id,
rgba:{
r:colorData.selectDetail.color.rgba.r,
g:colorData.selectDetail.color.rgba.g,
b:colorData.selectDetail.color.rgba.b,
},
tcx:colorData.selectDetail.color.tcx,
name:colorData.selectDetail.color.name,
} as any
if(colorData.selectDetail.color.gradient){
item.gradient = colorData.selectDetail.color.gradient
}
colorData.selectColor = item
colorData.colorList.index = pushIndex + 1
colorData.colorList.list[newVal][pushIndex + 1] = item
}
// for (let index = 0; index < 9; index++) {
// colorData.allBoardData.colorBoards
// let item:any = {}
// item = colorData.allBoardData.colorBoards[index]
// if(
// colorData.allBoardData.colorBoards?.[index] &&
// colorData.selectDetail.color.rgba?.r == colorData.allBoardData.colorBoards?.[index]?.rgba?.r &&
// colorData.selectDetail.color.rgba?.g == colorData.allBoardData.colorBoards?.[index]?.rgba?.g &&
// colorData.selectDetail.color.rgba?.b == colorData.allBoardData.colorBoards?.[index]?.rgba?.b &&
// JSON.stringify(colorData.selectDetail.color.gradient) == JSON.stringify(colorData.allBoardData.colorBoards?.[index]?.gradient)
// && colorData.selectDetail.color.rgba?.r
// ){
// console.log(13212)
// if(!isOneChecked){
// isOneChecked = true
// if(colorData.allBoardData.colorBoards?.[index].gradient){
// item.gradient = colorData.allBoardData.colorBoards?.[index].gradient
// }
// colorData.selectColor = item
// colorData.colorList.index = index
// }
// }else if(colorData.selectDetail.color.rgba?.r){
// if(!isNoSelect){
// item = {
// hex:rgbaToHex([colorData.selectDetail.color.rgba.r,colorData.selectDetail.color.rgba.g,colorData.selectDetail.color.rgba.b]),
// id:colorData.selectDetail.color.id,
// rgba:{
// r:colorData.selectDetail.color.rgba.r,
// g:colorData.selectDetail.color.rgba.g,
// b:colorData.selectDetail.color.rgba.b,
// },
// tcx:colorData.selectDetail.color.tcx,
// name:colorData.selectDetail.color.name,
// }
// if(colorData.selectDetail.color.gradient){
// item.gradient = colorData.selectDetail.color.gradient
// }
// colorData.colorList.index = index
// colorData.selectColor = item
// isNoSelect = true
// }else{
// item = {}
// }
// }
// colorData.colorList.list[newVal].push(item)
// }
},{immediate: true})
const selectImgItem = ()=>{
}
const getColorName = (color:any)=>{
let rgb:any = [color.r, color.g, color.b];
let hsv = rgbToHsv(rgb);
let data = [{
h: hsv[0],
s: hsv[1],
v: hsv[2],
}]
return new Promise((resolve, reject) => {
Https.axiosPost(Https.httpUrls.getRgbByHsvBatch, data)
.then((rv) => {
if (rv) {
resolve(rv[0])
}
})
.catch((res) => {
resolve({name:'--',tcx:'--'})
});
})
}
const selectUplpadColor = (item:any)=>{
colorData.selectColor = JSON.parse(JSON.stringify(item))
}
const setSelectColor = (item:any,index:number)=>{
colorData.colorList.index = index
if(item?.rgba){
colorData.selectColor = item
}else{
// colorData.colorList.list[colorData.selectDetail.id][index] = {}
colorData.selectColor = {}
}
}
const getTcxColor = ()=>{
if(!colorData.tcxToColor){
return
}
let pattern = /^\d{2}-\d{4}$/;
if(pattern.test(colorData.tcxToColor)){
Https.axiosGet(Https.httpUrls.getRgbByTcx + '?tcx=' + colorData.tcxToColor).then((rv) =>{
if(rv && rv.name){
let hex = rgbaToHex([rv.r,rv.g,rv.b,rv.a? rv.a :1])
let value = {
hex:hex,
rgba:{
r:rv.r,
g:rv.g,
b:rv.b,
},
name:rv.name,
tcx:rv.tcx,
id:rv.id,
}
colorData.selectColor = value
}else{
message.info(t('DesignDetailAlter.jsContent6'))
}
})
}else{
message.info(t('ColorboardUpload.jsContent5'))
}
}
onMounted(()=>{
if(colorData.allBoardData.colorBoards){
colorData.allBoardData.colorBoards.forEach((item:any)=>{
item.rgba = item.rgbValue
let rgba = [item.rgbValue.r,item.rgbValue.g,item.rgbValue.b]
item.hex = rgbaToHex(rgba)
})
}
})
return{
...toRefs(colorData),
selectImgItem,
selectUplpadColor,
setSelectColor,
getTcxColor,
}
},
provide() {
return {
}
},
})
</script>
<style lang="less" scoped>
.color{
// width: 34rem;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
overflow-y: auto;
> .detailText{
margin-bottom: .5rem;
}
> .pallet{
margin-bottom: 2rem;
}
> .colorBox{
margin-bottom: 1rem;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
> .colorBoxItem{
// margin: 1rem 0;
margin-bottom: 1rem;
width: 32%;
height: 11rem;
border-radius: .5rem;
border: 1px solid #999;
cursor: pointer;
display: flex;
flex-direction: column;
&.active{
border: 2px solid #000;
}
>.box{
width: 100%;
height: 100%;
> .background{
flex: 1;
height: 7rem;
width: 100%;
}
> .text{
font-weight: 600;
line-height: 2rem;
text-align: center;
white-space: nowrap; /* 禁止换行 */
overflow: hidden; /* 隐藏溢出内容 */
text-overflow: ellipsis;
}
> .backgroundImg{
width: 100%;
height: 100%;
}
}
}
}
> .uploadImage{
flex-shrink: 0;
margin-bottom: 3rem;
border: 1px dashed transparent;
background: linear-gradient(#fff, #fff) padding-box,repeating-linear-gradient(-45deg,#fff 0,#fff 0.3em, #000 0,#000 0.6em);
height: 10rem;
width: 100%;
border-radius: .5rem;
}
> .colorCode{
margin-bottom: 3rem;
> .generalModel_state{
> .generalModel_state_item{
width: 100%;
margin: 0;
border-radius: 1rem;
border: 1px solid;
overflow: hidden;
display: flex;
input{
border: none;
background: #f4f4f4;
}
i{
width: 5rem;
border-left: 1px solid;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
height: 100%;
background: #f4f4f4;
}
}
}
> .getTcxColorBtn{
background: #BDBDBD;
border-radius: 5rem;
line-height: 6rem;
text-align: center;
margin-top: 2rem;
cursor: pointer;
width: 100%;
transition: all .3s;
&:hover{
background: #d4d4d4;
}
}
}
}
</style>

View File

@@ -0,0 +1,641 @@
<template>
<div class="pallet">
<div class="palletColo" @click="openPallet">
<div v-show="!selectColor.gradient" class="palletBackColor" :title="selectColor.name" :style="{'background-color':selectColor.hex}">
{{ selectColor.hex }}
</div>
<div v-show="selectColor.gradient" class="palletBackColor" :style="{'background-image':`linear-gradient(${selectColor.gradient?.angle}deg,${setGradient(selectColor.gradient)})`}">
</div>
</div>
<div class="palletBox">
<div v-show="palletShow" class="color_setting_block">
<Chrome class="chrome_color" v-model="color_"></Chrome>
<div class="color_setting_operateSingle">
<div class="color_setting_btn" :class="{active:!color?.gradient?.gradientShow}">{{ $t('ColorboardUpload.Single') }}</div>
<a-switch :checked="color?.gradient?.gradientShow" @click="setOperate"/>
<div class="color_setting_btn" :class="{active:color?.gradient?.gradientShow}">{{ $t('ColorboardUpload.Gradual') }}</div>
</div>
<div class="color_setting_operate" v-if="color?.gradient?.gradientShow">
<div class="color_setting_operate_item color_setting_operate_control">
<div class="operate_item_box">
<div>{{ $t('ColorboardUpload.Alignment') }}</div>
</div>
<div class="operate_item_box operate_item_angle">
<div class="operate_item_angle_box" @mousedown="mousedownGradientAngle(getMousePosition($event,false))" @touchstart="mousedownGradientAngle(getMousePosition($event,true))">
<div :style="{'transform':`rotate(${color.gradient.angle}deg)`}"></div>
</div>
</div>
<div class="operate_item_box operate_item_delete">
<i class="fi fi-rr-trash" @click="deleteGradientItem"></i>
</div>
</div>
<div class="color_setting_operate_item color_setting_operate_input">
<div class="color_setting_operate_bg" @click="addGradient($event)" :style="{'background-image':color?.gradient?`linear-gradient(90deg,${setGradient(color.gradient)})`:'none'}">
</div>
<div v-for="item,index in color.gradient.gradientList" :key="item" class="color_setting_operate_btn" :class="{'active':index == color.gradient.selectIndex}" :style="{'left':item.left,'background-color':`rgba(${item.rgba.r},${item.rgba.g},${item.rgba.b},${item.rgba.a})`}" @mousedown="mousedownGradient(getMousePosition($event,false),item,index,)" @touchstart="mousedownGradient(getMousePosition($event,true),item,index,)"></div>
</div>
</div>
</div>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent,computed,ref,watch,nextTick,onMounted,toRefs, reactive} from 'vue'
import { useStore } from "vuex";
import { useI18n } from 'vue-i18n'
import { message,Upload} from 'ant-design-vue';
import { Sketch, Chrome} from '@ans1998/vue3-color'
import { getMousePosition } from "@/tool/mdEvent";
import { rgbaToHex } from "@/tool/util"
import { color } from 'echarts/core';
export default defineComponent({
components:{
Chrome,
},
props:{
selectColor:{
type:Object,
default:()=>{}
},
},
emits:['selectUplpadColor'],
setup(props,{emit}) {
const {t} = useI18n()
const store = useStore();
const palletData = reactive({
palletShow:false,
palletList:[],
color_:{} as any,
color:{} as any,
updataSelectColorTime:null as any,
gradient:{
gradientList:[
{
rgba:{
r:117,
g:119,
b:255,
a:1,
},
left:'0%'
},{
rgba:{
r:0,
g:222,
b:152,
a:1,
},
left:'100%'
},
],
angle:45,
selectIndex:-1,
gradientShow:false,
},
setGradient:computed(()=>{
return (gradient:any)=>{
let gradientStr = ''
if(!gradient?.gradientList)return
gradient.gradientList.sort((a:any, b:any) => {
let aArr = a.left.split('%')[0]
let bArr = b.left.split('%')[0]
return aArr - bArr;
});
gradient.gradientList.forEach((item:any,index:any)=>{
let str = ','
if(gradient.gradientList.length == index+1)str = ''
let rgba = item.rgba?item.rgba:{r:255,g:255,b:255}
gradientStr += `rgba(${rgba.r},${rgba.g},${rgba.b},${rgba.a}) ${item.left}${str}`
})
return `${gradientStr}`
}
})
})
const getpalletListDom = reactive({
})
watch(()=>palletData.color_,(newVal:any)=>{
if(!newVal?.rgba?.r)return
if(palletData.color?.gradient?.gradientShow){
palletData.color.gradient.gradientList[palletData.color.gradient.selectIndex].rgba = {
r:newVal.rgba.r,
g:newVal.rgba.g,
b:newVal.rgba.b,
a:newVal.rgba.a,
}
}else{
palletData.color = newVal
}
})
watch(()=>palletData.color,(newVal:any)=>{
clearTimeout(palletData.updataSelectColorTime)
palletData.updataSelectColorTime = setTimeout(()=>{
if(JSON.stringify(props.selectColor) != JSON.stringify(newVal)){
newVal.name = ''
newVal.tcx = ''
let rgba = [newVal.rgba.r,newVal.rgba.g,newVal.rgba.b]
let hex = rgbaToHex(rgba)
newVal.hex = hex
emit('selectUplpadColor',newVal)
}
},400)
},{deep: true })
const setOperate = ()=>{
if(!palletData.color.rgba)return message.info(t('DesignDetailAlter.jsContent7'))
palletData.color.rgba = palletData.color?.rgba?.r?palletData.color.rgba:{r:0,g:0,b:0,a:1}
palletData.gradient.selectIndex = 0
palletData.gradient.gradientShow = true
if(!palletData.color.gradient){
if(palletData.color.rgba.r){
palletData.gradient.gradientList[palletData.gradient.selectIndex].rgba = {
r:palletData.color.rgba.r,
g:palletData.color.rgba.g,
b:palletData.color.rgba.b,
a:1,
}
}
palletData.color.gradient = JSON.parse(JSON.stringify(palletData.gradient))
}else{
palletData.color.rgba = palletData.color.gradient.gradientList[0].rgba
palletData.color.gradient = null
}
}
const deleteGradientItem = ()=>{
if(palletData.color.gradient.gradientList.length <= 2)return
palletData.color.gradient.gradientList.splice(palletData.color.gradient.selectIndex,1)
}
const addGradient = (event:any)=>{
let gradientWidth = event.target.clientWidth
let left:any = event.offsetX/gradientWidth
palletData.color.gradient.gradientList.push({
rgba:palletData.color_.rgba,
left:left.toFixed(2)*100+'%'
})
}
const mousedownGradientAngle = (event:any)=>{
// isMoible() true为移动端
let domPosition = event.target.getBoundingClientRect()
let position = {
x:domPosition.x+domPosition.width/2,
y:domPosition.y+domPosition.height/2,
}
let angle
let mousedown = function(event:any){
let e = getMousePosition(event,false)
mouseDownOperation(e)
}
let touchstart = function(event:any){
let e = getMousePosition(event,true)
mouseDownOperation(e)
}
let mouseDownOperation = (e:any)=>{
let X = position.x
let Y = position.y
let x = (e.clientX) - X
let y = Y -( e.clientY)
angle = Math.atan2(x,y)*(180 / Math.PI)
// this.colorList[this.selectIndex].gradient = JSON.parse(JSON.stringify(this.gradient))
palletData.color.gradient.angle = angle
}
let mouseupGradientAngle = ()=>{
window.removeEventListener('touchmove',touchstart)
window.removeEventListener('touchend',mouseupGradientAngle)
window.removeEventListener('mousemove',mousedown)
window.removeEventListener('mouseup',mouseupGradientAngle)
}
window.addEventListener('touchmove',touchstart)
window.addEventListener('touchend',mouseupGradientAngle)
window.addEventListener('mousemove',mousedown)
window.addEventListener('mouseup',mouseupGradientAngle)
}
const mousedownGradient = (event:any,item:any,index:number)=>{
palletData.color.gradient.selectIndex = index
// this.selectColor = {rgba:gradientRgba,hex:hex} //顔色选择器默认颜色
let gradientWidth = (document.querySelector('.pallet .color_setting_operate_bg') as any).clientWidth
let position = {
x:event.clientX,
left:event.target.style.left?event.target.style.left.split('%')[0]:0
}
let mousedown = function(event:any){
let e = getMousePosition(event,false)
mousedownGradient(e)
}
let touchstart = function(event:any){
let e = getMousePosition(event,true)
mousedownGradient(e)
}
let mousedownGradient = (e:any)=>{
let left = ((e.clientX) - position.x)/gradientWidth*100+Number(position.left)
left = (left<0?0:left>100?100:left)
item.left = left+'%'
}
let mouseupGradientAngle = ()=>{
window.removeEventListener('touchmove',touchstart)
window.removeEventListener('touchend',mouseupGradientAngle)
window.removeEventListener('mousemove',mousedown)
window.removeEventListener('mouseup',mouseupGradientAngle)
}
window.addEventListener('touchmove',touchstart)
window.addEventListener('touchend',mouseupGradientAngle)
window.addEventListener('mousemove',mousedown)
window.addEventListener('mouseup',mouseupGradientAngle)
}
const selectImgItem = ()=>{
}
const openPallet = ()=>{
palletData.palletShow = !palletData.palletShow
console.log(props.selectColor,palletData.palletShow)
if(palletData.palletShow && props.selectColor?.rgba?.r){
if(props.selectColor.gradient){
palletData.color_.rgba = props.selectColor.gradient.gradientList[0].rgba
}else{
palletData.color_ = JSON.parse(JSON.stringify(props.selectColor))
palletData.gradient.gradientShow = false
}
palletData.color = JSON.parse(JSON.stringify(props.selectColor))
}else{
}
}
onMounted(()=>{
nextTick().then(()=>{
const backIcon = document.createElement('div');
backIcon.classList.add('vc-sketch-color-wrap')
let dropperDom = document.getElementsByClassName("pallet")?.[0]?.getElementsByClassName('vc-chrome-fields-wrap')[0]
dropperDom.appendChild(backIcon);
backIcon.addEventListener('click',async ()=>{
try {
const dropper = new EyeDropper();
const result = await dropper.open();
let hex = result.sRGBHex.replace("#", "");
// 将十六进制颜色码拆分成红、绿、蓝三个部分
const r = parseInt(hex.substring(0, 2), 16);
const g = parseInt(hex.substring(2, 4), 16);
const b = parseInt(hex.substring(4, 6), 16);
palletData.color = {rgba:{r:r,g:g,b:b,a:1},hex:result.sRGBHex}
// return `rgb(${r}, ${g}, ${b})`;
// box.style.backgroundColor = label.textContent = result.sRGBHex;
} catch (e) {
message.info(t('DesignDetailAlter.jsContent1'))
}
})
})
})
return{
...toRefs(palletData),
...toRefs(getpalletListDom),
openPallet,
selectImgItem,
setOperate,
deleteGradientItem,
addGradient,
mousedownGradientAngle,
mousedownGradient,
getMousePosition,
}
},
provide() {
return {
}
},
})
</script>
<style lang="less" scoped>
.pallet{
position: relative;
> .palletColo{
width: 100%;
height: 5.5rem;
border-radius: .5rem;
border: 1px solid #000;
padding: .5rem .6rem;
cursor: pointer;
> .palletBackColor{
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
}
> .palletBox{
position: absolute;
width: 100%;
z-index: 2;
> .color_setting_block{
margin: auto;
background: linear-gradient(70deg, #eee4f3, #f3f4e6);
width: 100%;
border-radius: calc(1rem*1.2);
overflow: hidden;
box-shadow: 2px 2px 8px rgba(0,0,0,.3);
.vc-chrome{
background: rgba(0,0,0,0);
box-shadow:none;
}
:deep(.chrome_color){
width: 100%;
overflow: hidden;
.vc-chrome-saturation-wrap{
width: 30rem;
height: 30rem;
margin: 2rem auto;
padding-bottom: 0;
}
.vc-chrome-body{
padding: 0;
width: 90%;
margin: 2 auto;
margin: 0 auto;
background: rgba(0,0,0,0);
margin-bottom: 3rem;
// display: none;
.vc-chrome-fields-wrap{
margin-top: 5%;
padding: 0;
position: relative;
.vc-chrome-toggle-btn{
width: calc(3.2rem*1.2);
.vc-chrome-toggle-icon{
height: auto;
margin-right: calc(-0.4rem*1.2);
margin-top: calc(0rem*1.2);
display: flex;
flex-direction: column;
align-items: center;
svg{
width: calc(2.4rem*1.2) !important;
height: calc(2.4rem*1.2) !important;
}
}
}
.vc-chrome-fields{
.vc-chrome-field{
padding-left: calc(.6rem*1.2);
}
.vc-input__label{
font-size: calc(1.6rem*1.2);
}
.vc-input__input{
font-size: 2rem;
height: 4rem;
}
}
.ant-upload-list{
}
.vc-sketch-color-wrap{
background-image: url(@../../../../../../assets/images/homePage/dropper.png);
background-size: 3rem;
background-repeat: no-repeat;
background-position: 50%;
cursor: pointer;
margin: 0;
width: 4rem;
height: 4rem;
padding: calc(.7rem*1.2);
border: 1px solid;
position: absolute;
bottom: -2rem;
right: 0rem;
border-radius: calc(.5rem*1.2);
}
.vc-chrome-fields{
.vc-input__label{
margin-top: calc(1rem*1.2);
}
}
.vc-chrome-fields:nth-child(2){
>:last-of-type {
display: none;
}
}
.vc-chrome-fields:nth-child(3){
>:last-of-type {
display: none;
}
}
}
.vc-chrome-controls{
align-items: center;
flex-direction: row-reverse;
.vc-chrome-color-wrap{
// width: 3.6rem*1.2);
margin-left: calc(2rem*1.2);
width: auto;
.vc-chrome-active-color{
border-radius: 50%;
}
.vc-chrome-active-color,.vc-checkerboard{
width: calc(3rem*1.2);
height: calc(3rem*1.2);
}
}
.vc-chrome-hue-wrap,.vc-chrome-alpha-wrap{
.vc-hue{
border-radius: 15px;
}
.vc-alpha{
border-radius: 15px;
overflow: hidden;
}
height: 2rem;
margin: 0;
.vc-hue-pointer{
transform: translateX(-1.25rem);
}
.vc-hue-picker{
width: 2.5rem;
height: 2.5rem;
border-radius: 50%;
transform: translate(0px,-3px);
}
}
.vc-chrome-alpha-wrap{
display: none;
}
}
}
.vc-chrome-saturation-wrap .vc-saturation-circle{
width: calc(1rem*1.2);
height: calc(1rem*1.2);
}
}
.color_block{
// margin-top: calc(1rem;
// display: flex;
// justify-content: space-between;
// font-size: calc(1.6rem;
width: 100%;
padding: 0 5%;
padding-bottom: 5%;
margin: calc(0.5rem*1.2) auto;
display: flex;
justify-content: space-between;
align-items: center;
.color_right{
width: 13rem;
font-size: calc(1.2rem*1.2);
color: #666666;
.color_rgb_block{
display: flex;
.rgb_item{
margin-left: calc(.2rem*1.2);
}
}
}
.color_left{
cursor: pointer;
color: rgb(153, 153, 153);
}
.color_right,.color_left{
>div{
display: flex;
align-items: center;
}
.color_HEX_block,.color_rgb_block{
padding: .25rem .6rem;
box-shadow: inset 0 0 0 1px #ccc;
border-radius: .5rem;
justify-content: space-around;
text-transform:uppercase;
.color_block_bg{
width: 1.8rem;
height: 2.5rem;
// margin-right: .5rem;
display: flex;
justify-content: space-between;
}
}
.color_block_bg{
}
}
}
.color_setting_operateSingle{
text-align: center;
margin: 1rem 0;
display: flex;
justify-content: center;
.color_setting_btn{
margin: 0 1rem;
color: rgba(0, 0, 0, 0.5);
&.active{
color: rgba(0, 0, 0, 0.7);
font-weight: 900;
}
}
}
.color_setting_operate{
*{
-webkit-touch-callout: none; /* iOS Safari */
-webkit-user-select: none; /* Safari */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* Internet Explorer/Edge */
user-select: none;
}
.color_setting_operate_item{
display: flex;
justify-content: space-around;
align-items: center;
.operate_item_box{
}
}
.color_setting_operate_control{
.operate_item_delete,.operate_item_angle{
cursor: pointer;
}
.operate_item_delete{
i{
display: flex;
font-size: 3rem;
}
}
.operate_item_angle{
.operate_item_angle_box{
border-radius: 50%;
width: 4rem;
height: 4rem;
border: solid 2px #000;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
>div{
height: 100%;
width: 1rem;
position: relative;
pointer-events:none;
}
>div::before{
position: absolute;
content: "";
top: 0.2rem;
width: 1rem;
height: 1rem;
border-radius: 50%;
background: #000;
}
}
}
}
.color_setting_operate_input{
width: 80%;
// padding: 0 10%;
margin: 1.2rem 10%;
border-radius: 10%;
position: relative;
height: 2.5rem;
.color_setting_operate_bg{
border-radius: .5rem;
width: 100%;
height: 2.5rem;
background: #fff;
position: absolute;
}
}
.color_setting_operate_btn{
position: absolute;
top: 50%;
transform: translate(-50%,-50%);
left: 0;
width: 1rem;
height: 110%;
border: .2rem solid;
border-radius: .5rem;
cursor: pointer;
box-sizing: content-box;
z-index: 2;
&.active{
border: .3rem solid;
}
}
.color_setting_operate_btn:hover{
border: .3rem solid;
}
}
}
}
}
</style>

View File

@@ -0,0 +1,258 @@
<template>
<div class="upload">
<div class="successfullyUpload" v-show="uploadList?.[selectDetail.id]?.length >= 1">
<div class="img">
<div class="upload_file_item" v-for="(file) in uploadList?.[selectDetail.id]" :key="file">
<div class="upload_file_item_content" v-show="file.status !== 'done'">
<a-spin :indicator="indicator" tip="Uploading..."/>
</div>
<div class="upload_file_item_content" v-show="file.status === 'done'">
<img :src="file?.imgUrl" class="upload_img">
<div class="delete_file_block" @click="colorDeleteFile(index)">{{ $t('DesignDetailAlter.Delete') }}</div>
</div>
</div>
</div>
<div class="color">
<div v-for="item in colorList?.[selectDetail.id]" :key="item" @click="selectColor(item)" :style="{'background-color': item.hex}"></div>
</div>
</div>
<a-upload
:capture="null"
v-show="!uploadList?.[selectDetail.id] || uploadList?.[selectDetail.id]?.length < 1"
list-type="picture-card"
:customRequest="function(){}"
@change="fileUploadChange"
:before-upload="beforeUpload"
:action="null"
accept=".jpg,.png,.jpeg,.bmp"
>
<div class="upload_tip_block">
<i class="fi fi-br-upload"></i>
</div>
</a-upload>
</div>
</template>
<script lang="ts">
import { defineComponent,computed,h,watch,nextTick,createVNode,toRefs, reactive} from 'vue'
import { message,Upload} from 'ant-design-vue';
import { useStore } from "vuex";
import GO from "@/tool/GO";
import { LoadingOutlined } from '@ant-design/icons-vue';
import { useI18n } from 'vue-i18n'
import { rgbaToHex } from "@/tool/util"
export default defineComponent({
components:{
},
emits:['selectUplpadColor'],
setup(props,{emit}) {
const {t} = useI18n();
const store = useStore();
const colorUpload = reactive({
selectDetail:computed(()=>store.state.DesignDetail.selectDetail),
uploadList:{} as any,
indicator: h(LoadingOutlined, {
style: {
fontSize: "2.4rem",
},
spin: true,
}),
colorList:{} as any,
})
const fileUploadChange = (data:any)=>{
let file:any = data.file
let fileData = file.originFileObj
var reader = new FileReader();
reader.onload = (e:any) => {
let data_new;
if (typeof e.target.result === 'object') {
// 把Array Buffer转化为blob 如果是base64不需要
data_new = window.URL.createObjectURL(new Blob([e.target.result]));
} else {
data_new = e.target.result;
}
file.imgUrl = data_new
file.status = 'done'
if(!colorUpload.uploadList[colorUpload.selectDetail.id])colorUpload.uploadList[colorUpload.selectDetail.id]=[]
colorUpload.uploadList[colorUpload.selectDetail.id].push(file)
setTimeout(async ()=>{
const img = new Image();
// let colorImage = this.$refs.colorImage
img.src = file.imgUrl;
img.onload = async () => {
const colorThief = new ColorThief();
// let domImg = colorImage[0];
// let color = colorThief.getColor(img)
// let colorHex = this.rgbaToHex(color)
let selectColorList:any = [];
let selectColor = colorThief.getPalette(img,8)
//排序
let obj = {
max : 5,
min: 5,
}
let colorSort:any
await GO.setColor(selectColor,file.imgUrl,obj).then(
(rv:any) => {
if(rv){
colorSort = rv.ratio
}
}
)
colorSort.sort((a:any, b:any) => {
var a_num = a.ratio;
var b_num = b.ratio;
return b_num - a_num;
});
selectColor = []
colorSort.forEach((v:any)=>{
selectColor.push(v.rgb)
})
selectColor = selectColor.join('&')
selectColor = selectColor.split("&")
let color = selectColor[0].split(',')
let colorHex = rgbaToHex(color)
let colorLi:any = []
new Set(selectColor).forEach((item:any)=>{
colorLi.push(item.split(","))
})
colorLi.forEach((element:any) => {
let colorLiHex = rgbaToHex(element)
selectColorList.push(
{rgba:{r:element[0],g:element[1],b:element[2],a:1},hex:colorLiHex}
)
});
if(!colorUpload.colorList[colorUpload.selectDetail.id])colorUpload.colorList[colorUpload.selectDetail.id]=[]
colorUpload.colorList[colorUpload.selectDetail.id] = selectColorList
// this.getHsvColor(selectColorList)
// this.selectColor = {rgba:{r:color[0],g:color[1],b:color[2],a:1},hex:colorHex}
img.remove()
};
},100)
};
// 转化为base64S
reader.readAsDataURL(fileData)
}
const beforeUpload = (file:any)=>{
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/jpg' || file.type === 'image/bmp';
if (!isJpgOrPng) {
message.info(t('DesignDetailAlter.jsContent4'));
}
const isLt2M = file.size / 1024 / 1024 < 5;
if (!isLt2M) {
message.info(t('DesignDetailAlter.jsContent5'));
}
return (isJpgOrPng && isLt2M) || Upload.LIST_IGNORE;
}
const selectColor = (color:any)=>{
emit('selectUplpadColor',color)
}
const colorDeleteFile = ()=>{
colorUpload.uploadList[colorUpload.selectDetail.id] = []
colorUpload.colorList[colorUpload.selectDetail.id] = []
}
return{
...toRefs(colorUpload),
fileUploadChange,
beforeUpload,
colorDeleteFile,
selectColor,
}
},
provide() {
return {
}
},
})
</script>
<style lang="less" scoped>
.upload{
// width: 34rem;
width: 100%;
height: 100%;
display: flex;
align-items: center;
:deep(.ant-upload-picture-card-wrapper){
height: 100%;
width: 100%;
.ant-upload-list{
height: 100%;
width: 100%;
.ant-upload-select-picture-card{
height: 100%;
width: 100%;
border: none;
margin: 0;
background: #fff;
&:hover{
border: none;
}
}
}
.upload_tip_block{
i{
font-size: 4rem;
display: flex;
}
}
}
> .successfullyUpload{
width: 100%;
display: flex;
> .color{
display: flex;
margin-left: 1rem;
flex-wrap: wrap;
align-items: center;
> div{
margin: .5rem;
width: 3rem;
height: 3rem;
cursor: pointer;
}
}
> .img{
> .upload_file_item{
> .upload_file_item_content{
width: 9rem;
height: 9rem;
position: relative;
&:hover{
> .delete_file_block{
display: block;
}
}
> .delete_file_block{
display: none;
cursor: pointer;
position: absolute;
bottom: 0;
line-height: 3rem;
background: rgba(0, 0, 0, 0.6);
color: #fff;
width: 100%;
text-align: center;
}
> img{
width: 100%;
height: 100%;
object-fit: contain;
}
}
}
}
}
}
</style>

View File

@@ -0,0 +1,162 @@
<template>
<div class="element">
<div class="detailText">{{$t('DesignPrintOperation.CurrentElement')}}</div>
<div class="select_element">
<img :class="{active:elementList.length == 1}" v-for="item in elementList" @click="addElement(item)" :src="item.path" alt="">
<!-- <img :src="selectDetail.path" alt="">
{{ selectDetail }} -->
<div v-if="elementList.length == 0">
<i class="fi fi-rr-picture centent"></i>
</div>
</div>
<selectList @selectImgItem="selectImgItem" level1Type="DesignElements" type="element" :catecoryList="printCatecoryList"></selectList>
</div>
</template>
<script lang="ts">
import { defineComponent,computed,ref,watch,nextTick,createVNode,toRefs, reactive} from 'vue'
// import setDesignItem from '@/component/Detail/setDesignItem2.vue'
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { Https } from "@/tool/https";
import { useStore } from "vuex";
import { useI18n } from 'vue-i18n'
// import sketchCategory from "@/component/HomePage/sketchCategory.vue";
import selectList from './module/selectList.vue'
export default defineComponent({
components:{
selectList,
},
setup(props,{emit}) {
const store = useStore();
const detailData = reactive({
selectTitle:'current',
selectDetail:computed(()=>store.state.DesignDetail.selectDetail),
printCatecoryList:computed(()=>{
return store.state.UserHabit.designElementsType
}),
elementList:[],
currentDetailType:computed(()=>store.state.DesignDetail.currentDetailType)
})
watch(()=>detailData?.selectDetail?.trims?.prints,(newVal,oldVal)=>{
if(!newVal)return
detailData.elementList = newVal.reduce((acc:any, curr:any) => {
if (!acc.some((item:any) => item.minIOPath === curr.minIOPath)) {
acc.push(curr);
}
return acc;
}, []);
},{immediate: true})
const getDetailListData = reactive({
total:0,
pageSize:10,
currentPage:1,
})
const getDetailListDom = reactive({
libraryList:null as any,
})
const openCurrent = ()=>{
detailData.selectTitle = 'current'
}
const openUpload = ()=>{
detailData.selectTitle = 'upload'
}
const openLibrary = ()=>{
detailData.selectTitle = 'library'
getDetailListDom.libraryList.init()
}
const addElement = (data:any)=>{
let value = {
designType:data.designType,
level2Type:data.level2Type,
minIOPath:data.minIOPath,
url:data.path,
}
store.commit('DesignDetail/setCurrentPrintElement',value)
}
const selectImgItem = (data:any)=>{
let value = {
data,
}
if(detailData.currentDetailType != 'print' && detailData.currentDetailType != 'element'){
store.commit('DesignDetail/setNewDetail',value)
}else{
store.commit('DesignDetail/setCurrentPrintElement',null)
store.commit('DesignDetail/setCurrentPrintElement',data)
}
}
return{
...toRefs(detailData),
...toRefs(getDetailListData),
...toRefs(getDetailListDom),
openCurrent,
openUpload,
openLibrary,
selectImgItem,
addElement,
}
},
provide() {
return {
}
},
})
</script>
<style lang="less" scoped>
.element{
// width: 34rem;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
> .detailText{
margin-bottom: 1rem;
}
> .select_element{
width: 100%;
height: 23.5rem;
padding: 1rem;
text-align: center;
border-radius: .5rem;
// border: 1px dashed #202020;
border: 1px dashed transparent;
background: linear-gradient(#fff, #fff) padding-box,repeating-linear-gradient(-45deg,#fff 0,#fff 0.3em, #000 0,#000 0.6em);
margin-bottom: 3rem;
display: flex;
flex-wrap: wrap;
overflow: hidden;
justify-content: space-between;
overflow-y: auto;
justify-content: flex-start;
> img{
object-fit: contain;
height: 9rem;
width: 9rem;
overflow-y: auto;
margin-bottom: 1rem;
margin: 1rem;
cursor: pointer;
}
> .active{
width: 100%;
height: 100%;
margin: 0;
margin-bottom: 0;
}
> div{
height: 100%;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
> i{
font-size: 10rem;
}
}
}
}
</style>

View File

@@ -0,0 +1,79 @@
<template>
<div class="detailLeft">
<sketch v-show="currentDetailType == 'sketch'" @addDetail="addDetail"></sketch>
<print v-show="currentDetailType == 'print'"></print>
<color v-if="currentDetailType == 'color'"></color>
<element v-show="currentDetailType == 'element'"></element>
<models v-show="currentDetailType == 'models'"></models>
<addDetails ref="addDetails" @setSloganData="setSloganData"></addDetails>
</div>
</template>
<script lang="ts">
import { defineComponent,computed,ref,provide,nextTick,createVNode,toRefs, reactive} from 'vue'
// import setDesignItem from '@/component/Detail/setDesignItem2.vue'
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { Https } from "@/tool/https";
import { useStore } from "vuex";
import { useI18n } from 'vue-i18n'
import sketch from './sketch.vue'
import print from './print.vue'
import color from './colorBox/index.vue'
import element from './element.vue'
import models from './models.vue'
import addDetails from '@/component/Detail/addDetails.vue'
export default defineComponent({
components:{
sketch,print,color,addDetails,element,models
},
setup(props,{emit}) {
const store = useStore();
const detailData = reactive({
selectTitle:'upload',
selectDetail:computed(()=>store.state.DesignDetail.selectDetail),
currentDetailType:computed(()=>store.state.DesignDetail.currentDetailType),
})
const getDetailListData = reactive({
total:0,
pageSize:10,
currentPage:1,
})
const getDetailListDom = reactive({
addDetails:null as any,
})
const addDetail = () =>{
let addDetails:any = getDetailListDom.addDetails
addDetails.init(detailData.selectDetail,'')
}
const setSloganData = (data:any)=>{
detailData.selectDetail.sketchString = data
if(detailData.currentDetailType == 'sketch' && detailData.selectDetail?.newDetail?.sketch){
detailData.selectDetail.newDetail.sketch = null
}
}
return{
...toRefs(detailData),
...toRefs(getDetailListData),
...toRefs(getDetailListDom),
addDetail,
setSloganData,
}
},
provide() {
return {
}
},
})
</script>
<style lang="less" scoped>
.detailLeft{
width: 34rem;
// width: 100%;
height: 100%;
display: flex;
flex-direction: column;
}
</style>

View File

@@ -0,0 +1,172 @@
<template>
<div class="sketch">
<div class="detailText">{{$t('DesignPrintOperation.CurrentModel')}}</div>
<div class="select_sketch">
<!-- <img :src="selectDetail?.sketchString?selectDetail?.sketchString:selectDetail.path" alt=""> -->
<img :src="frontBack.body.path || selectDetail.path" alt="">
</div>
<selectList @selectImgItem="selectImgItem" :isUpload="false" level1Type="Models" type="models" :catecoryList="sketchCatecoryList"></selectList>
</div>
</template>
<script lang="ts">
import { defineComponent,computed,ref,provide,nextTick,createVNode,toRefs, reactive} from 'vue'
// import setDesignItem from '@/component/Detail/setDesignItem2.vue'
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { Https } from "@/tool/https";
import { useStore } from "vuex";
import { useI18n } from 'vue-i18n'
// import sketchCategory from "@/component/HomePage/sketchCategory.vue";
import selectList from './module/selectList.vue'
export default defineComponent({
components:{
selectList,
},
emit:['addDetail'],
setup(props,{emit}) {
const store = useStore();
const detailData = reactive({
selectTitle:'current',
frontBack:computed(()=>store.state.DesignDetail.frontBack),
designDetail:computed(()=>store.state.DesignDetail.designDetail),
selectDetail:computed(()=>store.state.DesignDetail.selectDetail),
sketchCatecoryList:computed(()=>{
return store.state.UserHabit.sex.value
}),
currentDetailType:computed(()=>store.state.DesignDetail.currentDetailType)
})
const getDetailListData = reactive({
total:0,
pageSize:10,
currentPage:1,
})
const getDetailListDom = reactive({
libraryList:null as any,
})
const openCurrent = ()=>{
detailData.selectTitle = 'current'
}
const openUpload = ()=>{
detailData.selectTitle = 'upload'
}
const openLibrary = ()=>{
detailData.selectTitle = 'library'
getDetailListDom.libraryList.init()
}
const selectImgItem = (data:any)=>{
if(data.presignedUrl)data.url = data.presignedUrl
let value = {
data,
}
store.commit('DesignDetail/setNewDetail',value)
}
const openAddDetail = ()=>{
emit('addDetail')
}
return{
...toRefs(detailData),
...toRefs(getDetailListData),
...toRefs(getDetailListDom),
openCurrent,
openUpload,
openLibrary,
selectImgItem,
openAddDetail,
}
},
provide() {
return {
}
},
})
</script>
<style lang="less" scoped>
.sketch{
// width: 34rem;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
> .detailText{
margin-bottom: 1rem;
text-align: left;
}
> .select_sketch{
width: 100%;
height: 23.5rem;
padding: 1rem 0;
text-align: center;
border-radius: .5rem;
// border: 1px dashed #202020;
border: 1px dashed transparent;
position: relative;
background: linear-gradient(#fff, #fff) padding-box,repeating-linear-gradient(-45deg,#fff 0,#fff 0.3em, #000 0,#000 0.6em);
margin-bottom: 3rem;
> img{
width: 100%;
height: 100%;
object-fit: contain;
}
> i{
position: absolute;
left: auto;
right: 1rem;
top: 2rem;
font-size: 2rem;
cursor: pointer;
}
> div{
height: 100%;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
> i{
font-size: 10rem;
}
}
}
> .switch_type_list{
display: flex;
margin-bottom: 2.5rem;
> .switch_type_item:last-child{
margin-right: 0;
}
> .switch_type_item{
position: relative;
cursor: pointer;
margin-right: 6.5rem;
}
> .switch_type_item::before {
position: absolute;
content: "";
display: block;
background: #000;
height: calc(.4rem*1.2);
left: 50%;
transform: translateX(-50%);
bottom: -.5rem;
width: 0px;
transition: 0.3s all;
}
> .select_swtich {
color: #000;
font-weight: 600;
}
> .select_swtich::before {
width: 100%;
}
}
> .sketch_content_list{
flex: 1;
overflow: hidden;
> .content_item{
height: 100%;
margin-top: 1rem;
}
}
}
</style>

View File

@@ -0,0 +1,135 @@
<template>
<div class="uploadList">
<div class="uploadList_box">
<div class="content_img_item" v-for="(file) in currentList[type]" :key="file.id">
<div class="content_img_item_block" :class="{active:file?.checked}">
<img :src="file.imgUrl?file.imgUrl:file.url" :key="file.imgUrl || file.url" :alt="file.name" @click.stop="selectImgItem(file)"/>
<sketchCategory v-if="type != 'models'" v-model:disignTypeList="catecoryList" :generateList="allBoardData.sketchboardFiles" :item="file" :isSpread="true"></sketchCategory>
</div>
</div>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent,computed,ref,provide,nextTick,watch,toRefs, reactive, onMounted} from 'vue'
import { Https } from "@/tool/https";
import { useStore } from "vuex";
import sketchCategory from "@/component/HomePage/sketchCategory.vue";
import { getCookie } from "@/tool/cookie";
import { message,Upload} from 'ant-design-vue';
import {getMinioUrl} from '@/tool/util'
import { useI18n } from 'vue-i18n'
export default defineComponent({
components:{
sketchCategory
},
props:{
catecoryList:{
type:Object,
default:()=>[] as any,
required:true
},
type:{
type:String,
default:'' as any,
required:true
},
},
emits:['selectImgItem'],
setup(props,{emit}) {
const {t} = useI18n();
const store = useStore();
const detailData = reactive({
allBoardData:computed(()=>store.state.UploadFilesModule.allBoardData),
currentList:{
sketch:computed(()=>store.state.UploadFilesModule.allBoardData.sketchboardFiles),
print:computed(()=>store.state.UploadFilesModule.allBoardData.printboardFiles),
color:computed(()=>store.state.UploadFilesModule.allBoardData.colorBoards),
models:computed(()=>store.state.Workspace.probjects.model),
},
currentDetailType:computed(()=>store.state.DesignDetail.currentDetailType),
})
const getDetailListData = reactive({
})
const selectImgItem = (file:any)=>{
if(props.type != 'models'){
if(!file.resData.minIOPath){
file.minIOPath = getMinioUrl(file.resData.url)
}
if(!file.designType){
file.designType = file.resData.designType
}
}
// store.commit('DesignDetail/setNewDetail',file.resData)
emit('selectImgItem',file)
}
onMounted(()=>{
// detailData.currentList = {
// sketch:detailData.allBoardData.sketchboardFiles,
// print:detailData.allBoardData.printboardFiles,
// color:detailData.allBoardData.colorBoards,
// }
})
return{
...toRefs(detailData),
...toRefs(getDetailListData),
selectImgItem,
}
},
provide() {
return {
}
},
})
</script>
<style lang="less" scoped>
.uploadList{
height: 100%;
display: flex;
flex-direction: column;
> .uploadList_box{
width: 100%;
flex: 1;
overflow-y: auto;
display: flex;
flex-wrap: wrap;
margin-top: 1rem;
justify-content: space-between;
align-content: flex-start;
&::-webkit-scrollbar{display: none;}
> .content_img_item{
> .content_img_item_block{
width: calc((34rem - 2rem) / 2);
height: calc((34rem - 2rem) / 2);
position: relative;
margin-bottom: 2rem;
> img{
cursor: pointer;
width: 100%;
height: 100%;
object-fit: contain;
}
}
}
> .material_content_list_loding{
width: 100%;
height: calc((34rem - 2rem) / 2);
}
> .upload_item{
width: calc((34rem - 2rem) / 2);
height: calc((34rem - 2rem) / 2);
align-items: center;
justify-content: center;
}
}
}
</style>

View File

@@ -0,0 +1,408 @@
<template>
<div class="libraryList">
<div class="generalModel_state">
<div class="generalModel_state_item" v-if="level1Type != 'Models' && catecoryList.length > 0" :style="{'width':(level1Type == 'DesignElements'?'100%':'40%')}">
<a-select
v-model:value="designType"
:options="(designTypeList)"
@change="handleChange"
style="width:100%"
size="large"
:fieldNames="{ label: 'name', value: 'value' }"
>
<template #suffixIcon
><span
class="icon iconfont icon-xiala"
style="color: #000"
></span
></template>
</a-select>
</div>
<div class="generalModel_state_item" v-if="level1Type == 'Models'" style="margin-bottom: 1rem;" :style="{'width':mannequinData.system == 'system'?'48%':'100%'}">
<a-select
v-model:value="mannequinData.system"
:options="systemList"
@change="handleChange"
style="width:100%"
size="large"
:fieldNames="{ label: 'name', value: 'value' }"
>
<template #suffixIcon
><span
class="icon iconfont icon-xiala"
style="color: #000"
></span
></template>
</a-select>
</div>
<div class="generalModel_state_item" v-if="level1Type == 'Models'" v-show="mannequinData.system == 'system'" style="width: 48%; margin-bottom: 1rem;">
<!-- {{ mannequinStyle }} -->
<a-select
v-model:value="mannequinData.style"
:options="mannequinStyle"
@change="handleChange"
style="width:100%"
size="large"
:fieldNames="{ label: 'name', value: 'value' }"
>
<template #suffixIcon
><span
class="icon iconfont icon-xiala"
style="color: #000"
></span
></template>
</a-select>
</div>
<div class="generalModel_state_item" v-if="level1Type == 'Models'" style="width: 39%;">
<a-select
v-model:value="mannequinData.ageGroup"
:options="ageGroupList"
@change="handleChange"
style="width:100%"
size="large"
:fieldNames="{ label: 'name', value: 'value' }"
>
<template #suffixIcon
><span
class="icon iconfont icon-xiala"
style="color: #000"
></span
></template>
</a-select>
</div>
<div class="generalModel_state_item" v-if="level1Type == 'Models'" style="width: 39%;">
<a-select
v-model:value="mannequinData.sex"
:options="sexList"
@change="handleChange"
style="width:100%"
size="large"
:fieldNames="{ label: 'name', value: 'value' }"
>
<template #suffixIcon
><span
class="icon iconfont icon-xiala"
style="color: #000"
></span
></template>
</a-select>
</div>
<div class="generalModel_state_item" style="width: 35%; flex: 1;margin-right: 2%;" v-if="level1Type != 'Models' && level1Type != 'DesignElements'">
<input class="search_input" style="width: 100%;" :placeholder="$t('DesignDetailAlter.inputContent1')" v-model="searchPictureName" @keydown.enter="getLibraryList()">
</div>
<div class="generalModel_state_item" style="width: auto;" v-show="level1Type != 'DesignElements'">
<div class="search_icon_block" @click.stop="getLibraryList()"><span class="icon iconfont icon-sousuo"></span></div>
</div>
<!-- clothesPrint -->
</div>
<div class="libraryList_box">
<div class="content_img_item" v-for="(file) in libraryList" :key="file.id">
<div class="content_img_item_block" :class="{active:file?.checked}">
<img :src="level1Type != 'Models'?file.url:file.presignedUrl" :key="level1Type != 'Models'?file.url:file.presignedUrl" :alt="file?.name" @click.stop="selectImgItem(file)"/>
<sketchCategory v-if="level1Type != 'Models' && level1Type != 'DesignElements'" :isSpread="catecoryList.length == 0" :disignTypeList="designTypeList" :generateList="libraryList" :item="file" :isSetSketchCategory="true"></sketchCategory>
</div>
</div>
<div v-show="total > libraryList.length" class="material_content_list_loding" v-observe>
<img src="@/assets/images/homePage/loading.gif" alt="">
</div>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent,computed,ref,provide,nextTick,createVNode,toRefs, reactive, onMounted, watch} from 'vue'
import { Https } from "@/tool/https";
import { useStore } from "vuex";
import sketchCategory from "@/component/HomePage/sketchCategory.vue";
import { useI18n } from 'vue-i18n'
export default defineComponent({
components:{
sketchCategory
},
props:{
catecoryList:{
type:Object,
default:()=>[] as any,
required:true
},
type:{
type:String,
default:'' as any,
required:true
},
randomId:{
type:Boolean,
default:true
},
level1Type:{
type:String,
default:'' as any,
required:true
},
isSegmentation:{
type:Boolean,
default:false as any,
required:true
},
},
emits:['selectImgItem'],
setup(props,{emit}) {
const store = useStore();
const {t} = useI18n()
const detailData = reactive({
isShowLoading:false,//懒加载,加载中
libraryList:[],
designTypeList:computed(()=>props.catecoryList) as any,
designType:'',
searchPictureName:'',
designDetail:computed(()=>store.state.DesignDetail.designDetail),
mannequinData:{
sex:'Female',
style:'',
system:'system',
ageGroup:'Adult',
systemList:[],
libraryList:[],
},
systemList:[{name:t('libraryList.System'),value:'system',},{name:t('libraryList.Library'),value:'library',}],//系统
mannequinStyle:computed(()=>store.state.UserHabit.mannequinStyle),//风格列表
sexList:computed(()=>store.state.UserHabit.sex.value),//风格列表
ageGroupList:computed(()=>store.state.UserHabit.ageGroup),//风格列表
selectObject:computed(()=>store.state.Workspace.probjects),//选择的项目
})
watch(()=>detailData.selectObject,(newValue,oldValue)=>{
detailData.mannequinData.sex = newValue.sex?newValue.sex:'Female'
detailData.mannequinData.style = newValue.style?newValue.style:''
detailData.mannequinData.ageGroup = newValue.ageGroup?newValue.ageGroup:''
},{immediate:true})
watch(()=>detailData.designTypeList.length,(newValue,oldValue)=>{
detailData.designType = detailData.designTypeList[0]?.value?detailData.designTypeList[0]?.value:''
getLibraryList()
})
const getDetailListData = reactive({
total:0,
pageSize:10,
currentPage:1,
})
const init = ()=>{
detailData.designType = detailData.designTypeList[0]?.value?detailData.designTypeList[0]?.value:''
getLibraryList()
}
const hasDuplicateId = (id:any)=>{
let arr = detailData.designDetail.clothes
for (let i = 0; i < arr.length; i++) {
if (arr[i].id === id) {
return true;
}
}
return false;
}
const selectImgItem = (file:any)=>{
let randomNum = Math.floor(100 + Math.random() * 900);
let type = props.type
// let type = store.state.DesignDetail.currentDetailType
let id = file.id
if(type == 'sketch'){
id = Number(file.id + (randomNum + ''))
if(props.randomId){
if(hasDuplicateId(id)){
selectImgItem(file)
return
}
}
}
let data = JSON.parse(JSON.stringify(file))
data.type = detailData.mannequinData.system == 'system'?'System':'Library'
if(!props.isSegmentation){
data.id = id
}
emit('selectImgItem',data)
// store.commit('DesignDetail/setNewDetail',data)
}
const getLibraryList = ()=>{
if(props.type == 'models'){
getModelList()
}else{
getList()
}
}
const getModelList = ()=>{
detailData.isShowLoading = true
let value = {
sex:detailData.mannequinData.sex,
style:detailData.mannequinData?.style,
ageGroup:store.state.Workspace.probjects.ageGroup,
}
Https.axiosGet(Https.httpUrls.getMannequins,{params:value}).then((rv: any) => {
if (rv) {
rv.forEach((item:any) => {
if(item.type == 'System'){
detailData.mannequinData.systemList = item.modelList
}else{
detailData.mannequinData.libraryList = item.modelList
}
});
setMannequinList()
}
detailData.isShowLoading = false
}).catch((res)=>{
detailData.isShowLoading = false
});
}
const setMannequinList = ()=>{
if(detailData.mannequinData.system == 'system'){
detailData.libraryList = detailData.mannequinData.systemList
}else{
detailData.libraryList = detailData.mannequinData.libraryList
}
}
const getList = ()=>{
detailData.isShowLoading = true
let level2Type = ''
let workspace = store.state.Workspace.probjects
// let type = store.state.DesignDetail.currentDetailType
let data = {
level1Type:props.level1Type,
// level2Type:'Pattern',
level2Type:detailData.designType,
modelSex:workspace?.sex,
page:getDetailListData.currentPage,
pictureName:detailData.searchPictureName,
size:getDetailListData.pageSize+detailData.libraryList.length,
}
Https.axiosPost(Https.httpUrls.queryLibraryPage,data).then(
(rv) => {
rv.content.forEach((vItem:any)=>{
if(props.catecoryList){
props.catecoryList.forEach((item:any) => {
if(item.value == vItem.level2Type){
vItem.categoryValue = item.value
vItem.category = item.name
}
});
}
})
detailData.libraryList = rv.content
detailData.isShowLoading = false
getDetailListData.total = rv.total
}
).catch((res)=>{
detailData.isShowLoading = false
});
}
const handleChange = ()=>{
getDetailListData.currentPage = 1
detailData.libraryList = []
getLibraryList()
}
onMounted(()=>{
})
return{
...toRefs(detailData),
...toRefs(getDetailListData),
init,
selectImgItem,
getLibraryList,
handleChange,
}
},
directives:{
observe:{
mounted (el,binding) {
// console.log(binding.instance);
let callback = (entries:any, observer:any)=> {
entries.forEach((entry:any) => {
if (entry.isIntersecting && !this_.isShowLoading) {
this_.getLibraryList()
} else {
}
});
}
const ob = new IntersectionObserver(callback,{
root:null,
threshold:[.5]
})
ob.observe(el)
// this.currentPage = +=1
// this.pageSize = 12
// currentPage
let this_:any = binding.instance
},
},
},
provide() {
return {
}
},
})
</script>
<style lang="less" scoped>
.libraryList{
height: 100%;
display: flex;
flex-direction: column;
> .generalModel_state{
width: 100%;
display: flex;
justify-content: space-between;
> .generalModel_state_item{
width: 100%;
margin: 0;
position: relative;
> .search_icon_block{
// position: absolute;
// right: 5px;
width: calc(6rem - 4px);
height: calc(6rem - 4px);
color: #fff;
background: #000;
border-radius: 50%;
display: flex;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
}
}
> .generalModel_state_item:last-child{
// margin-top: 2rem;
}
}
> .libraryList_box{
width: 100%;
flex: 1;
overflow-y: auto;
display: flex;
flex-wrap: wrap;
margin-top: 1rem;
justify-content: space-between;
align-content: flex-start;
&::-webkit-scrollbar{display: none;}
> .content_img_item{
> .content_img_item_block{
width: calc((34rem - 2rem) / 2);
height: calc((34rem - 2rem) / 2);
position: relative;
margin-bottom: 2rem;
cursor: pointer;
> img{
width: 100%;
height: 100%;
object-fit: contain;
}
}
}
> .material_content_list_loding{
width: 100%;
height: calc((34rem - 2rem) / 2);
overflow: hidden;
> img{
width: 100%;
}
}
}
}
</style>

View File

@@ -0,0 +1,207 @@
<template>
<div class="selectList">
<div class="selectList_header">
<div class="switch_type_list" v-if="type != 'element'">
<div
@click.stop="openCurrent()"
class="switch_type_item"
:class="[selectTitle == 'current' ? 'select_swtich' : '',]"
v-if="deReconstructionList.length == 0"
>
<span class="detailText">{{ $t('DesignDetailAlter.inProject') }}</span>
</div>
<div
v-if="isUpload"
@click.stop="openUpload()"
class="switch_type_item"
:class="[selectTitle == 'upload' ? 'select_swtich' : '',]"
>
<span class="detailText">{{ $t('DesignDetailAlter.Upload') }}</span>
</div>
<div
@click.stop="openLibrary()"
class="switch_type_item"
:class="[selectTitle == 'library' ? 'select_swtich' : '']"
>
<span class="detailText">{{ $t('DesignDetailAlter.Library') }}</span>
</div>
</div>
<slot name="selectSex"></slot>
</div>
<div class="print_content_list">
<div class="content_item" v-show="selectTitle == 'current'" v-if="type != 'element' && deReconstructionList.length == 0">
<currentList ref="currentList" :level1Type="level1Type" :type="type" @selectImgItem="selectImgItem" :catecoryList="catecoryList"></currentList>
</div>
<div class="content_item" v-show="selectTitle == 'upload'" v-if="type != 'element'">
<uploadList v-if="!isSegmentation" @selectImgItem="selectImgItem" :level1Type="level1Type" :catecoryList="catecoryList"></uploadList>
<uploadSegmentation v-if="isSegmentation" :segmentationType="segmentationType" :deReconstructionList=deReconstructionList @selectImgItem="selectImgItem" :level1Type="level1Type" :catecoryList="catecoryList"></uploadSegmentation>
</div>
<div class="content_item" v-show="selectTitle == 'library'">
<libraryList :isSegmentation="isSegmentation" @selectImgItem="selectImgItem" :randomId="randomId" :level1Type="level1Type" :type="type" ref="libraryList" :catecoryList="catecoryList"></libraryList>
</div>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent,computed,onMounted,watch,nextTick,createVNode,toRefs, reactive} from 'vue'
// import setDesignItem from '@/component/Detail/setDesignItem2.vue'
import { useStore } from "vuex";
import { useI18n } from 'vue-i18n'
// import sketchCategory from "@/component/HomePage/sketchCategory.vue";
import libraryList from './libraryList.vue'
import uploadList from './uploadList.vue'
import uploadSegmentation from './uploadSegmentation.vue'
import currentList from './currentList.vue'
import { getMinioUrl } from '@/tool/util';
export default defineComponent({
components:{
currentList,
libraryList,
uploadList,
uploadSegmentation,
},
props:{
catecoryList:{
type:Array,
default:()=>[]
},
randomId:{
type:Boolean,
default:true,
required:false
},
isSegmentation:{//决定上传的入参,是否需要分割
type:Boolean,
default:false,
required:false
},
segmentationType:{//决定上传的入参,是否需要分割
type:String,
default:'',
required:false
},
type:{
type:String,
default:'' as any,
required:true
},
level1Type:{
type:String,
default:'' as any,
required:true
},
isUpload:{
type:Boolean,
default:true,
required:false
},
deReconstructionList:{
type:Array,
default:()=>[]
}
},
emits:['selectImgItem'],
setup(props,{emit}) {
const store = useStore();
const detailData = reactive({
selectTitle: props.type == 'element'?'library':'current',
printList:[]
})
const getDetailListDom = reactive({
libraryList:null as any,
})
const openCurrent = ()=>{
detailData.selectTitle = 'current'
}
const openUpload = ()=>{
detailData.selectTitle = 'upload'
}
const openLibrary = ()=>{
detailData.selectTitle = 'library'
getDetailListDom.libraryList.init()
}
const selectImgItem = (data:any)=>{
emit('selectImgItem',data)
}
onMounted(()=>{
if(props.type == 'element'){
openLibrary()
}
if(props.deReconstructionList.length > 0){
detailData.selectTitle = 'upload'
}
})
return{
...toRefs(detailData),
...toRefs(getDetailListDom),
openCurrent,
openUpload,
openLibrary,
selectImgItem,
}
},
provide() {
return {
}
},
})
</script>
<style lang="less" scoped>
.selectList{
// width: 34rem;
flex: 1;
overflow: hidden;
width: 100%;
height: auto;
display: flex;
flex-direction: column;
> .selectList_header{
margin-bottom: 2.5rem;
display: flex;
align-items: center;
> .switch_type_list{
display: flex;
> .switch_type_item:last-child{
margin-right: 0;
}
> .switch_type_item{
position: relative;
cursor: pointer;
margin-right: 6.5rem;
font-size: 1.8rem;
}
> .switch_type_item::before {
position: absolute;
content: "";
display: block;
background: #000;
height: calc(.4rem*1.2);
left: 50%;
transform: translateX(-50%);
bottom: -.5rem;
width: 0px;
transition: 0.3s all;
}
> .select_swtich {
color: #000;
font-weight: 600;
}
> .select_swtich::before {
width: 100%;
}
}
}
> .print_content_list{
flex: 1;
overflow: hidden;
> .content_item{
height: 100%;
margin-top: 1rem;
}
}
}
</style>

View File

@@ -0,0 +1,229 @@
<template>
<div class="uploadList">
<div class="uploadList_box">
<div class="content_img_item" v-for="(file) in uploadList" :key="file.id">
<div class="content_img_item_block" :class="{active:file?.checked}">
<img v-lazy="file.url" :key="file.url" :alt="file.name" @click.stop="selectImgItem(file)"/>
<sketchCategory :disignTypeList="catecoryList" :generateList="uploadList" :item="file" ></sketchCategory>
</div>
</div>
<div class="upload_item">
<div class="upload_file_item upload_component">
<a-upload
:action="uploadUrl + (upLoadHttpsUrl?upLoadHttpsUrl:'/api/element/upload')"
list-type="picture-card"
:capture="null"
:multiple="true"
:data="{
...upload,
}"
:headers="{ Authorization: token }"
v-model:file-list="uploadList"
:before-upload="beforeUpload"
:maxCount="8"
accept=".jpg,.png,.jpeg,.bmp"
@change="(file) => upFileUploadChange(file)"
>
<div
class="upload_tip_block"
v-show="uploadList.length != 8"
>
<i class="fi fi-br-upload"></i>
<!-- <img class="upload_img_icon" src="@/assets/images/homePage/add_file.png"> -->
</div>
</a-upload>
</div>
</div>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent,computed,ref,provide,nextTick,createVNode,toRefs, reactive, onMounted} from 'vue'
import { Https } from "@/tool/https";
import { useStore } from "vuex";
import sketchCategory from "@/component/HomePage/sketchCategory.vue";
import { getCookie } from "@/tool/cookie";
import { message,Upload} from 'ant-design-vue';
import {getUploadUrl} from '@/tool/util'
import { useI18n } from 'vue-i18n'
export default defineComponent({
components:{
sketchCategory
},
props:{
catecoryList:{
type:Object,
default:()=>[] as any,
required:true
},
level1Type:{
type:String,
default:'' as any,
required:true
},
segmentation:{
type:Object,
default:null as any,
},
upLoadHttpsUrl:{//决定上传的入参,是否需要分割
type:String,
default:'' as any,
},
},
emits:['selectImgItem'],
setup(props,{emit}) {
const {t} = useI18n();
const store = useStore();
const detailData = reactive({
isShowLoading:false,//懒加载,加载中
uploadList:[],
upload:props.segmentation?
props.segmentation:{
isPin: 0,
level1Type: props.level1Type,
gender:store.state.Workspace.probjects.sex ,
timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,
ageGroup:store.state.Workspace.probjects.ageGroup,
},
token:getCookie("token"),
uploadUrl:getUploadUrl(),
currentDetailType:computed(()=>store.state.DesignDetail.currentDetailType)
})
const getDetailListData = reactive({
total:0,
pageSize:10,
currentPage:1,
})
const selectImgItem = (file:any)=>{
// let data = JSON.parse(JSON.stringify(file))
// store.commit('DesignDetail/setNewDetail',file)
emit('selectImgItem',file)
}
const upFileUploadChange = (data:any)=>{
let file = data.file;
let bor = true
if (file.status === "done") {
let res = JSON.parse(file.xhr.response);
if(res.errCode == 0){
file.id = res.data.id;
file.url = res.data.url;
file.resData = res.data;
let type
if(props?.catecoryList){
if(res.data.level2Type){
props?.catecoryList.forEach((item:any) => {
if(item.value == res.data.level2Type){
file.categoryValue = item?.value;
type = item.value
file.category = item?.name;
}
});
}else{
file.categoryValue = props?.catecoryList?.[0].value;
type = props.catecoryList[0].value
file.category = props.catecoryList[0].name;
}
}
file.designType = res.data.designType
file.level2Type = type;
file.minIOPath = file.resData.minIOPath
let fileList = detailData.uploadList.filter(
(v:any) => v.status === "done"
);
detailData.uploadList = fileList
// this.selectImgItem(detailData.uploadList[detailData.uploadList.length-1])
}else{
bor = false
}
} else if (file.status === "error") {
bor = false
}
if(!bor){
let res = JSON.parse(file.xhr.response);
let index = -1;
detailData.uploadList.forEach((ele:any, index1) => {
if (file.uid === ele.uid) {
index = index1;
}
});
if (index > -1) {
detailData.uploadList.splice(index, 1);
}
message.warning(res.errMsg);
}
}
const beforeUpload = (file:any)=>{
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/jpg' || file.type === 'image/bmp';
if (!isJpgOrPng) {
message.info(t('DesignDetailAlter.jsContent4'));
}
const isLt2M = file.size / 1024 / 1024 < 5;
if (!isLt2M) {
message.info(t('DesignDetailAlter.jsContent5'));
}
return (isJpgOrPng && isLt2M) || Upload.LIST_IGNORE;
}
return{
...toRefs(detailData),
...toRefs(getDetailListData),
selectImgItem,
beforeUpload,
upFileUploadChange,
}
},
provide() {
return {
}
},
})
</script>
<style lang="less" scoped>
.uploadList{
height: 100%;
display: flex;
flex-direction: column;
> .uploadList_box{
width: 100%;
flex: 1;
overflow-y: auto;
display: flex;
flex-wrap: wrap;
margin-top: 1rem;
justify-content: space-between;
align-content: flex-start;
&::-webkit-scrollbar{display: none;}
> .content_img_item{
> .content_img_item_block{
width: calc((34rem - 2rem) / 2);
height: calc((34rem - 2rem) / 2);
position: relative;
margin-bottom: 2rem;
> img{
cursor: pointer;
width: 100%;
height: 100%;
object-fit: contain;
}
}
}
> .material_content_list_loding{
width: 100%;
height: calc((34rem - 2rem) / 2);
}
> .upload_item{
width: calc((34rem - 2rem) / 2);
height: calc((34rem - 2rem) / 2);
align-items: center;
justify-content: center;
}
}
}
</style>

View File

@@ -0,0 +1,309 @@
<template>
<div class="createCloud" ref="createCloud"></div>
<a-modal
class="createCloud_modal generalModel"
v-model:visible="operationsModal"
:footer="null"
:get-container="() => $refs.createCloud"
width="50%"
:height="'77rem'"
:maskClosable="false"
:centered="true"
:closable="false"
:mask="true"
wrapClassName="#app"
:keyboard="false"
>
<div class="generalModel_btn">
<div class="generalModel_closeIcon" @click.stop="clearData()">
<svg
width="46"
height="46"
viewBox="0 0 46 46"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<circle cx="23" cy="23" r="23" fill="white" fill-opacity="0.3" />
<rect
x="32.5063"
y="12"
width="3"
height="29"
rx="1.5"
transform="rotate(45 32.5063 12)"
fill="#000"
/>
<rect
x="34.6274"
y="32.5059"
width="3"
height="29"
rx="1.5"
transform="rotate(135 34.6274 32.5059)"
fill="#000"
/>
</svg>
</div>
</div>
<div class="modal_title_text">
<div>Upload</div>
</div>
<div class="allUserPoeration_btn">
<div class="uploadList_box">
<div class="content_img_item" v-for="(file) in uploadList" :key="file.id">
<div class="content_img_item_block" :class="{active:file?.checked}">
<img v-lazy="file.url" :key="file.url" :alt="file.name"/>
<sketchCategory :disignTypeList="deReconstructionList" :generateList="uploadList" :item="file" :isSetSketchCategory="true" :upDataType="'element'"></sketchCategory>
</div>
</div>
<div class="upload_item">
<div class="upload" @click="upload">
<i class="fi fi-br-upload"></i>
</div>
</div>
<div class="mark_loading" v-show="isShowMark">
<a-spin size="large" />
</div>
</div>
<div class="gallery_btn" style="margin-left: auto;" @click="setOk">OK</div>
</div>
</a-modal>
</template>
<script lang="ts">
import {
defineComponent,
computed,
reactive,
watch,
onMounted,
h,
nextTick,
toRefs,
} from "vue";
import { LoadingOutlined } from "@ant-design/icons-vue";
import { Https } from "@/tool/https";
import { getCookie, setCookie } from "@/tool/cookie";
import { useStore } from "vuex";
import { useI18n } from "vue-i18n";
import { getMinioUrl } from "@/tool/util";
import sketchCategory from "@/component/HomePage/sketchCategory.vue";
export default defineComponent({
components: {sketchCategory},
props: {
deReconstructionList:{
type:Array,
default:()=>[]
}
},
emits: ["setUploadImgList"],
setup(props, { emit }) {
const store = useStore();
let operations = reactive({
operationsModal: false,
isShowMark:false,
uploadList:[],
});
let operationsData = reactive({
selectObject:computed(()=>store.state.Workspace.probjects),//选择的项目
});
const getUploadElement = () => {
};
let init = () => {
operations.operationsModal = true
};
const clearData = () => {
operations.operationsModal = false
emit('setUploadImgList',JSON.parse(JSON.stringify(operations.uploadList)))
operations.uploadList = []
};
let setOk = () => {
clearData()
};
const createProbject:any = inject('createProbject',()=>{}) as any
const upload = async ()=>{
if(!operationsData.selectObject?.id)await createProbject()
const input = document.createElement('input');
input.type = 'file';
input.accept = 'image/*'; // 只允许选择图片文件
input.multiple = true; // 允许多选
input.addEventListener('change', (event:any) => {
operations.isShowMark = true; // 显示加载状态
const files = event?.target?.files;
if (!files || files.length === 0) {
operations.isShowMark = false;
return;
}
let file = [...Array.from(files)];
let param = new FormData();
param.append('isPin', '0');
param.append('gender', store.state.Workspace.probjects.sex);
param.append('ageGroup',store.state.Workspace.probjects.ageGroup)
param.append('projectId', operationsData.selectObject.id);
param.append('level1Type', 'De/Reconstruction');
param.append('level2Type', props.deReconstructionList[0].value);
param.append('timeZone', Intl.DateTimeFormat().resolvedOptions().timeZone);
file.forEach((image:any) => {
param.append('file', image);
});
let config: any = {
headers: {
'Content-Type': 'multipart/form-data',
'Accept': '*/*'
}
};
Https.axiosPost(Https.httpUrls.elementUpload, param, config)
.then((rv: any) => {
rv.designType = 'Upload'
// rv.forEach((item:any)=>{
rv.category = props.deReconstructionList[0].name
rv.categoryValue = props.deReconstructionList[0].value
// })
operations.uploadList.unshift(rv);
operations.isShowMark = false;
})
.catch(rv => {
operations.isShowMark = false;
});
});
// 触发文件选择对话框
input.click();
}
return {
...toRefs(operations),
...toRefs(operationsData),
init,
setOk,
clearData,
upload,
};
},
data() {
return {
indicator: h(LoadingOutlined, {
style: {
fontSize: "2.4rem",
},
spin: true,
}),
};
},
mounted() {},
methods: {},
directives: {
mousewheel: {
mounted(el) {
el.addEventListener("mouseenter", (e) => {
if (el.scrollWidth > el.clientWidth) {
el.parentElement.style.overflowY = "hidden";
}
});
// 鼠标移出事件
el.addEventListener("mouseleave", () => {
el.parentElement.style.overflowY = "auto";
});
el.addEventListener(
"wheel",
(e) => {
let num = 0;
if (e.deltaY > 0) {
num = 25;
} else {
num = -25;
}
el.scrollBy(num, 0);
},
{ passive: true }
);
},
},
},
});
</script>
<style lang="less" scoped>
:deep(.ant-modal-mask) {
background: rgba(0, 0, 0, 0.2);
}
:deep(.createCloud_modal) {
.ant-modal-body {
display: flex;
flex-direction: column;
}
}
</style>
<style lang="less" scoped>
.createCloud_modal {
.closeIcon {
z-index: 2;
}
.allUserPoeration_btn {
display: flex;
overflow-x: auto;
width: auto;
margin-bottom: 2rem;
flex-wrap: nowrap;
flex-direction: column;
width: 100%;
flex: 1;
> .uploadList_box{
width: 100%;
flex: 1;
overflow-y: auto;
display: flex;
flex-wrap: wrap;
margin-top: 1rem;
align-content: flex-start;
&::-webkit-scrollbar{display: none;}
> .content_img_item{
> .content_img_item_block{
width: calc((34rem - 2rem) / 2);
height: calc((34rem - 2rem) / 2);
position: relative;
margin-bottom: 2rem;
margin: 1rem;
> img{
cursor: pointer;
width: 100%;
height: 100%;
object-fit: contain;
}
}
}
> .material_content_list_loding{
width: 100%;
height: calc((34rem - 2rem) / 2);
}
> .upload_item{
width: calc((34rem - 2rem) / 2);
height: calc((34rem - 2rem) / 2);
align-items: center;
justify-content: center;
.upload{
cursor: pointer;
width: calc(6rem * 1.2);
height: calc(6rem * 1.2);
border: calc(0.3rem * 1.2) solid #000;
border-radius: calc(1rem * 1.2);
display: flex;
align-items: center;
justify-content: center;
i{
font-size: 2rem;
display: flex;
color: #000;
}
}
}
}
}
}
</style>

View File

@@ -0,0 +1,203 @@
<template>
<div class="uploadList">
<div class="uploadList_box">
<div class="content_img_item" v-for="(file,index) in uploadList" :key="file.id">
<div class="content_img_item_block" :class="{active:file?.checked}">
<img v-lazy="file.url" :key="file.url" :alt="file.name" @click.stop="selectImgItem(file)"/>
<sketchCategory :disignTypeList="deReconstructionList" :generateList="uploadList" :item="file" :isSetSketchCategory="true" :upDataType="'element'"></sketchCategory>
<i class="fi fi-rr-trash icon_delete" @click="deleteImgItem(file,index)"></i>
</div>
</div>
<div class="upload_item">
<div class="upload" @click="openUpload">
<i class="fi fi-br-upload"></i>
</div>
</div>
</div>
<uploadModel ref="uploadModel" @setUploadImgList="setUploadImgList" :deReconstructionList="deReconstructionList"></uploadModel>
</div>
</template>
<script lang="ts">
import { defineComponent,computed,ref,provide,nextTick,createVNode,toRefs, reactive, onMounted} from 'vue'
import { Https } from "@/tool/https";
import { useStore } from "vuex";
import sketchCategory from "@/component/HomePage/sketchCategory.vue";
import { getCookie } from "@/tool/cookie";
import { message,Upload} from 'ant-design-vue';
import {getUploadUrl} from '@/tool/util'
import { useI18n } from 'vue-i18n'
import uploadModel from "./uploadModel.vue"
export default defineComponent({
components:{
sketchCategory,uploadModel
},
props:{
catecoryList:{
type:Object,
default:()=>[] as any,
required:true
},
level1Type:{
type:String,
default:'' as any,
required:true
},
segmentation:{
type:Object,
default:null as any,
},
segmentationType:{
type:String,
default:'' as any,
},
upLoadHttpsUrl:{//决定上传的入参,是否需要分割
type:String,
default:'' as any,
},
deReconstructionList:{
type:Array,
default:()=>[]
}
},
emits:['selectImgItem'],
setup(props,{emit}) {
const {t} = useI18n();
const store = useStore();
const detailData = reactive({
isShowLoading:false,//懒加载,加载中
uploadList:computed(()=>store.state.HomeStoreModule.deReconstructionUploadImages) as any,
upload:props.segmentation?
props.segmentation:{
isPin: 0,
level1Type: props.level1Type,
gender:store.state.Workspace.probjects.sex ,
timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,
},
token:getCookie("token"),
uploadUrl:getUploadUrl(),
currentDetailType:computed(()=>store.state.DesignDetail.currentDetailType),
})
const dataDom = reactive({
uploadModel:null as any
})
const getDetailListData = reactive({
total:0,
pageSize:10,
currentPage:1,
})
const selectImgItem = (file:any)=>{
// let data = JSON.parse(JSON.stringify(file))
// store.commit('DesignDetail/setNewDetail',file)
emit('selectImgItem',file)
}
const setUploadImgList = (list:any)=>{
if(list.length>0){
detailData.uploadList.push(...list)
}
}
const openUpload = ()=>{
dataDom.uploadModel.init()
}
const deleteImgItem = (item:any,index)=>{
console.log(item)
Https.axiosPost(
Https.httpUrls.elementDelete,
{
id:item.id,
}
).then(res=>{
detailData.uploadList.splice(item.index,1)
})
}
return{
...toRefs(detailData),
...toRefs(dataDom),
...toRefs(getDetailListData),
selectImgItem,
openUpload,
setUploadImgList,
deleteImgItem,
}
},
provide() {
return {
}
},
})
</script>
<style lang="less" scoped>
.uploadList{
height: 100%;
display: flex;
flex-direction: column;
> .uploadList_box{
width: 100%;
flex: 1;
overflow-y: auto;
display: flex;
flex-wrap: wrap;
margin-top: 1rem;
justify-content: space-between;
align-content: flex-start;
&::-webkit-scrollbar{display: none;}
> .content_img_item{
> .content_img_item_block{
width: calc((34rem - 2rem) / 2);
height: calc((34rem - 2rem) / 2);
position: relative;
margin-bottom: 2rem;
> img{
cursor: pointer;
width: 100%;
height: 100%;
object-fit: contain;
}
&:hover{
> .icon_delete{
opacity: 1;
}
}
> .icon_delete{
position: absolute;
right: 1rem;
top: 1rem;
font-size: 1.8rem;
cursor: pointer;
opacity: 0;
}
}
}
> .material_content_list_loding{
width: 100%;
height: calc((34rem - 2rem) / 2);
}
> .upload_item{
width: calc((34rem - 2rem) / 2);
height: calc((34rem - 2rem) / 2);
align-items: center;
justify-content: center;
.upload{
cursor: pointer;
width: calc(6rem * 1.2);
height: calc(6rem * 1.2);
border: calc(0.3rem * 1.2) solid #000;
border-radius: calc(1rem * 1.2);
display: flex;
align-items: center;
justify-content: center;
i{
font-size: 2rem;
display: flex;
color: #000;
}
}
}
}
}
</style>

View File

@@ -0,0 +1,161 @@
<template>
<div class="print">
<div class="detailText">{{$t('DesignPrintOperation.CurrentPrint')}}</div>
<div class="select_print">
<img :class="{active:printList.length == 1}" v-for="item in printList" @click="addElement(item)" :src="item.path" alt="">
<!-- <img :src="selectDetail.path" alt="">
{{ selectDetail }} -->
<div v-if="printList.length == 0">
<i class="fi fi-rr-picture centent"></i>
</div>
</div>
<selectList @selectImgItem="selectImgItem" level1Type="Printboard" type="print" :catecoryList="printCatecoryList"></selectList>
</div>
</template>
<script lang="ts">
import { defineComponent,computed,ref,watch,nextTick,createVNode,toRefs, reactive} from 'vue'
// import setDesignItem from '@/component/Detail/setDesignItem2.vue'
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { Https } from "@/tool/https";
import { useStore } from "vuex";
import { useI18n } from 'vue-i18n'
// import sketchCategory from "@/component/HomePage/sketchCategory.vue";
import selectList from './module/selectList.vue'
export default defineComponent({
components:{
selectList,
},
setup(props,{emit}) {
const store = useStore();
const detailData = reactive({
selectTitle:'current',
selectDetail:computed(()=>store.state.DesignDetail.selectDetail),
printCatecoryList:computed(()=>{
return store.state.UserHabit.printType
}),
printList:[],
currentDetailType:computed(()=>store.state.DesignDetail.currentDetailType)
})
watch(()=>detailData?.selectDetail?.printObject?.prints,(newVal,oldVal)=>{
if(!newVal)return
detailData.printList = newVal.reduce((acc:any, curr:any) => {
if (!acc.some((item:any) => item.minIOPath === curr.minIOPath)) {
acc.push(curr);
}
return acc;
}, []);
},{immediate: true})
const getDetailListData = reactive({
total:0,
pageSize:10,
currentPage:1,
})
const getDetailListDom = reactive({
libraryList:null as any,
})
const openCurrent = ()=>{
detailData.selectTitle = 'current'
}
const openUpload = ()=>{
detailData.selectTitle = 'upload'
}
const openLibrary = ()=>{
detailData.selectTitle = 'library'
getDetailListDom.libraryList.init()
}
const addElement = (data:any)=>{
let value = {
designType:data.designType,
level2Type:data.level2Type,
minIOPath:data.minIOPath,
url:data.path,
}
store.commit('DesignDetail/setCurrentPrintElement',value)
}
const selectImgItem = (data:any)=>{
let value = {
data,
}
if(detailData.currentDetailType != 'print' && detailData.currentDetailType != 'element'){
store.commit('DesignDetail/setNewDetail',value)
}else{
store.commit('DesignDetail/setCurrentPrintElement',null)
store.commit('DesignDetail/setCurrentPrintElement',data)
}
}
return{
...toRefs(detailData),
...toRefs(getDetailListData),
...toRefs(getDetailListDom),
openCurrent,
openUpload,
openLibrary,
selectImgItem,
addElement,
}
},
provide() {
return {
}
},
})
</script>
<style lang="less" scoped>
.print{
// width: 34rem;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
> .detailText{
margin-bottom: 1rem;
}
> .select_print{
width: 100%;
height: 23.5rem;
padding: 1rem;
text-align: center;
border-radius: .5rem;
// border: 1px dashed #202020;
border: 1px dashed transparent;
background: linear-gradient(#fff, #fff) padding-box,repeating-linear-gradient(-45deg,#fff 0,#fff 0.3em, #000 0,#000 0.6em);
margin-bottom: 3rem;
display: flex;
flex-wrap: wrap;
overflow: hidden;
justify-content: space-between;
overflow-y: auto;
justify-content: flex-start;
> img{
object-fit: contain;
height: 9rem;
width: 9rem;
overflow-y: auto;
margin-bottom: 1rem;
margin: 1rem;
cursor: pointer;
}
> .active{
width: 100%;
height: 100%;
margin: 0;
margin-bottom: 0;
}
> div{
height: 100%;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
> i{
font-size: 10rem;
}
}
}
}
</style>

View File

@@ -0,0 +1,181 @@
<template>
<div class="sketch">
<div class="detailText">{{$t('DesignPrintOperation.CurrentSketch')}}</div>
<div class="select_sketch" v-if="selectDetail.id">
<!-- <img :src="selectDetail?.sketchString?selectDetail?.sketchString:selectDetail.path" alt=""> -->
<img :src="selectDetail.path" alt="">
<!-- <img :src="selectDetail.sketchString || selectDetail.path" alt=""> -->
<i :title="$t('DesignDetail.editSketchTitle')" class="fi fi-rs-pencil-paintbrush" @click.stop="openAddDetail"></i>
</div>
<div class="select_sketch" v-else>
<div>
<i class="fi fi-rr-picture centent"></i>
</div>
</div>
<selectList @selectImgItem="selectImgItem" source="detail" level1Type="Sketchboard" type="sketch" :catecoryList="sketchCatecoryList"></selectList>
</div>
</template>
<script lang="ts">
import { defineComponent,computed,ref,provide,nextTick,createVNode,toRefs, reactive} from 'vue'
// import setDesignItem from '@/component/Detail/setDesignItem2.vue'
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { Https } from "@/tool/https";
import { useStore } from "vuex";
import { useI18n } from 'vue-i18n'
// import sketchCategory from "@/component/HomePage/sketchCategory.vue";
import selectList from './module/selectList.vue'
export default defineComponent({
components:{
selectList,
},
emit:['addDetail'],
setup(props,{emit}) {
const store = useStore();
const detailData = reactive({
selectTitle:'current',
selectDetail:computed(()=>store.state.DesignDetail.selectDetail),
sketchCatecoryList:computed(()=>{
return store.state.Workspace.probjects.positionList
}),
currentDetailType:computed(()=>store.state.DesignDetail.currentDetailType)
})
const getDetailListData = reactive({
total:0,
pageSize:10,
currentPage:1,
})
const getDetailListDom = reactive({
libraryList:null as any,
})
const openCurrent = ()=>{
detailData.selectTitle = 'current'
}
const openUpload = ()=>{
detailData.selectTitle = 'upload'
}
const openLibrary = ()=>{
detailData.selectTitle = 'library'
getDetailListDom.libraryList.init()
}
const selectImgItem = (data:any)=>{
console.log(data)
if(data?.imgUrl)data.url = data.imgUrl
let value = {
data,
}
if(detailData.currentDetailType == 'sketch'){
detailData.selectDetail.sketchString = ''
}
store.commit('DesignDetail/setNewDetail',value)
}
const openAddDetail = ()=>{
emit('addDetail')
}
return{
...toRefs(detailData),
...toRefs(getDetailListData),
...toRefs(getDetailListDom),
openCurrent,
openUpload,
openLibrary,
selectImgItem,
openAddDetail,
}
},
provide() {
return {
}
},
})
</script>
<style lang="less" scoped>
.sketch{
// width: 34rem;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
> .detailText{
margin-bottom: 1rem;
text-align: left;
}
> .select_sketch{
width: 100%;
height: 23.5rem;
padding: 1rem 0;
text-align: center;
border-radius: .5rem;
// border: 1px dashed #202020;
border: 1px dashed transparent;
position: relative;
background: linear-gradient(#fff, #fff) padding-box,repeating-linear-gradient(-45deg,#fff 0,#fff 0.3em, #000 0,#000 0.6em);
margin-bottom: 3rem;
> img{
width: 100%;
height: 100%;
object-fit: contain;
}
> i{
position: absolute;
left: auto;
right: 1rem;
top: 2rem;
font-size: 2rem;
cursor: pointer;
}
> div{
height: 100%;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
> i{
font-size: 10rem;
}
}
}
> .switch_type_list{
display: flex;
margin-bottom: 2.5rem;
> .switch_type_item:last-child{
margin-right: 0;
}
> .switch_type_item{
position: relative;
cursor: pointer;
margin-right: 6.5rem;
}
> .switch_type_item::before {
position: absolute;
content: "";
display: block;
background: #000;
height: calc(.4rem*1.2);
left: 50%;
transform: translateX(-50%);
bottom: -.5rem;
width: 0px;
transition: 0.3s all;
}
> .select_swtich {
color: #000;
font-weight: 600;
}
> .select_swtich::before {
width: 100%;
}
}
> .sketch_content_list{
flex: 1;
overflow: hidden;
> .content_item{
height: 100%;
margin-top: 1rem;
}
}
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,116 @@
<template>
<div class="detailRight">
<!-- <div class="detailText">Current Print</div>
<div class="select_sketch">
<img src="https://develop.aida.com.hk/img/aida_logo_centent.b8a50882.jpg" alt="">
</div> -->
<sketchType v-if="currentDetailType === 'sketch'"></sketchType>
<!-- <printType v-if="currentDetailType === 'print'"></printType> -->
<editPrintElement ref="editPrintElement" v-if="currentDetailType === 'print'" type="print"></editPrintElement>
<editPrintElement ref="editPrintElement" v-if="currentDetailType === 'element'" type="element"></editPrintElement>
<modelsType ref="modelsType" v-if="currentDetailType === 'models'"></modelsType>
</div>
</template>
<script lang="ts">
import { defineComponent,computed,ref,provide,nextTick,createVNode,toRefs, reactive} from 'vue'
// import setDesignItem from '@/component/Detail/setDesignItem2.vue'
import { useStore } from "vuex";
import sketchType from './sketchType.vue'
import printType from './printType.vue'
import editPrintElement from './editPrintElement.vue'
import modelsType from './modelsType.vue'
export default defineComponent({
components:{
sketchType,printType,editPrintElement,modelsType
},
setup(props,{emit}) {
const store = useStore();
const detailData = reactive({
designDetail:computed(()=>store.state.DesignDetail.designDetail),
editPrintElement:null as any,
selectDetail:computed(()=>store.state.DesignDetail.selectDetail),
currentDetailType:computed(()=>store.state.DesignDetail.currentDetailType),
})
const privewDetail = ()=>{
if(detailData.editPrintElement?.previewDetailPrintData)detailData.editPrintElement.previewDetailPrintData()
}
return{
...toRefs(detailData),
privewDetail,
}
},
provide() {
return {
}
},
})
</script>
<style lang="less" scoped>
.detailRight{
height: 100%;
display: flex;
flex: 1;
overflow: hidden;
flex-direction: column;
> .detailText{
margin-bottom: 1rem;
}
> .select_sketch{
width: 100%;
height: 23.5rem;
padding: 1rem 0;
text-align: center;
border-radius: .5rem;
// border: 1px dashed #202020;
border: 1px dashed transparent;
background: linear-gradient(#fff, #fff) padding-box,repeating-linear-gradient(-45deg,#fff 0,#fff 0.3em, #000 0,#000 0.6em);
margin-bottom: 3rem;
> img{
width: 100%;
height: 100%;
object-fit: contain;
}
}
> .switch_type_list{
display: flex;
margin-bottom: 2.5rem;
> .switch_type_item:nth-child(1){
margin-right: 6.5rem;
}
> .switch_type_item{
position: relative;
cursor: pointer;
}
> .switch_type_item::before {
position: absolute;
content: "";
display: block;
background: #000;
height: calc(.4rem*1.2);
left: 50%;
transform: translateX(-50%);
bottom: -.5rem;
width: 0px;
transition: 0.3s all;
}
> .select_swtich {
color: #000;
font-weight: 600;
}
> .select_swtich::before {
width: 100%;
}
}
> .sketch_content_list{
flex: 1;
overflow: hidden;
> .content_item{
height: 100%;
margin-top: 1rem;
}
}
}
</style>

View File

@@ -0,0 +1,67 @@
<template>
<div class="sketchType" v-show="designDetail?.newModel">
<div class="detailText">{{$t('DesignPrintOperation.NewModel')}}</div>
<div class="sketchContent">
<img :src="designDetail.newModel?.url" alt="">
</div>
</div>
</template>
<script lang="ts">
import { defineComponent,computed,ref,provide,nextTick,createVNode,toRefs, reactive} from 'vue'
// import setDesignItem from '@/component/Detail/setDesignItem2.vue'
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { Https } from "@/tool/https";
import { useStore } from "vuex";
import { useI18n } from 'vue-i18n'
export default defineComponent({
components:{
},
setup(props,{emit}) {
const store = useStore();
const detailData = reactive({
designDetail:computed(()=>store.state.DesignDetail.designDetail),
currentDetailType:computed(()=>store.state.DesignDetail.currentDetailType),
})
const getDetailListData = reactive({
})
const getDetailListDom = reactive({
})
return{
...toRefs(detailData),
...toRefs(getDetailListData),
...toRefs(getDetailListDom),
}
},
provide() {
return {
}
},
})
</script>
<style lang="less" scoped>
.sketchType{
margin: auto 0;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
> .detailText{
margin-bottom: 1rem;
text-align: left;
}
> .sketchContent{
flex: 1;
display: flex;
align-items: center;
> img{
width: 100%;
object-fit: contain;
max-height: 60rem;
}
}
}
</style>

View File

@@ -0,0 +1,112 @@
<template>
<div class="printType">
<div class="detailText">{{$t('DesignPrintOperation.NewPrint')}}</div>
<div class="printContent">
<div>
<div class="content_img_item" v-for="(file) in selectList" :key="file.id">
<div class="content_img_item_block" :class="{active:file?.checked}">
<img v-lazy="file.path" :key="file.path" :alt="file.name"/>
<sketchCategory :disignTypeList="sketchCatecoryList" :generateList="selectList" :item="file" :isSpread="true"></sketchCategory>
</div>
</div>
<div v-if="selectDetail?.newDetail?.[currentDetailType]" class="content_img_item" v-for="(file) in selectDetail.newDetail?.[currentDetailType]" :key="file.id">
<div class="content_img_item_block" :class="{active:file?.checked}">
<img v-lazy="file.url" :key="file.paurlth" :alt="file.name"/>
<sketchCategory :disignTypeList="sketchCatecoryList" :generateList="selectDetail.newDetail?.[currentDetailType]" :item="file" :isSpread="true"></sketchCategory>
</div>
</div>
<!-- <img v-for="item in selectList" :src="item.path" alt="">
<img v-for="item in selectDetail?.newDetail?.[currentDetailType]?selectDetail.newDetail?.[currentDetailType]:[]" :src="item?.url" :key="item" :title="selectDetail.type" alt=""> -->
</div>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent,computed,ref,watch,nextTick,createVNode,toRefs, reactive} from 'vue'
// import setDesignItem from '@/component/Detail/setDesignItem2.vue'
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { useStore } from "vuex";
import { useI18n } from 'vue-i18n'
import sketchCategory from "@/component/HomePage/sketchCategory.vue";
export default defineComponent({
components:{
sketchCategory
},
setup(props,{emit}) {
const store = useStore();
const detailData = reactive({
sketchCatecoryList:computed(()=>{
return store.state.UserHabit.printType
}),
selectDetail:computed(()=>store.state.DesignDetail.selectDetail),
currentDetailType:computed(()=>store.state.DesignDetail.currentDetailType),
selectList:[],
})
watch(()=>detailData.selectDetail?.printObject?.prints,(newVal,oldVal)=>{
detailData.selectList = newVal.reduce((acc:any, curr:any) => {
if (!acc.some((item:any) => item.id === curr.id)) {
acc.push(curr);
}
return acc;
}, []);
},{immediate: true})
const getDetailListData = reactive({
})
const getDetailListDom = reactive({
})
return{
...toRefs(detailData),
...toRefs(getDetailListData),
...toRefs(getDetailListDom),
}
},
provide() {
return {
}
},
})
</script>
<style lang="less" scoped>
.printType{
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
> .detailText{
margin-bottom: 1rem;
}
> .printContent{
flex: 1;
overflow: hidden;
> div{
max-height: 100%;
display: flex;
flex-wrap: wrap;
overflow-y: auto;
// display: flex;
// flex-wrap: wrap;
> .content_img_item{
margin: 1rem;
> .content_img_item_block{
width: 30rem;
height: 30rem;
position: relative;
> img{
cursor: pointer;
width: 100%;
height: 100%;
object-fit: contain;
}
}
}
}
}
}
</style>

View File

@@ -0,0 +1,67 @@
<template>
<div class="sketchType" v-show="selectDetail?.newDetail?.[currentDetailType] || selectDetail.sketchString">
<div class="detailText">{{$t('DesignPrintOperation.NewApparel')}}</div>
<div class="sketchContent">
<img :src="(selectDetail?.newDetail?.[currentDetailType]?selectDetail.newDetail?.[currentDetailType].url:selectDetail.sketchString)" :title="selectDetail.type" alt="">
</div>
</div>
</template>
<script lang="ts">
import { defineComponent,computed,ref,provide,nextTick,createVNode,toRefs, reactive} from 'vue'
// import setDesignItem from '@/component/Detail/setDesignItem2.vue'
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { Https } from "@/tool/https";
import { useStore } from "vuex";
import { useI18n } from 'vue-i18n'
export default defineComponent({
components:{
},
setup(props,{emit}) {
const store = useStore();
const detailData = reactive({
selectDetail:computed(()=>store.state.DesignDetail.selectDetail),
currentDetailType:computed(()=>store.state.DesignDetail.currentDetailType),
})
const getDetailListData = reactive({
})
const getDetailListDom = reactive({
})
return{
...toRefs(detailData),
...toRefs(getDetailListData),
...toRefs(getDetailListDom),
}
},
provide() {
return {
}
},
})
</script>
<style lang="less" scoped>
.sketchType{
margin: auto 0;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
> .detailText{
margin-bottom: 1rem;
text-align: left;
}
> .sketchContent{
flex: 1;
display: flex;
align-items: center;
> img{
width: 100%;
object-fit: contain;
max-height: 60rem;
}
}
}
</style>

View File

@@ -1,447 +0,0 @@
<template>
<div class="editFrontBack_center">
<!-- <div class="editFrontBack_center_btn editFrontBack_center_item" :class="{spread:spreadState}">
<i class="icon iconfont icon-chehui" @click="historyState('')"></i>
<i class="icon iconfont icon-fanchehui" @click="historyState('reverse')"></i>
<i class="icon iconfont icon-bianji" @click="setOperation('pencil')" :class="{active:canvasState == 'pencil'}"></i>
<div class="editFrontBack_center_btn_colorRed" @click="setOperationColor('rgb(255,0,0)')" :class="{active:(canvasState != 'eraser' && rgba == 'rgb(255,0,0)')}" title="front">front</div>
<div class="editFrontBack_center_btn_colorGreen" @click="setOperationColor('rgb(0,255,0)')" :class="{active:(canvasState != 'eraser' && rgba == 'rgb(0,255,0)')}" title="back">back</div>
<div class="editFrontBack_center_btn_colorWhite" @click="setOperation('eraser')" :class="{active:canvasState == 'eraser'}" title="background">background</div>
<input type="range" v-show="canvasState != 'move'" @input="setPencilWidth" min="1" max="50" v-model="canvasPencilWidth[canvasState]">
</div> -->
<div class="exportCanvasBox_center_box">
<div class="exportCanvasBox_center">
<div class="editFrontBack_bgImg" v-show="loadingShow">
<img :src="imgData?.undividedLayer" alt="">
</div>
<div class="editFrontBack_pencilbtn" v-show="loadingShow" :style="frontBackCanvasObj.pencilbtnStyle" style="display: block;"></div>
</div>
<!-- <div class="editFrontBack_pencilbtn" v-show="loadingShow" :style="pencilbtnStyle"></div> -->
<!--
<div class="editFrontBack_pencilbtn" v-show="loadingShow" :style="frontBackCanvasObj.pencilbtnStyle" style="display: block;"></div>
{{frontBackCanvasObj.pencilbtnStyle}} -->
</div>
</div>
</template>
<script>
import { defineComponent, ref, reactive, inject, onMounted, nextTick, toRefs, onBeforeUnmount, watch, computed } from "vue";
import { formatTime,segmentImage } from "@/tool/util";
import { exportSele,JSRectUpdata,JSchangeType,JScanvasMouseDown,JSSetRemoveImage,JScreateCheck,JSSetTexture } from "@/tool/canvasDrawing";
import { getMousePosition } from "@/tool/mdEvent";
import { useStore } from "vuex";
import { useI18n } from "vue-i18n";
export default defineComponent({
components: {
},
// emits: ['setSloganData'],
props:['patchData','imgDomIndex'],
setup(props,{emit}) {
const store = useStore();
let presentState = ref('paypal');
let loadingShow = ref(false);
let { t } = useI18n();
// let canvas = new frontBackCanvasObjCopy();
let canvas = null;
let frontBackCanvasObj = inject('frontBackCanvasObj')
let ratio = [1,1]
let exportWH = 0
let imgData = ref()
let pencilbtnStyle = ref({
background:'',
width:0+'px',
height:0+'px',
display:'none',
left:0+'px',
top:0+'px',
})
let selectDetail = computed(()=>store.state.DesignDetailCopy.selectDetail)
// let a = computed(()=>{
// console.log(123);
// return props.patchData
// })
watch(()=>pencilbtnStyle.value.background,(newVal)=>{
frontBackCanvasObj.brushwork.color = newVal
frontBackCanvasObj.setPencilColor()
})
onMounted(()=>{
props.patchData.front.imageUrl= ''
clearTimeout(setTimeSubmit)
// init(props.patchData.front[props.imgDomIndex],'')
})
let canvasBtn = reactive({
canvasState:'move',
canvasPencilWidth:{
pencil:20,
eraser:20,
},
spreadState:false,
})
let canvasWH = ref(0);
let reverseCanvasState = ref([])//存放canvas操作
let normalCanvasState = ref([])//存放canvas操作
let down = false
let init = (data,index)=>{
normalCanvasState.value = []
reverseCanvasState.value = []
ratio = [1,1]
imgData.value = data
nextTick(()=>{
let contentBox = document.querySelector(".editFrontBack_center");
let canvasBox = document.querySelector(".editFrontBack_center .exportCanvasBox_center");
let editFrontBack_bgImg = document.querySelector(".editFrontBack_center .editFrontBack_bgImg");
document.removeEventListener('mousemove', mouseMove);
document.removeEventListener('touchmove', touchmove);
let img = new Image();
img.onload = async function(){
loadingShow.value = true
let scale
let wScale = 1
let hScale = 1
let styleWidth = Number(data.style.width.split('px')[0])
let styleHeight = Number(data.style.height.split('px')[0])
let width = contentBox.offsetWidth;
let height = contentBox.offsetHeight;
if(styleWidth>styleHeight){
hScale = styleHeight/styleWidth
exportWH = img.width
canvasWH.value = width
scale = img.height/img.width
console.log(width,scale)
canvasBox.style.height = width * scale+'px'
}else{
wScale = styleWidth/styleHeight
exportWH = img.height
canvasWH.value = height
scale = img.width/img.height
canvasBox.style.width = height * scale+'px'
}
editFrontBack_bgImg.style.width = canvasWH.value * wScale+'px'
editFrontBack_bgImg.style.height = canvasWH.value * hScale+'px'
ratio = [wScale,hScale]
await frontBackCanvasObj.canvasInit(canvasBox,{
width:canvasWH.value * wScale,
height:canvasWH.value * hScale,
},data.maskUrl,'',{noWheel:true})
// undividedLayer
canvas = frontBackCanvasObj.canvas
frontBackCanvasObj.setOperation('pencil')
pencilbtnStyle.value.background = rgba.value
// console.log(frontBackCanvasObj,frontBackCanvasObj.setPencilWidth);
frontBackCanvasObj.setPencilWidth()
fabric.Object.prototype.cornerSize = 10
fabric.Object.prototype.transparentCorners = false
// await frontBackCanvasObj.addPartImg({minioUrl:data.maskUrl},'',{opacity: 0.5})
// await new Promise((resolve, reject) => {
// fabric.Image.fromURL(data.maskUrl, function(img) {
// // 设置背景图对象的宽度和高度与 canvas 相同
// canvas.add(img)
// resolve('')
// },{ crossOrigin: "Anonymous" });
// })
//画布上移动
// canvas.on("mouse:move", event =>setCanvasMove(event));
canvas.on('mouse:up', (event)=> {
updateCanvasState('mouseUp')
});
document.addEventListener('mousemove', mouseMove);
document.addEventListener('touchmove', touchmove);
createSetTimeSubmit()
img.remove()
}
img.src = data.maskUrl
})
}
const setBackground = (value)=>{
if(value == 'background'){
frontBackCanvasObj.setOperation('eraser')
}else{
frontBackCanvasObj.setOperation('pencil')
frontBackCanvasObj.brushwork.color = value
frontBackCanvasObj.pencilColor()
}
}
let updateCanvasState = (str) =>{
if(str != 'mouseUp'){
// editFrontBackPencilbtn.value.style.display = 'none'
}else{
clearTimeout(setTimeSubmit)
setTimeSubmit = setTimeout(()=>{
createSetTimeSubmit()
},1000)
}
}
let setClone = ()=>{
let canvasBox = document.querySelector(".editFrontBack_center .exportCanvasBox_center");
let oldCanvasDom = canvasBox.querySelector('.canvas-container')
let oldCanvasDom1 = canvasBox.querySelector('canvas')
if(oldCanvasDom)oldCanvasDom.remove()
if(oldCanvasDom1)oldCanvasDom1.remove()
loadingShow.value = false
}
let rgba = ref('#ff0000')
let mouseMove = (event)=>{
let e = getMousePosition(event,false)
setCanvasMove(e)
}
let touchmove = (event)=>{
let e = getMousePosition(event,true)
setCanvasMove(e)
}
let setCanvasMove = (event)=>{
if(canvas.isDrawingMode && canvas){
canvas.setCursor('none');
}
let canvasCenterBox = document.querySelector(".editFrontBack_center .exportCanvasBox_center_box");
if(!canvasCenterBox)return
let parentX = event.clientX - canvasCenterBox.getBoundingClientRect().left
let parentY = event.clientY - canvasCenterBox.getBoundingClientRect().top
pencilbtnStyle.value.left = parentX + "px"
pencilbtnStyle.value.top = parentY+'px'
}
let mousedown = (e)=>{
if(e.target instanceof HTMLCanvasElement){
down = true
}
}
let mouseup = (e)=>{
if(down){
nextTick(()=>{
createSetTimeSubmit()
})
}
down = false
}
let setTimeSubmit = null
let createSetTimeSubmit = ()=>{
setSubmit()
}
//撤回
let setSubmit = async ()=>{
// let data = await frontBackCanvasObj.allExport()
let data = await frontBackCanvasObj.detailSubmit()
// props.props.patchData.front[imgDomIndex].imageUrl = data
let mark = data
let full = props.patchData.front[props.imgDomIndex].undividedLayer
let size = {
width: Math.round(exportWH * ratio[0]),
height: Math.round(exportWH * ratio[1]),
}
segmentImage(mark,full,size).then((rv)=>{
props.patchData.front[props.imgDomIndex].imageUrl = rv.targetFrontUrl
props.patchData.back[props.imgDomIndex].imageUrl = rv.targetBackUrl
props.patchData.front[props.imgDomIndex].maskUrl = data
store.commit('DesignDetailCopy/updataDetailItem',{maskUrl:data})
})
}
onBeforeUnmount(()=>{
frontBackCanvasObj.canvasClear()
document.removeEventListener('mousemove', mouseMove);
document.removeEventListener('touchmove', touchmove);
document.removeEventListener('mousedown', mousedown);
document.removeEventListener('mouseup', mouseup);
})
return {
frontBackCanvasObj,
presentState,
loadingShow,
imgData,
pencilbtnStyle,
t,
...toRefs(canvasBtn),
setBackground,
init,
setSubmit,
setClone,
};
},
data() {
return {
};
},
mounted() {},
methods: {
},
});
</script>
<style lang="less" scoped>
.editFrontBack_center{
position: relative;
// width: calc(512px / 2);
// width: 256px;
height: 100%;
width: 100%;
display: flex;
flex-direction: column;
// height: calc(512px / 2);
margin: 0 auto;
.editFrontBack_center_item{
// position: relative;
background: #ffffff;
position: absolute;
display: flex;
border: 0.2rem solid #c4c4c4;
width: 35rem;
border-radius: 4px; /* 设置圆角半径 */
flex-wrap: wrap;
align-items: center;
.editFrontBack_center_btn_item{
display: flex;
align-items: center;
padding: 1rem 0;
}
}
.editFrontBack_center_btn{
z-index: 2;
left: 50%;
// transform: translate(-50%,-135%);
// transition: all .3s;
padding: 1rem 1.5rem;
transform: translate(-50%,0);
position: relative;
width: 100%;
flex-direction: row;
input{
// width: 100%;
flex: 1;
max-width: 30%;
}
.icon-xiala{
position: absolute;
width: 2rem;
bottom: 0;
transform: translate(-50%, 90%);
left: 50%;
width: 6rem;
background: #fff;
text-align: center;
cursor: pointer;
&.icon-xiala::before{
transition: all .3s;
}
&.btnRotate::before{
transform: rotate(180deg);
display: block;
}
}
.editFrontBack_center_btn_colorRed,.editFrontBack_center_btn_colorGreen,.editFrontBack_center_btn_colorWhite{
width: 9rem;
line-height: 3rem;
text-align: center;
height: 3rem;
border-radius: 4px;
margin: 0 .5rem;
cursor: pointer;
padding: .5rem 1;
border: 1px solid rgba(0,0,0,.5);
&.active{
border: 2px solid;
border-radius: .4rem;
}
}
.editFrontBack_center_btn_colorRed{
background: rgba(255,0,0);
}
.editFrontBack_center_btn_colorGreen{
background: rgba(0,255,0);
}
.editFrontBack_center_btn_colorWhite{
background: rgba(255,255,255);
}
i{
font-size: 2.5rem;
cursor: pointer;
width: 4rem;
height: 4rem;
display: flex;
align-items: center;
justify-content: center;
&.active{
border: 1px solid;
border-radius: .4rem;
}
}
&.spread{
transform: translate(-50%,0);
}
}
.exportCanvasBox_center_box{
height: 100%;
flex: 1;
position: relative;
overflow: hidden;
width: 100%;
background: #e6e6e6;
cursor: auto;
display: flex;
align-items: center;
&:hover{
cursor: none;
}
.editFrontBack_pencilbtn{
position: absolute;
z-index: 1;
border-radius: 50%;
border: 1px solid #000;
pointer-events: none;
transform: translate(-50%,-50%);
}
}
.exportCanvasBox_center{
margin: 0 auto;
overflow: hidden;
height: 100%;
position: relative;
// overflow: scroll;
cursor: none;
:deep(.canvas-container){
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
// opacity: .5;
// background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC);
}
.editFrontBack_bgImg{
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
z-index: 2;
pointer-events:none;
opacity: .5;
img{
height: 100%;
width: 100%;
}
}
}
.exportCanvasBox_center:hover{
.editFrontBack_center_btn{
transform: translate(-50%,-101%);
&.spread{
transform: translate(-50%,0);
}
}
}
}
</style>

View File

@@ -1,155 +0,0 @@
<template>
<div class="magnifyingGlass">
<div class="initial">
<div class="initial_mask" v-mousemove>
<img class="initial_img" :src="imageUrl" alt="">
<div class="initial_haver"></div>
</div>
</div>
<div class="big"></div>
</div>
</template>
<script>
import { getUploadUrl,isMoible } from "@/tool/util";
import { defineComponent, createVNode, ref,Ref} from "vue";
import { UserOutlined, DownOutlined } from "@ant-design/icons-vue";
export default defineComponent({
components: {
DownOutlined,
UserOutlined,
},
props: ['designItemDetailUrl'],
setup(props){
let imageUrl = ref()
let showGlass = ref(false)
return{
imageUrl,
showGlass
}
},
watch:{
},
data() {
return {
};
},
mounted() {
},
directives:{
mousemove:{
mounted (el,binding) {
if(isMoible()){
let touchstart = (event)=>{//移入
const mask = document.getElementsByClassName('magnifyingGlass')[0].querySelector('.initial_haver')
const initialImg = document.getElementsByClassName('magnifyingGlass')[0].querySelector(".initial_img");
const bigImg = document.getElementsByClassName('magnifyingGlass')[0].querySelector(".big");
const maskW = mask.getBoundingClientRect().width;
const bigImgW = bigImg.getBoundingClientRect().width;
const num = bigImgW / maskW
bigImg.style.backgroundImage = `url(${initialImg.src})`;
const { left, top} = initialImg.getBoundingClientRect();
const initialImgH = initialImg.getBoundingClientRect().height
const initialImgW = initialImg.getBoundingClientRect().width;
const {width,height} = mask.getBoundingClientRect();
let touchmove = (event)=>{//移动
const x = event.targetTouches[0].pageX - left;
const y = event.targetTouches[0].pageY - top;
const bgPosX = (-x+width/2 )* num;
const bgPosY = (-y+height/2) * num;
const bgPosW = initialImgW * num;
const bgPosH = initialImgH * num;
mask.style.top = y-height/2+'px';
mask.style.left = x-width/2+'px';
bigImg.style.backgroundPosition = `${bgPosX}px ${bgPosY}px`;
bigImg.style.backgroundSize = `${bgPosW}px ${bgPosH}px`;
}
document.addEventListener('touchmove',touchmove,{passive:true})
el.addEventListener('touchend',()=>{
document.removeEventListener('touchmove',touchmove)
document.removeEventListener('touchstart',touchstart)
})
}
el.addEventListener('touchstart',touchstart)
}else{
let mouseover = (event)=>{//移入
const mask = document.getElementsByClassName('magnifyingGlass')[0].querySelector('.initial_haver')
const initialImg = document.getElementsByClassName('magnifyingGlass')[0].querySelector(".initial_img");
const bigImg = document.getElementsByClassName('magnifyingGlass')[0].querySelector(".big");
const maskW = mask.getBoundingClientRect().width;
const bigImgW = bigImg.getBoundingClientRect().width;
const num = bigImgW / maskW
bigImg.style.backgroundImage = `url(${initialImg.src})`;
const { left, top} = initialImg.getBoundingClientRect();
const initialImgH = initialImg.getBoundingClientRect().height
const initialImgW = initialImg.getBoundingClientRect().width;
const {width,height} = mask.getBoundingClientRect();
let mousemove = (event)=>{//移动
const x = event.clientX - left;
const y = event.clientY - top;
const bgPosX = (-x+width/2 )* num;
const bgPosY = (-y+height/2) * num;
const bgPosW = initialImgW * num;
const bgPosH = initialImgH * num;
mask.style.top = y-height/2+'px';
mask.style.left = x-width/2+'px';
bigImg.style.backgroundPosition = `${bgPosX}px ${bgPosY}px`;
bigImg.style.backgroundSize = `${bgPosW}px ${bgPosH}px`;
}
document.addEventListener('mousemove',mousemove)
el.addEventListener('mouseout',()=>{
document.removeEventListener('mousemove',mousemove)
document.removeEventListener('mouseover',mouseover)
})
}
el.addEventListener('mouseover',mouseover)
}
},
},
},
methods: {
handleMouseMove(event) {
},
},
});
</script>
<style lang="less" scoped>
.magnifyingGlass{
height: 100%;
width: 100%;
display: flex;
justify-content: center;
.initial{
justify-content: center;
width: 40%;
text-align: center;
.initial_mask{
overflow: hidden;
width: auto;
height: 100%;
display: inline-block;
position: relative;
.initial_img{
height: 100%;
width: auto;
max-width: 100%;
}
.initial_haver{
width: calc(10rem*1.2);
height: calc(10rem*1.2);
position: absolute;
background-color: rgba(0,0,0,.2);
top: 0;
}
}
}
.big{
width: 40%;
background-position: 0 0;
background-repeat: no-repeat;
}
}
</style>

View File

@@ -0,0 +1,202 @@
<template>
<div class="modelindex">
<div class="modelindex_left">
<modelNav @canvasReload="()=>$emit('canvasReload')" @addSketch="()=>$emit('addSketch')" @deleteItem="deleteItem"></modelNav>
</div>
<div class="modelindex_right">
<div class="detail_btn">
<!-- 全屏 -->
<!-- <i class="fi fi-bs-expand-arrows-alt" @click="showDesignImgDetail('2')"></i> -->
<i v-show="true" class="icon iconfont icon-chehui" @click="revocation"></i>
<i v-show="true" class="icon iconfont icon-fanchehui" @click="oppositeRevocation"></i>
<!-- 编辑 -->
<i class="fi fi-rr-edit" :title="$t('DesignDetail.editTitle')" :class="{active:isEditPattern.value}" @click="showDesignImgDetail('edit')"></i>
<!-- <i class="fi fi-rr-copy" :title="$t('DesignDetail.compareTitle')" :class="{active:imgDesignImg}" @click="mousedownDesignImg"></i> -->
<!-- <i v-show="!body && !deleteShow" :title="$t('DesignDetail.DetailTitle')" class="fi fi-rr-trash" @click="deleteNav(0)"></i>
<i v-show="!body && deleteShow" class="fi fi-br-check" @click="deleteNav(1)"></i> -->
<!-- -->
<i class="fi fi-rr-copy" :title="$t('DesignDetail.compareTitle')" @mousedown="mousedownDesignImg" @mouseup="mousedownDesignImg" @touchstart="mousedownDesignImg" @touchend="mousedownDesignImg"></i>
</div>
<position ref="position" @canvasReload="()=>$emit('canvasReload')" :imgDesignImg=imgDesignImg></position>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent,computed,ref,inject,onBeforeUnmount,createVNode,toRefs, reactive, onMounted} from 'vue'
// import setDesignItem from '@/component/Detail/setDesignItem2.vue'
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { Https } from "@/tool/https";
import { useStore } from "vuex";
import { Modal,message } from 'ant-design-vue';
import { useI18n } from 'vue-i18n'
import position from './modelPosition.vue';
import modelNav from './modelNav.vue';
export default defineComponent({
components:{
position,modelNav
},
emits:['detailEdit','canvasReload','addSketch','revocation','oppositeRevocation'],
setup(props,{emit}) {
const {t} = useI18n()
const store = useStore();
const detailData = reactive({
getCanvasIfEdit:inject('getCanvasIfEdit')as any,
})
const setRevocation:any = inject('setRevocation')
const getDetailListData = reactive({
designDetail:computed(()=>store.state.DesignDetail.designDetail),
isEditPattern:inject('isEditPattern') as any,
imgDesignImg:false,
})
const getDetailListDom = reactive({
libraryList:null as any,
position:null as any,
})
const getSubmitData = (value:any)=>{
return getDetailListDom.position.getSubmitData(value)
}
const showDesignImgDetail = (str:any)=>{
new Promise((resolve, reject) => {
// if(
// getDetailListData.isEditPattern.value&&
// detailData?.getCanvasIfEdit?.fun&&detailData?.getCanvasIfEdit?.fun() > 0
// ){
// Modal.confirm({
// title: t('collectionModal.jsContent2'),
// icon: createVNode(ExclamationCircleOutlined),
// okText: 'Yes',
// cancelText: 'No',
// mask:false,
// centered:true,
// onOk() {
// resolve(true)
// emit('detailEdit',str)
// },
// onCancel(){
// resolve(false)
// }
// });
// }else{
resolve(true)
emit('detailEdit',str)
// }
})
}
const deleteItem = ()=>{
setRevocation()
}
const revocation = ()=>{//撤回
emit('revocation')
getDetailListDom.position.updataPosition()
}
const oppositeRevocation = ()=>{//反撤回
emit('oppositeRevocation')
getDetailListDom.position.updataPosition()
}
//图片按下样子
const mousedownDesignImg = ()=>{
getDetailListData.imgDesignImg = !getDetailListData.imgDesignImg
}
let time = null as any
const handleResize = ()=>{
clearTimeout(time)
time = setTimeout(()=>{
store.commit('DesignDetail/setDesignDetail',getDetailListData.designDetail)
getDetailListDom.position.updataPosition()
},1000)
}
onMounted(()=>{
window.addEventListener('resize', handleResize);
})
onBeforeUnmount(()=>{
window.removeEventListener('resize', handleResize);
})
return{
...toRefs(detailData),
...toRefs(getDetailListData),
...toRefs(getDetailListDom),
getSubmitData,
showDesignImgDetail,
revocation,
deleteItem,
oppositeRevocation,
mousedownDesignImg,
}
},
provide() {
return {
}
},
})
</script>
<style lang="less" scoped>
.modelindex{
width: 100%;
height: 100%;
display: flex;
// padding-top: 3rem;
flex: 1;
overflow: hidden;
.modelindex_right,.modelindex_left{
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
> .modelindex_right{
flex: 1;
overflow: hidden;
> .detail_btn{
width: 100%;
display: flex;
justify-content: space-between;
border-radius: 1rem;
padding: .7rem ;
flex-shrink: 0;
overflow: hidden;
// max-height: 4rem;
position: relative;
z-index: 99;
> i{
font-size: 2rem;
cursor: pointer;
// padding: 1.5rem;
display: flex;
align-items: center;
border-radius: .6rem;
overflow: hidden;
transition: all .3s;
width: 4rem;
height: 4rem;
justify-content: center;
@media (min-width: 1024px) {
font-size: 2.4rem;
}
}
> i:hover{
background: #000000;
color: #fff;
}
> .active{
background: #000000;
color: #fff;
}
}
}
.modelindex_left{
justify-content: center;
}
}
</style>

View File

@@ -0,0 +1,311 @@
<template>
<div class="modelNavBox">
<div class="modelNav" ref="modelNav" :style="{height:prentHeight}">
<div class="modelNav_item item"
v-for="item,index in designDetail.clothes"
:class="{active:(selectDetail && item.id == selectDetail.id)}"
@mousedown.stop="designMousedown(getMousePosition($event,false),item.uniqueId,'disLike')"
@touchstart.passive="designMousedown(getMousePosition($event,true),item.uniqueId,'disLike')"
@click="selectDetailItem(item,index)">
<i v-if="item?.id != selectDetail?.id" class="fi fi-rr-trash" @click.stop="deleteDetailItem(item?.id)"></i>
<img :src="item.path" alt="">
</div>
</div>
<div v-show="singleOveral.value == 'overall'" v-if="(currentDetailType == 'sketch' || currentDetailType == '') && designDetail.clothes.length < 5 " :class="{active:!selectDetail?.id && currentDetailType == 'sketch'}" class="modelNav_item add" @click="addSketch">
+
</div>
</div>
</template>
<script lang="ts">
import { defineComponent,computed,createVNode,inject,watch,onBeforeUnmount,toRefs, reactive} from 'vue'
// import setDesignItem from '@/component/Detail/setDesignItem2.vue'
import { ExclamationCircleOutlined, } from '@ant-design/icons-vue';
import { Https } from "@/tool/https";
import { Modal,message } from 'ant-design-vue';
import { useStore } from "vuex";
import { useI18n } from 'vue-i18n'
import position from './modelPosition.vue';
import { getMousePosition } from "@/tool/mdEvent"
export default defineComponent({
components:{
position,
},
emits:['canvasReload','addSketch','deleteItem'],
setup(props,{emit}) {
const store = useStore();
const {t} = useI18n()
const detailData = reactive({
selectDetail:computed(()=>store.state.DesignDetail.selectDetail),
frontBack_:computed(()=>store.state.DesignDetail.frontBack),
designDetail:computed(()=>store.state.DesignDetail.designDetail),
currentDetailType:computed(()=>store.state.DesignDetail.currentDetailType),
isEditPattern:inject('isEditPattern') as any,
singleOveral:inject('singleOveral') as any,
getCanvasIfEdit:inject('getCanvasIfEdit')as any,
modelNav:null as any,
})
const collItemSize = reactive({
collValue:18,
num:1,
prentHeight:0 as any,
padding:10,
likeStyle:{
},
itemStyle:{
width:0,
height:0,
},
collTime:null as any,
isMove:false,
elList:[] as any,
selectIndex:0,
})
watch(()=>detailData.designDetail.clothes.length,(newVal)=>{
nextTick(()=>{
setItemPosition()
})
},{immediate:true})
const selectDetailItem = (item:any,index:number)=>{
new Promise((resolve, reject) => {
// if(detailData.isEditPattern.value &&
// detailData.selectDetail?.id &&
// detailData?.getCanvasIfEdit?.fun&&detailData?.getCanvasIfEdit?.fun() > 0
// ){
// Modal.confirm({
// title: t('collectionModal.jsContent2'),
// icon: createVNode(ExclamationCircleOutlined),
// okText: 'Yes',
// cancelText: 'No',
// mask:false,
// centered:true,
// onOk() {
// resolve(true)
// emit('canvasReload')
// },
// onCancel(){
// resolve(false)
// }
// });
// }else{
resolve(true)
emit('canvasReload')
// }
}).then((rv)=>{
if(rv)store.commit('DesignDetail/setDesignColthes',item.id)
})
}
const deleteDetailItem = (id:number)=>{
detailData.designDetail.clothes = detailData.designDetail.clothes.filter((item:any)=>item.id != id)
detailData.frontBack_.back = detailData.frontBack_.back.filter((item:any)=>item.id != id)
detailData.frontBack_.front = detailData.frontBack_.front.filter((item:any)=>item.id != id)
emit('deleteItem')
}
const addSketch = ()=>{
if(detailData.currentDetailType != 'sketch')store.commit('DesignDetail/setCurrentDetailType','sketch')
store.commit('DesignDetail/addDesignColthes')
emit('addSketch')
}
const designMousedown = (e:any,uniqueId:number,str:string)=>{
let item:any = collItemSize.elList.filter((item:any)=>item.uniqueId == uniqueId)[0]
if(!item)return
item.el.style.zIndex = 2;
item.el.style.transition = 'all 0s';
let startX = e.clientX,
startY = e.clientY,
top = item.el.offsetTop;
collItemSize.isMove = false
let moveFun = (e:any) => {
collItemSize.isMove = true
let X = 0;
let Y = e.clientY - startY + top;
item.el.style.left = `${X}px`;
item.el.style.top = `${Y}px`;
reRange(item, X, Y,str);
};
let mouseUpFun = ()=>{
document.removeEventListener('mousemove',mouseMove)
document.removeEventListener('touchmove',touchmove)
document.removeEventListener('mouseup',mouseUpFun)
document.removeEventListener('touchend',mouseUpFun)
item.el.style.zIndex = 1;
item.el.style.transition = 'top .5s';
moveItem();
sortDesignCollection()
}
let mouseMove = function(event:any){
let e = getMousePosition(event,false)
moveFun(e)
}
let touchmove = function(event:any){
let e = getMousePosition(event,true)
moveFun(e)
}
document.addEventListener('mousemove',mouseMove)
document.addEventListener('touchmove',touchmove)
document.addEventListener('mouseup',mouseUpFun)
document.addEventListener('touchend',mouseUpFun)
}
//排序 从大到小
const sortDesignCollection = ()=> {
}
const reRange = (item:any, x:number, y:number,str:string)=>{
let elList:any = collItemSize.elList
let index = collItemSize.selectIndex
let width,height,num
num = collItemSize.num
width = collItemSize.itemStyle.width
height = collItemSize.itemStyle.height
let moveIndex = Math.round(x / (width + 10)) + Math.round(y / (height + 10)) * num;
moveIndex = elList.length - 1 - moveIndex
moveIndex = moveIndex < 0 ? 0 : moveIndex;
moveIndex = moveIndex > elList.length - 1 ? elList.length - 1 : moveIndex;
if(moveIndex != index){
collItemSize.selectIndex = moveIndex;
let currentSort = item.sort;
for(let i = 0;i < elList.length;i++){
if(currentSort < moveIndex){
if(elList[i].sort > currentSort && elList[i].sort <= moveIndex){
elList[i].sort -= 1;
};
}else if(currentSort > moveIndex){
if(elList[i].sort < currentSort && elList[i].sort >= moveIndex){
elList[i].sort += 1;
};
}
};
elList[item.index].sort = moveIndex;
moveItem();
}
}
const moveItem = ()=>{
let value = collItemSize.num
for(let i = 0;i < collItemSize.elList.length;i++){
let height = parseInt(String((collItemSize.elList.length - 1 - collItemSize.elList[i].sort) / value)) * (collItemSize.itemStyle.height +collItemSize.padding) + 'px';
collItemSize.elList[i].el.style.top = height
}
setZIndex()
}
const setZIndex = ()=>{
collItemSize.elList.forEach((elItem:any)=>{
let clothesIndex = detailData.designDetail.clothes.findIndex((item:any)=>item.uniqueId == elItem.uniqueId)
let clothesId = detailData.designDetail.clothes[clothesIndex].id
detailData.designDetail.clothes[clothesIndex].priority = elItem.sort
let frontIndex = detailData.frontBack_.front.findIndex((item:any)=>item.id == clothesId)
detailData.frontBack_.front[frontIndex].style.zIndex = elItem.sort + 10
// detailData.frontBack_.back[frontIndex].style.zIndex = elItem.sort + 1
})
}
const setItemPosition = ()=>{
let parent = detailData.modelNav.offsetWidth
let elArr = detailData.modelNav.querySelectorAll('.item')
let value = collItemSize.num
const htmlFontSize = parseFloat(getComputedStyle(document.documentElement).fontSize);
const remValue = 12 * htmlFontSize;
//子元素宽度 = (父容器总宽度 - (列数-1)*间隙) / 列数
collItemSize.itemStyle.height = remValue
collItemSize.elList = []
let arr:any = detailData.designDetail.clothes
arr.forEach((item,index) => {item.uniqueId = `${Date.now()}_${index}`});
const sortedArray = [...arr].sort((a, b) => a.priority - b.priority);
const sortMap = {} as any;
sortedArray.forEach((item, index) => {
sortMap[item.priority] = index ; // 1, 2, 3, 4...
});
for(let i = 0;i < elArr.length;i++){
collItemSize.elList.push({
el: elArr[i],
// sort: elArr.length - i -1,
sort: sortMap[arr[i].priority],
index: i,
uniqueId:arr[i]?.uniqueId || 99999,
});
}
collItemSize.prentHeight = (collItemSize.padding + remValue) * elArr.length + 'px'
moveItem()
}
onMounted(()=>{
})
// onBeforeUnmount(()=>{
// detailData.selectIndex = -1
// })
return{
...toRefs(detailData),
...toRefs(collItemSize),
selectDetailItem,
deleteDetailItem,
designMousedown,
addSketch,
getMousePosition,
}
},
provide() {
return {
}
},
})
</script>
<style lang="less" scoped>
.modelNavBox{
.modelNav_item{
width: 12rem;
height: 12rem;
padding: 1rem;
border-radius: 2rem;
border: 2px solid #B4B4B4;
margin-bottom: 1.5rem;
cursor: pointer;
position: absolute;
background: #fff;
transition: top .3s;
&:hover{
> i{
display: block;
}
}
> i{
display: none;
position: absolute;
right: 1rem;
top: 1rem;
cursor: pointer;
font-size: 2rem;
}
&:last-child{
margin-bottom: 0;
}
&.active{
border: 3px solid #000;
}
> img{
width: 100%;
height: 100%;
object-fit: contain;
}
&.add{
font-size: 8rem;
display: flex;
align-items: center;
position: absolute;
justify-content: center;
}
}
}
.modelNav{
position: relative;
width: 12rem;
}
</style>

View File

@@ -0,0 +1,595 @@
<template>
<div class="molepositon" :class="{active:!imgDesignImg}">
<div class="designOpenrtion_imgMask" v-if="frontBack?.body?.path" :style="frontBack?.body?.style">
<div class="designOpenrtion_print" v-for="item,index in frontBack.back" @mousedown.stop="itemMoveMousedown(index,getMousePosition($event,false))" @touchstart.passive="itemMoveMousedown(index,getMousePosition($event,true))" @click="setpitch(item,index)" :style="frontBack.front[index].style">
<img :style="item.imageUrl?'':'display:none;'" :src="item.imageUrl" alt="">
</div>
<img class="perview_img" ref="detailBody" :src="frontBack?.body?.path" :style="'width:'+ frontBack?.body?.layersObject?.[0].imageSize?.[0] +';height:' + frontBack?.body?.layersObject?.[0].imageSize?.[0] +';'" v-lazy="frontBack?.body?.layersObject?.[0].imageUrl || ''">
<div class="detail_modal_item_front" v-for="item,index in frontBack.front" @mousedown.stop="itemMoveMousedown(index,getMousePosition($event,false))" @touchstart.passive="itemMoveMousedown(index,getMousePosition($event,true))" @click="setpitch(item,index)" :style="item.style">
<img :src="item.imageUrl" alt="">
</div>
<div class="designOpenrtion_btnBox">
<ul v-for="item,index in frontBack.front" :key="item" :class="{active:item.designOpenrtionBtn}" class="designOpenrtion_btn" :style="item.style" @mousedown.stop="itemMoveMousedown(index,getMousePosition($event,false))" @touchstart.passive="itemMoveMousedown(index,getMousePosition($event,true))">
<li class="designOpenrtion_btn_top" @mousedown.stop="itemSizeMousedown('top',getMousePosition($event,false))" @touchstart.passive="itemSizeMousedown('top',getMousePosition($event,true))"></li>
<li class="designOpenrtion_btn_bottom" @mousedown.stop="itemSizeMousedown('bottom',getMousePosition($event,false))" @touchstart.passive="itemSizeMousedown('bottom',getMousePosition($event,true))"></li>
<li class="designOpenrtion_btn_left" @mousedown.stop="itemSizeMousedown('left',getMousePosition($event,false))" @touchstart.passive="itemSizeMousedown('left',getMousePosition($event,true))"></li>
<li class="designOpenrtion_btn_right" @mousedown.stop="itemSizeMousedown('right',getMousePosition($event,false))" @touchstart.passive="itemSizeMousedown('right',getMousePosition($event,true))"></li>
</ul>
</div>
</div>
<div class="designOpenrtion_imgMask" v-else>
<img :src="designDetail.currentFullBodyView || selectDetail.undividedLayer" style="object-fit: cover;" alt="">
</div>
</div>
<div class="molepositon" :class="{active:imgDesignImg}">
<div class="designOpenrtion_imgMask">
<div class="detail_modal_item_front">
<img :src="designDetail.designItemUrl" alt="" style="object-fit: cover;">
</div>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent,computed,inject,watch,nextTick,createVNode,toRefs, reactive} from 'vue'
// import setDesignItem from '@/component/Detail/setDesignItem2.vue'
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { Https } from "@/tool/https";
import { useStore } from "vuex";
import { useI18n } from 'vue-i18n'
import { getMousePosition } from "@/tool/mdEvent";
import { Modal,message } from 'ant-design-vue';
import newFollowVue from '@/component/Account/message/newFollow.vue';
export default defineComponent({
components:{
},
props:{
imgDesignImg:{
default:false,
type:Boolean,
}
},
emits:['canvasReload'],
setup(props,{emit}) {
const {t} = useI18n()
const store = useStore();
const detailData = reactive({
frontBack:computed(()=>store.state.DesignDetail.frontBack),
designDetail:computed(()=>store.state.DesignDetail.designDetail),
isEditPattern:inject('isEditPattern') as any,
singleOveral:inject('singleOveral') as any,
detailBody:null as any,
})
const selectItem = reactive({
selectDetail:computed(()=>store.state.DesignDetail.selectDetail),
imgDomIndex:-1,
printZIndex:store.state.DesignDetail.printZIndex,
imgDom:null as any,
direction:'',
})
watch(()=>selectItem.selectDetail,(newValue,oldValue)=>{
if(newValue.id == oldValue?.id)return
selectItem.imgDomIndex = detailData.frontBack.front.findIndex((item:any)=>item.id == newValue.id)
},{immediate: true,})
watch(()=>detailData.frontBack?.body?.path,(newVal)=>{
let sacle = 0
const img = new Image();
img.onload = () => {
// resolve(img)
sacle = detailData.detailBody.parentNode.offsetWidth / img.width
detailData.frontBack.front.forEach((item:any,index:number) => {
for (const key in item.style) {
if(key == 'zIndex')return
let value = item.style[key]
if(typeof value !== 'number'){
value = value.replace('px','')
item.style[key] = value
}else{
item.style[key] = value*sacle+'px'
}
// item.style[key] = value*sacle+'px'
}
for (const key in detailData.frontBack.back[index].style) {
if(key == 'zIndex')return
let value = detailData.frontBack.back[index].style[key]
if(typeof value !== 'number'){
value = value.replace('px','')
detailData.frontBack.back[index].style[key] = value
}else{
detailData.frontBack.back[index].style[key] = value*sacle+'px'
}
// detailData.frontBack.back[index].style[key] = value*sacle+'px'
}
});
};
img.src = newVal;
},{immediate: true,})
const getDetailListDom = reactive({
libraryList:null as any,
})
//设置尺寸
const itemSizeMousedown = (direction:any,event:any)=>{
selectItem.direction = direction
selectItem.imgDom = document.getElementsByClassName('molepositon')[0].getElementsByClassName("detail_modal_item_front")[selectItem.imgDomIndex]
detailData.frontBack.front[selectItem.imgDomIndex].designOpenrtionBtn = true
let imgDomWH = selectItem.imgDom.getBoundingClientRect()
let li = (document.getElementsByClassName('molepositon')[0].getElementsByClassName("designOpenrtion_btn_top")[0] as any).offsetWidth/2
if(selectItem.direction == 'right' || selectItem.direction == 'bottom'){
detailData.frontBack.front[selectItem.imgDomIndex].centers.left = imgDomWH.x+event.offsetX-li
detailData.frontBack.front[selectItem.imgDomIndex].centers.top = imgDomWH.y+event.offsetY-li
}else{
detailData.frontBack.front[selectItem.imgDomIndex].centers.left = imgDomWH.x+event.offsetX+imgDomWH.width-li
detailData.frontBack.front[selectItem.imgDomIndex].centers.top = imgDomWH.y+event.offsetY+imgDomWH.height-li
}
document.addEventListener('mousemove', sizeMouseMove);
document.addEventListener('touchmove', sizeTouchmove);
document.addEventListener('mouseup', sizeMouseup);
document.addEventListener('touchend', sizeMouseup);
}
const sizeMouseMove = (event:any)=>{
let e = getMousePosition(event,false)
sizeMouseMoveOperation(e)
}
const sizeTouchmove = (event:any)=>{
let e = getMousePosition(event,true)
sizeMouseMoveOperation(e)
}
const sizeMouseup = (e:any)=>{
detailData.frontBack.front[selectItem.imgDomIndex].style={
right:'auto',
left:selectItem.imgDom.offsetLeft+'px',
bottom:'auto',
top:selectItem.imgDom.offsetTop+'px',
height:selectItem.imgDom.offsetHeight+'px',
width:selectItem.imgDom.offsetWidth+'px',
zIndex:selectItem.imgDom.style.zIndex,
// zIndex:selectItem.printZIndex
}
// detailData.frontBack.back[selectItem.imgDomIndex].style.zIndex = selectItem.printZIndex
document.removeEventListener('mousemove',sizeMouseMove)
document.removeEventListener('touchmove',sizeTouchmove)
document.removeEventListener('mouseup',sizeMouseup)
document.removeEventListener('touchend',sizeMouseup)
}
const sizeMouseMoveOperation = (e:any)=> {
let imgDomWH = selectItem.imgDom.getBoundingClientRect()
let parentNode =selectItem.imgDom.parentNode
let width = imgDomWH.width
let height = imgDomWH.height
let w,h
let num = height/width
//判断移动四个边
if(selectItem.direction == 'right'){
w = (e.clientX - detailData.frontBack.front[selectItem.imgDomIndex].centers.left)
h = (e.clientX - detailData.frontBack.front[selectItem.imgDomIndex].centers.left)*num
width = w+'px'
// height = w*num+'px'
}else if(selectItem.direction == 'top'){
num = width/height
detailData.frontBack.front[selectItem.imgDomIndex].style.top = 'auto'
// this.printStyleList[selectItem.imgDomIndex].style.left = 'auto'
detailData.frontBack.front[selectItem.imgDomIndex].style.bottom = parentNode.offsetHeight -imgDomWH.height - selectItem.imgDom.offsetTop+'px'
w = (e.clientX - detailData.frontBack.front[selectItem.imgDomIndex].centers.left)*num
h = (detailData.frontBack.front[selectItem.imgDomIndex].centers.top - e.clientY)
height = h+'px'
// width = h*num+'px'
}else if(selectItem.direction == 'bottom'){
num = width/height
h = (e.clientY - detailData.frontBack.front[selectItem.imgDomIndex].centers.top)
height = h+'px'
// width = h*num+'px'
}else if(selectItem.direction == 'left'){
detailData.frontBack.front[selectItem.imgDomIndex].style.left = 'auto'
detailData.frontBack.front[selectItem.imgDomIndex].style.right = parentNode.offsetWidth -imgDomWH.width - selectItem.imgDom.offsetLeft+'px'
w = (detailData.frontBack.front[selectItem.imgDomIndex].centers.left - e.clientX)
width = w+'px'
// height = w*num+'px'
}
//判断尺寸是否到边
detailData.frontBack.front[selectItem.imgDomIndex].style.width = width
detailData.frontBack.front[selectItem.imgDomIndex].style.height = height
}
// 设置移动
const mouseMove = (event:any)=>{
let e = getMousePosition(event,false)
mouseMoveOperation(e)
}
const touchmove=(event:any)=>{
let e = getMousePosition(event,true)
mouseMoveOperation(e)
}
const mouseup = (e:any)=> {
document.removeEventListener('mousemove',mouseMove)
document.removeEventListener('touchmove',touchmove)
document.removeEventListener('mouseup',mouseup)
document.removeEventListener('touchend',mouseup)
}
const mouseMoveOperation = (e:any)=>{
let imgDomWH = selectItem.imgDom.getBoundingClientRect()
let parentNode = document.getElementsByClassName('molepositon')[0].getElementsByClassName("designOpenrtion_imgMask")[0].getBoundingClientRect()
let x = (e.clientX - detailData.frontBack.front[selectItem.imgDomIndex].centers.left)+'px'
let y = ( e.clientY - detailData.frontBack.front[selectItem.imgDomIndex].centers.top)+'px'
detailData.frontBack.front[selectItem.imgDomIndex].style.left = x
detailData.frontBack.front[selectItem.imgDomIndex].style.top = y
}
const clothesOpenActive = (index:number)=>{
// this.designItemDetail.clothes.forEach((item)=>{
// item.clothesOpenItem = false
// })
// if(index != -1){
// this.designItemDetail.clothes[index].clothesOpenItem = true
// }
}
const itemMoveMousedown = async (index:any,e:any)=>{
let isOpen = false
let isModal = false
await new Promise((resolve, reject) => {
if(
detailData.isEditPattern.value &&
selectItem.selectDetail?.id &&
(detailData.frontBack.front[index].id != selectItem.selectDetail.id)
){
isModal = true
Modal.confirm({
title: t('collectionModal.jsContent2'),
icon: createVNode(ExclamationCircleOutlined),
okText: 'Yes',
cancelText: 'No',
mask:false,
centered:true,
onOk() {
resolve(true)
isOpen = true
},
onCancel(){
resolve(false)
isOpen = false
}
});
}else{
resolve(true)
isModal = false
}
}).then((rv)=>{
})
if(isOpen){
store.commit('DesignDetail/setDesignColthes',detailData.frontBack.front[index].id)
emit('canvasReload')
return
}
if(isModal)return
store.commit('DesignDetail/setDesignColthes',detailData.frontBack.front[index].id)
selectItem.imgDomIndex = index
detailData.frontBack.front.forEach((v:any)=>{
v.designOpenrtionBtn = false
})
clothesOpenActive(index)
let event = e||window.event
selectItem.imgDom = document.getElementsByClassName('molepositon')[0].getElementsByClassName("detail_modal_item_front")[selectItem.imgDomIndex]
detailData.frontBack.front[index].designOpenrtionBtn = true
// detailData.frontBack.front[index].style.zIndex = selectItem.printZIndex++
// detailData.frontBack.back[index].style.zIndex = selectItem.printZIndex
let imgDomWH = selectItem.imgDom.getBoundingClientRect()
let left = Number(detailData.frontBack.front[index].style.left.replace(/px/g,''))
let top = Number(detailData.frontBack.front[index].style.top.replace(/px/g,''))
detailData.frontBack.front[index].centers.left = imgDomWH.x+event.offsetX-left
detailData.frontBack.front[index].centers.top = imgDomWH.y+event.offsetY-top
document.addEventListener('mousemove', mouseMove);
document.addEventListener('touchmove', touchmove);
document.addEventListener('mouseup', mouseup);
document.addEventListener('touchend', mouseup);
}
const sort = (arr:any)=>{
arr.sort((a:any, b:any) => {
var a_num = a.style.zIndex;
var b_num = b.style.zIndex;
return a_num - b_num;
});
return arr
}
const getSubmitData = (value:any)=>{
let parentNode = document.getElementsByClassName('molepositon')[0].getElementsByClassName("designOpenrtion_imgMask")[0].getBoundingClientRect()
if(!detailData.frontBack?.body?.layersObject?.[0]?.imageSize){
return{
scale:value.layersObject[0].scale,
offset:value.layersObject[0].offset,
priority:value.layersObject[0].priority,
}
}
let ratio = detailData.frontBack.body.layersObject[0].imageSize[0]/parentNode.width
// let arr:any = sort(detailData.frontBack.front)
let arr:any = sort(JSON.parse(JSON.stringify(detailData.frontBack.front)))
let num = 10
arr.forEach((item:any)=>{
item.priority = num++
})
let data:any = {
scale:null,
offset:null,
priority:'',
maskUrl:'',
maskMinioUrl:'',
}
let state = false
for (let index = 0; index < arr.length; index++) {
if(value.id == arr[index].id){
state = true
let y = ((arr[index]?.style?.top.replace(/px/g,'')*ratio).toFixed(0) as any - arr[index]?.position[0])
let x = ((arr[index]?.style?.left.replace(/px/g,'')*ratio).toFixed(0) as any - arr[index]?.position[1])
let scaleWidth = arr[index]?.imageSize?Number(((arr[index]?.style?.width.replace(/px/g,'')*ratio)/(arr[index]?.imageSize[0]/arr[index].scale[0])).toFixed(2)):1
let scaleHeight = arr[index]?.imageSize?Number(((arr[index]?.style?.height.replace(/px/g,'')*ratio)/(arr[index]?.imageSize[1]/arr[index].scale[1])).toFixed(2)):1
// let widthScale = (arr[index].style.width.replace(/px/g,'')/arr[index].style.height.replace(/px/g,'')).toFixed(2)
data.scale = [scaleWidth,scaleHeight]
let top = y == 0 ? value.layersObject[0].offset[1]:y+value.layersObject[0].offset[1]
let left = x == 0 ? value.layersObject[0].offset[0]:x+value.layersObject[0].offset[0]
data.offset = [left?left:0,top?top:0]
// data.offset = [left?left:0,top?top:0]
data.maskUrl = arr[index].maskUrl
data.maskMinioUrl = arr[index].maskMinioUrl
// data.priority = arr[index].style.zIndex
data.priority = arr[index].priority
arr[index].similarity = true
// item.offset = [(arr[index]?.style?.left.replace(/px/g,'')*ratio).toFixed(0),(i?.style?.top.replace(/px/g,'')*ratio).toFixed(0)]
break
}
}
if(!state){
data.scale = [1,1]
data.offset = [0,0]
data.priority = 10+arr.length
}
return data
}
const deleteNav = ()=>{
}
const setpitch = (item:any,index:any)=>{
detailData.frontBack.front.forEach((v:any)=>{
v.designOpenrtionBtn = false
})
detailData.frontBack.front[index].designOpenrtionBtn = true
// detailData.frontBack.front[index].style.zIndex = selectItem.printZIndex++
// detailData.frontBack.back[index].style.zIndex = selectItem.printZIndex
clothesOpenActive(index)
}
const updataPosition = ()=>{
let url = detailData.frontBack?.body?.path
let sacle = 0
const img = new Image();
img.onload = () => {
let dom:any = document.querySelector('.molepositon .perview_img')
// resolve(img)
sacle = dom.parentNode.offsetWidth / img.width
detailData.frontBack.front.forEach((item:any,index:number) => {
for (const key in item.style) {
if(key == 'zIndex')return
item.style[key] = item.style[key]*sacle+'px'
}
for (const key in detailData.frontBack.back[index].style) {
if(key == 'zIndex')return
detailData.frontBack.back[index].style[key] = detailData.frontBack.back[index].style[key]*sacle+'px'
}
});
};
img.src = url;
}
return{
...toRefs(detailData),
...toRefs(selectItem),
...toRefs(getDetailListDom),
itemSizeMousedown,
itemMoveMousedown,
deleteNav,
setpitch,
getSubmitData,
getMousePosition,
updataPosition,
}
},
directives:{
detailBody:{
mounted (el,data:any) {
let sacle = 0
const img = new Image();
img.onload = () => {
// resolve(img)
sacle = el.parentNode.offsetWidth / img.width
data.instance.frontBack.front.forEach((item:any,index:number) => {
for (const key in item.style) {
if(key == 'zIndex')return
item.style[key] = item.style[key]*sacle+'px'
}
for (const key in data.instance.frontBack.back[index].style) {
if(key == 'zIndex')return
data.instance.frontBack.back[index].style[key] = data.instance.frontBack.back[index].style[key]*sacle+'px'
}
});
};
img.src = data.value;
},
updated (el,data:any) {
let sacle = 0
const img = new Image();
img.onload = () => {
// resolve(img)
sacle = el.parentNode.offsetWidth / img.width
data.instance.frontBack.front.forEach((item:any,index:number) => {
for (const key in item.style) {
if(key == 'zIndex')return
item.style[key] = item.style[key].replace(/px/g,'')*sacle+'px'
}
for (const key in data.instance.frontBack.back[index].style) {
if(key == 'zIndex')return
data.instance.frontBack.back[index].style[key] = data.instance.frontBack.back[index].style[key].replace(/px/g,'')*sacle+'px'
}
});
};
img.src = data.value;
}
}
},
provide() {
return {
}
},
})
</script>
<style lang="less" scoped>
.molepositon{
// width: 30rem;
// width: calc(66 * .470rem);
width: calc(66 * .457rem);
height: 66rem;
display: flex;
flex-direction: column;
// margin: auto 0;
// padding-top: 3rem;
position: relative;
display: none;
&.active{
display: block;
z-index: 2;
}
> .designOpenrtion_imgMask{
width: auto;
height: auto;
position: relative;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
>img{
z-index: 2;
position: relative;
width: 100%;
height: auto;
// height: 100%;
// object-fit: contain;
}
>div{
position: absolute;
top: 0;
}
.detail_modal_item_front,.designOpenrtion_print{
z-index: 2;
height: 100%;
width: 100%;
img{
width: 100%;
height: 100%;
// width: 100%;
// height: auto;
float: left;
user-select:none;
-webkit-user-drag: none;
}
.modal_imgItem{
position: absolute;
overflow: hidden;
top: 0;
}
}
.designOpenrtion_print{
z-index: 1 !important;
}
> .designOpenrtion_btnBox{
z-index: 99;
width: 100%;
height: 100%;
left: 0;
ul{
list-style: none;
// width: 100%;
// height: 100%;
position: absolute;
top: 0;
left: 0;
box-sizing: border-box;
border: 2px solid rgb(20, 188, 255);
padding: 0;
-webkit-user-drag: none;
user-select:none;
opacity: 0;
margin: 0;
li{
cursor: pointer;
// border-radius: 50%;
width: calc(2rem*1.2);
height: calc(2rem*1.2);
background-color: rgb(20, 188, 255);
position: absolute;
pointer-events: none;
}
&.active{
opacity: 1;
z-index: 999 !important;
li{
pointer-events: auto;
}
}
.designOpenrtion_btn_top,.designOpenrtion_btn_bottom{
left: 50%;
transform: translate(-50%,-50%) ;
cursor: n-resize;
}
.designOpenrtion_btn_top{
top: 0;
}
.designOpenrtion_btn_bottom{
top: 100%;
}
.designOpenrtion_btn_left,.designOpenrtion_btn_right{
top: 50%;
transform: translate(-50%,-50%) ;
cursor: e-resize;
}
.designOpenrtion_btn_left{
left: 0;
}
.designOpenrtion_btn_right{
left: 100%;
}
.designOpenrtion_rotote{
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
width: 0;
height: 0;
}
.designOpenrtion_rotote::after{
position: absolute;
content: "";
background-color: #14bcff;
width: 2px;
height: 30px;
left: 50%;
bottom: 0;
transform: translateX(-50%);
}
.designOpenrtion_rotote::before{
position: absolute;
content: "";
background-color: #14bcff;
top: calc(50% - 30px);
left: 50%;
transform: translate(-50%,-50%) ;
width: calc(1.5rem*1.2);
height: calc(1.5rem*1.2);
border-radius: 50%;
}
}
}
}
}
</style>

View File

@@ -1,763 +0,0 @@
<template>
<div class="design_compile_content" id="design_compile_content">
<div class="designOpenrtion_centent" id="designOpenrtionCentent">
<div class="detail_modal_body_title">
<div class="detail_modal_body_nav">
<div v-for="item,index in designItemDetail?.clothes" v-show="item.id" :class="{active:item.clothesOpenItem}" @click="clothesOpen(index)">
<img :src="item?.path" alt="">
</div>
</div>
</div>
<div class="designOpenrtion_imgMask" :style="frontBack?.body?.style">
<!-- <div
v-for="item,index in frontBack.back"
:key="item"
:style="item.style"
@mousedown.stop="itemMoveMousedown(index,$event)"
class="modal_imgItem"
@click="setpitch(item,index)" ref="content" >
<img crossOrigin="anonymous" :src="item.path" class="designOpenrtion_imgItme" draggable="false">
</div> -->
<div class="designOpenrtion_print" v-for="item,index in frontBack.back" @mousedown.stop="itemMoveMousedown(index,getMousePosition($event,false))" @touchstart.passive="itemMoveMousedown(index,getMousePosition($event,true))" @click="setpitch(item,index)" :style="frontBack.front[index].style">
<img :style="item.imageUrl?'':'display:none;'" :src="item.imageUrl" alt="">
</div>
<img class="perview_img" :style="'width:'+ frontBack?.body?.layersObject?.[0].imageSize?.[0] +';height:' + frontBack?.body?.layersObject?.[0].imageSize?.[0] +';'" v-lazy="frontBack?.body?.layersObject?.[0].imageUrl || ''" :key="designItemDetail.designItemUrl">
<div class="detail_modal_item_front" v-for="item,index in frontBack.front" @mousedown.stop="itemMoveMousedown(index,getMousePosition($event,false))" @touchstart.passive="itemMoveMousedown(index,getMousePosition($event,true))" @click="setpitch(item,index)" :style="item.style">
<img :src="item.imageUrl" alt="">
</div>
<div class="designOpenrtion_btn" v-if="!isBody">
<ul v-for="item,index in frontBack.front" :key="item" :class="{active:item.designOpenrtionBtn}" class="designOpenrtion_btn" :style="item.style" @mousedown.stop="itemMoveMousedown(index,getMousePosition($event,false))" @touchstart.passive="itemMoveMousedown(index,getMousePosition($event,true))">
<li class="designOpenrtion_btn_top" @mousedown.stop="itemSizeMousedown('top',getMousePosition($event,false))" @touchstart.passive="itemSizeMousedown('top',getMousePosition($event,true))"></li>
<li class="designOpenrtion_btn_bottom" @mousedown.stop="itemSizeMousedown('bottom',getMousePosition($event,false))" @touchstart.passive="itemSizeMousedown('bottom',getMousePosition($event,true))"></li>
<li class="designOpenrtion_btn_left" @mousedown.stop="itemSizeMousedown('left',getMousePosition($event,false))" @touchstart.passive="itemSizeMousedown('left',getMousePosition($event,true))"></li>
<li class="designOpenrtion_btn_right" @mousedown.stop="itemSizeMousedown('right',getMousePosition($event,false))" @touchstart.passive="itemSizeMousedown('right',getMousePosition($event,true))"></li>
<!-- <li class="designOpenrtion_rotote" v-rotote.stop="[index,item.transform]"></li> -->
</ul>
</div>
</div>
<div class="subitOkPreviewBtn" @click="imgClear" style="margin-bottom: 0rem;">{{ $t('LibraryPage.Reset') }}</div>
<div @click="setPreviewData" class="subitOkPreviewBtn">OK</div>
</div>
<div class="designOpenrtion_imgMask_open" @click.stop="deleteBorder"></div>
</div>
<!-- <div class="design_compile_content">
<editFrontBack :patchData="frontBack" :imgDomIndex="imgDomIndex" ref="editFrontBack"></editFrontBack>
</div> -->
</template>
<script >
import { defineComponent, h,createVNode, ref ,computed, inject,nextTick} from "vue";
// import { LoadingOutlined } from "@ant-design/icons-vue";
import { useStore } from "vuex";
// import { Modal,message } from 'ant-design-vue';
import { Https } from "@/tool/https";
import editFrontBack from '@/component/Detail/editFrontBack.vue'
import { getMousePosition } from "@/tool/mdEvent";
export default defineComponent({
props: ["isBody"],
emits:['setParentLoadingShow','setDesignCoverage','setSubmit'],
components:{editFrontBack},
setup(prop) {
const store = useStore();
let designItemDetail = computed(()=>{
return store.state.DesignDetailModule.designItemDetail
})
let current = inject('current')//父组件传过来的数据
let setRevocation = inject('setRevocation')//父组件传过来的数据
let printZIndex = ref(4)//印花优先级
let printStyleList = ref([
{
centers:{
left:0,
top:0,
},
style:{
left:0+"px",
top:0+"px",
right:"auto",
bottom:"auto",
width:100+'px',
height:100+'px',
// zIndex:1,
},
transform:{
scale:1,
rotateZ:0,
},
designOpenrtionBtn:false
}
]);
let direction = ref('')
let imgDom = ref()
let imgDomIndex = ref(-1)
let frontBack = ref({})
let frontBackOld = ref({})
let editFrontBack = ref(null)
return {
designItemDetail,
current,
printZIndex,
printStyleList,
direction,//判断点击的是li那个边
imgDom,
imgDomIndex,
frontBack,
setRevocation,
frontBackOld,
editFrontBack,
getMousePosition,
};
},
data() {
return {
loadingShow:false,//加载中
store: useStore(),
setImgSizeTimeout:null
};
},
mounted () {
window.addEventListener('resize', this.setImgSizeTime);
},
methods: {
init(){
let DesignParent = this.$parent
// this.clearModal()
// console.log(this.current,DesignParent.frontBack);
this.printStyleList.push({
centers:{
left:0,
top:0,
},
style:{
left:0+"px",
top:0+"px",
right:"auto",
bottom:"auto",
width:100+'px',
height:100+'px',
// zIndex:1,
},
transform:{
scale:1,
rotateZ:0,
},
designOpenrtionBtn:false
})
this.setImgSize()
},
setImgSizeTime(){
clearTimeout(this.setImgSizeTimeout)
this.setImgSizeTimeout = setTimeout(()=>{
this.setImgSize()
},300)
},
async setImgSize(){
this.frontBack.body = null
let designItemDetail = JSON.parse(JSON.stringify(this.store.state.DesignDetailModule.designItemDetail))
let front = []
let back = []
let body = {}
if(designItemDetail.others.length > 0){
designItemDetail.others.forEach((item) => {
if(item.type == 'Body'){
body = item
}
});
}else{
designItemDetail.clothes.forEach((item) => {
body = item
});
}
let ratio = await this.setPostition(body.layersObject[0]?.imageUrl)
let frontIndex = 6
let backIndex = 3
// let front = 3
// let back = 3
designItemDetail.clothes.forEach((v,index)=>{
for (let i = v.layersObject.length-1; i >= 0; i--) {
v.layersObject[i].style = {
top:v.layersObject[i].position?.[0]*ratio+'px',
left:v.layersObject[i].position?.[1]*ratio+'px',
width:v.layersObject[i].imageSize?.[0]*ratio+'px',
height:v.layersObject[i].imageSize?.[1]*ratio+'px',
// zIndex:zIndex-=1
}
v.layersObject[i].centers={
left:0,
top:0,
}
v.layersObject[i].designOpenrtionBtn = false
if(v.layersObject[i].imageCategory.indexOf("back") == -1){
front[index] = v.layersObject[i]
front[index].style.zIndex = v.priority
front[index].id = v.id
front[index].undividedLayer = v.undividedLayer
}else{
back[index] = v.layersObject[i]
back[index].style.zIndex = v.priority
back[index].id = v.id
back[index].undividedLayer = v.undividedLayer
// back[index].style.zIndex = backIndex==0?v.layersObject[i]:backIndex++
}
if(this.printZIndex < v.priority){
this.printZIndex = v.priority
}
}
this.printZIndex++
})
if(body){
body.style = {
width:body.layersObject[0].imageSize?.[0]*ratio+'px',
height:body.layersObject[0].imageSize?.[1]*ratio+'px',
}
}
this.frontBack = {
front:front,
back:back,
body:body,
}
this.frontBackOld = JSON.parse(JSON.stringify({
front:front,
back:back,
body:body,
}))
},
imgClear(){
this.frontBack = JSON.parse(JSON.stringify(this.frontBackOld))
},
//按比设置单件衣服宽高位置
async setPostition(url){
let img = await loadImage(url)
let modal_body = document.getElementsByClassName('designOpenrtion_imgMask')[0]
const num = modal_body?.offsetHeight / img.height;
function loadImage(url) {
return new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => {
resolve(img)
img.remove()
};
img.onerror = reject;
img.src = url;
});
}
return num
},
clear(){
this.imgDomIndex = -1
this.clothesOpenActive(-1)
if(this.editFrontBack)this.editFrontBack.setClone()
window.removeEventListener('resize', this.setImgSizeTime);
},
setpitch(item,index){
this.frontBack.front.forEach((v)=>{
v.designOpenrtionBtn = false
})
this.frontBack.front[index].designOpenrtionBtn = true
this.frontBack.front[index].style.zIndex = this.printZIndex++
this.frontBack.back[index].style.zIndex = this.printZIndex
this.clothesOpenActive(index)
},
// 设置移动
itemMoveMousedown(index,e){
this.imgDomIndex = index
this.frontBack.front.forEach((v)=>{
v.designOpenrtionBtn = false
})
this.clothesOpenActive(index)
let event = e||window.event
this.imgDom = document.getElementsByClassName('design_compile_content')[0].getElementsByClassName("detail_modal_item_front")[this.imgDomIndex]
this.frontBack.front[index].designOpenrtionBtn = true
this.frontBack.front[index].style.zIndex = this.printZIndex++
this.frontBack.back[index].style.zIndex = this.printZIndex
let imgDomWH = this.imgDom.getBoundingClientRect()
let left = Number(this.frontBack.front[index].style.left.replace(/px/g,''))
let top = Number(this.frontBack.front[index].style.top.replace(/px/g,''))
this.frontBack.front[index].centers.left = imgDomWH.x+event.offsetX-left
this.frontBack.front[index].centers.top = imgDomWH.y+event.offsetY-top
// document.addEventListener("mouseup", this.mouseup);
// document.addEventListener("mousemove", this.moveMousemove);
document.addEventListener('mousemove', this.mouseMove);
document.addEventListener('touchmove', this.touchmove);
document.addEventListener('mouseup', this.mouseup);
document.addEventListener('touchend', this.mouseup);
},
//设置尺寸
itemSizeMousedown(direction,event){
this.direction = direction
this.imgDom = document.getElementsByClassName('design_compile_content')[0].getElementsByClassName("detail_modal_item_front")[this.imgDomIndex]
this.frontBack.front[this.imgDomIndex].designOpenrtionBtn = true
let imgDomWH = this.imgDom.getBoundingClientRect()
let li = document.getElementsByClassName('design_compile_content')[0].getElementsByClassName("designOpenrtion_btn_top")[0].offsetWidth/2
if(this.direction == 'right' || this.direction == 'bottom'){
this.frontBack.front[this.imgDomIndex].centers.left = imgDomWH.x+event.offsetX-li
this.frontBack.front[this.imgDomIndex].centers.top = imgDomWH.y+event.offsetY-li
}else{
this.frontBack.front[this.imgDomIndex].centers.left = imgDomWH.x+event.offsetX+imgDomWH.width-li
this.frontBack.front[this.imgDomIndex].centers.top = imgDomWH.y+event.offsetY+imgDomWH.height-li
}
document.addEventListener('mousemove', this.sizeMouseMove);
document.addEventListener('touchmove', this.sizeTouchmove);
document.addEventListener('mouseup', this.sizeMouseup);
document.addEventListener('touchend', this.sizeMouseup);
},
mouseMove(event){
let e = getMousePosition(event,false)
this.mouseMoveOperation(e)
},
touchmove(event){
let e = getMousePosition(event,true)
this.mouseMoveOperation(e)
},
//鼠标移动
mouseMoveOperation(e) {
let imgDomWH = this.imgDom.getBoundingClientRect()
let parentNode = document.getElementsByClassName('design_compile_content')[0].getElementsByClassName("designOpenrtion_imgMask")[0].getBoundingClientRect()
let x = (e.clientX - this.frontBack.front[this.imgDomIndex].centers.left)+'px'
let y = ( e.clientY - this.frontBack.front[this.imgDomIndex].centers.top)+'px'
this.frontBack.front[this.imgDomIndex].style.left = x
this.frontBack.front[this.imgDomIndex].style.top = y
// if(x.replace(/px/g,'') >= parentNode.width - imgDomWH.width){
// this.frontBack.front[this.imgDomIndex].style.left = parentNode.width - imgDomWH.width+'px'
// }
// if(x.replace(/px/g,'') <= 0){
// this.frontBack.front[this.imgDomIndex].style.left = 0+'px'
// }
// if(y.replace(/px/g,'') >= parentNode.height - imgDomWH.height){
// this.frontBack.front[this.imgDomIndex].style.top = parentNode.height - imgDomWH.height+'px'
// }
// if(y.replace(/px/g,'') <= 0){
// this.frontBack.front[this.imgDomIndex].style.top = 0+'px'
// }
},
sizeMouseMove(event){
let e = getMousePosition(event,false)
this.sizeMouseMoveOperation(e)
},
sizeTouchmove(event){
let e = getMousePosition(event,true)
this.sizeMouseMoveOperation(e)
},
sizeMouseMoveOperation(e) {
let imgDomWH = this.imgDom.getBoundingClientRect()
let parentNode =this.imgDom.parentNode
let width = imgDomWH.width
let height = imgDomWH.height
let w,h
let num = height/width
//判断移动四个边
if(this.direction == 'right'){
w = (e.clientX - this.frontBack.front[this.imgDomIndex].centers.left)
h = (e.clientX - this.frontBack.front[this.imgDomIndex].centers.left)*num
width = w+'px'
// height = w*num+'px'
}else if(this.direction == 'top'){
num = width/height
this.frontBack.front[this.imgDomIndex].style.top = 'auto'
// this.printStyleList[this.imgDomIndex].style.left = 'auto'
this.frontBack.front[this.imgDomIndex].style.bottom = parentNode.offsetHeight -imgDomWH.height - this.imgDom.offsetTop+'px'
w = (e.clientX - this.frontBack.front[this.imgDomIndex].centers.left)*num
h = (this.frontBack.front[this.imgDomIndex].centers.top - e.clientY)
height = h+'px'
// width = h*num+'px'
}else if(this.direction == 'bottom'){
num = width/height
h = (e.clientY - this.frontBack.front[this.imgDomIndex].centers.top)
height = h+'px'
// width = h*num+'px'
}else if(this.direction == 'left'){
this.frontBack.front[this.imgDomIndex].style.left = 'auto'
this.frontBack.front[this.imgDomIndex].style.right = parentNode.offsetWidth -imgDomWH.width - this.imgDom.offsetLeft+'px'
w = (this.frontBack.front[this.imgDomIndex].centers.left - e.clientX)
width = w+'px'
// height = w*num+'px'
}
//判断尺寸是否到边
this.frontBack.front[this.imgDomIndex].style.width = width
this.frontBack.front[this.imgDomIndex].style.height = height
},
//鼠标抬起
sizeMouseup(e){
this.frontBack.front[this.imgDomIndex].style={
right:'auto',
left:this.imgDom.offsetLeft+'px',
bottom:'auto',
top:this.imgDom.offsetTop+'px',
height:this.imgDom.offsetHeight+'px',
width:this.imgDom.offsetWidth+'px',
zIndex:this.printZIndex
}
this.frontBack.back[this.imgDomIndex].style.zIndex = this.printZIndex
document.removeEventListener('mousemove',this.sizeMouseMove)
document.removeEventListener('touchmove',this.sizeTouchmove)
document.removeEventListener('mouseup',this.sizeMouseup)
document.removeEventListener('touchend',this.sizeMouseup)
},
mouseup(e) {
// document.removeEventListener("mouseup", this.mouseup);
// document.removeEventListener("mousemove", this.moveMousemove);
document.removeEventListener('mousemove',this.mouseMove)
document.removeEventListener('touchmove',this.touchmove)
document.removeEventListener('mouseup',this.mouseup)
document.removeEventListener('touchend',this.mouseup)
},
clearModal(){
this.printZIndex = 2//点击图片z-index
this.imgDomIndex = 0//点击图片下标
this.clothes = []
this.printStyleList.splice(1,this.printStyleList.length-1)
},
capitalizeFirstLetter(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
},
setPreviewData(){
this.$emit('setSubmit','preview');
},
deleteBorder(){
this.frontBack?.front?.forEach((item)=>{
item.designOpenrtionBtn = false
})
},
clothesOpen(index){
this.imgDomIndex = index
this.clothesOpenActive(index)
this.setpitch('',index)
},
clothesOpenActive(index){
this.designItemDetail.clothes.forEach((item)=>{
item.clothesOpenItem = false
})
if(index != -1){
this.designItemDetail.clothes[index].clothesOpenItem = true
}
},
sort(arr){
arr.sort((a, b) => {
var a_num = a.style.zIndex;
var b_num = b.style.zIndex;
return a_num - b_num;
});
return arr
},
async setPreview(data){
let ratio = this.frontBack.body.layersObject[0].imageSize[0]/this.frontBack.body.style.width.replace(/px/g,'')
let designItemDetail = this.store.state.DesignDetailModule.designItemDetail
// this.frontBack.back.sort((a, b) => {
// var a_num = a.style.zIndex;
// var b_num = b.style.zIndex;
// return a_num - b_num;
// });
let arr = this.sort(JSON.parse(JSON.stringify(this.frontBack.front)))
let num = 10
arr.forEach((item)=>{
item.priority = num++
item.similarity = false//新增衣服传的是衣服id会存在两件衣服id相同所以设置为false让每次赋值都是不一样的
})
let front = arr
let imageCategory1
data.designSingleItemDTOList.forEach((item)=>{
if(arr.length > 1){
imageCategory1 = arr[1].imageCategory
}
for (let index = 0; index < arr.length; index++) {
if(item.id == arr[index].id && !arr[index].similarity){
let y = ((arr[index]?.style?.top.replace(/px/g,'')*ratio).toFixed(0) - arr[index]?.position[0])
let x = ((arr[index]?.style?.left.replace(/px/g,'')*ratio).toFixed(0) - arr[index]?.position[1])
let scaleWidth = arr[index]?.imageSize?Number(((arr[index]?.style?.width.replace(/px/g,'')*ratio)/(arr[index]?.imageSize[0]/arr[index].scale[0])).toFixed(2)):1
let scaleHeight = arr[index]?.imageSize?Number(((arr[index]?.style?.height.replace(/px/g,'')*ratio)/(arr[index]?.imageSize[1]/arr[index].scale[1])).toFixed(2)):1
// let widthScale = (arr[index].style.width.replace(/px/g,'')/arr[index].style.height.replace(/px/g,'')).toFixed(2)
item.scale = [scaleWidth,scaleHeight]
let top = y == 0 ? item.offset[1]:y+item.offset[1]
let left = x == 0 ? item.offset[0]:x+item.offset[0]
item.offset = [left,top]
item.maskUrl = arr[index].maskUrl
item.priority = arr[index].priority
arr[index].similarity = true
// item.offset = [(arr[index]?.style?.left.replace(/px/g,'')*ratio).toFixed(0),(i?.style?.top.replace(/px/g,'')*ratio).toFixed(0)]
break
}
}
if(arr.length > 1 && item.type == this.capitalizeFirstLetter(imageCategory1)){
item.scale = front?.imageSize?Number(((front?.style?.width.replace(/px/g,'')*ratio)/front?.imageSize[0]).toFixed(2)):1
}
})
Https.axiosPost(Https.httpUrls.designSingle, data).then(
(rv) => {
// this.$parent.loadingShow = false
// let designItemDetail = JSON.parse(JSON.stringify(this.store.state.DesignDetailModule.designItemDetail))
// designItemDetail.designItemUrl = rv.designItemUrl
// designItemDetail.ifSubmit = true
// designItemDetail.currentFullBodyView = rv.currentFullBodyView
// rv.clothes.forEach((item)=>{
// designItemDetail.clothes.forEach((i)=>{
// if(item.id === i.id){
// i.layersObject = item.layersObject
// i.priority = item.layersObject[0].priority
// }
// })
// })
let designItemDetail = JSON.parse(JSON.stringify(this.store.state.DesignDetailModule.designItemDetail))
rv.clothes.forEach((i)=>{
i.similarity = false//新增衣服传的是衣服id会存在两件衣服id相同所以设置为false让每次赋值都是不一样的
})
designItemDetail.designItemUrl = rv.designItemUrl
designItemDetail.ifSubmit = true
designItemDetail.currentFullBodyView = rv.currentFullBodyView
designItemDetail.clothes.forEach((item)=>{
for (let index = 0; index < rv.clothes.length; index++) {
if(rv.clothes[index].id === item.id && !rv.clothes[index].similarity){
item.layersObject = rv.clothes[index].layersObject
item.undividedLayer = rv.clothes[index].undividedLayer
item.priority = rv.clothes[index].layersObject[0].priority
rv.clothes[index].similarity = true
break
}
}
})
// rv.clothes.forEach((item)=>{
// for (let index = 0; index < designItemDetail.clothes.length; index++) {
// if(item.id === designItemDetail.clothes[index].id && !designItemDetail.clothes[index].similarity){
// designItemDetail.clothes[index].layersObject = item.layersObject
// designItemDetail.clothes[index].priority = item.layersObject[0].priority
// break
// }
// }
// })
this.$emit('setDesignCoverage');
this.store.commit("setDesignItemDetail", designItemDetail);
this.setRevocation(designItemDetail,data)
this.clear()
}
).catch(res=>{
// this.$parent.loadingShow = false
this.$emit('setParentLoadingShow');
});
},
},
});
</script>
<style lang="less" scoped>
.designOpenrtion_modal {
// max-width: 1440px;
user-select: none; /* 对现代浏览器有效 */
-webkit-user-select: none; /* Safari */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* Internet Explorer/Edge */
.ant-modal-body{
padding: calc(5rem*1.2) calc(6rem*1.2) calc(0rem*1.2)!important;
// height: calc(65vh - 6.4rem*1.2));
height: calc(65rem*1.2);
display: flex;
overflow-y: hidden;
flex-direction: column;
}
.ant-modal-content{
border-radius: calc(1rem*1.2);
overflow: hidden;
}
}
.design_compile_content {
// background: #f2f3fb;
// padding-bottom: 2.9rem*1.2);
display: flex;
flex-direction: column;
height: 100%;
width: 100%;
width: 50%;
position: relative;
overflow: hidden;
.designOpenrtion_centent{
// flex: 1;
height: 100%;
display: flex;
flex-direction: column;
align-content: space-around;
flex-wrap: nowrap;
margin: 0 auto;
// overflow: hidden;
justify-content: space-between;
user-select:none;
z-index: 2;
&.active{
flex-direction: row;
}
.designOpenrtion_imgMask{
width: auto;
height: auto;
position: relative;
height: calc(100% - 1.2rem - 4.8rem - 20%);
// overflow: hidden;
>img{
z-index: 2;
position: relative;
}
>div{
position: absolute;
width: 100%;
height: 100%;
top: 0;
}
}
.detail_modal_body_nav{
display: flex;
position: relative;
top: 0;
left: 50%;
z-index: 999;
transform: translate(-50%,-0%);
transition: all .3s;
justify-content: center;
margin-bottom: calc(1rem*1.2);
>div{
width: calc(4rem*1.2);
height: calc(4rem*1.2);
cursor: pointer;
text-align: center;
margin-left: calc(.3rem*1.2);
img{
// width: 100%;
height: 100%;
max-width: 100%;
object-fit: cover;
}
&.active{
border: 2px solid rgba(0,0,0,0.4);
img{
transform: scale(.8);
opacity: .8;
}
}
}
>div:nth-child(1){
margin-left: calc(0rem*1.2);
}
}
.designOpenrtion_print,.detail_modal_item_front{
z-index: 1;
img{
width: 100%;
height: 100%;
float: left;
user-select:none;
-webkit-user-drag: none;
}
.modal_imgItem{
position: absolute;
top: 0;
}
}
.designOpenrtion_print{
z-index: 1 !important;
}
.designOpenrtion_btn{
z-index: 9999;
ul{
list-style: none;
// width: 100%;
// height: 100%;
position: absolute;
top: 0;
left: 0;
box-sizing: border-box;
border: 2px solid rgb(20, 188, 255);
padding: 0;
-webkit-user-drag: none;
user-select:none;
opacity: 0;
margin: 0;
li{
cursor: pointer;
// border-radius: 50%;
width: calc(2rem*1.2);
height: calc(2rem*1.2);
background-color: rgb(20, 188, 255);
position: absolute;
pointer-events: none;
}
&.active{
opacity: 1;
li{
pointer-events: auto;
}
}
.designOpenrtion_btn_top,.designOpenrtion_btn_bottom{
left: 50%;
transform: translate(-50%,-50%) ;
cursor: n-resize;
}
.designOpenrtion_btn_top{
top: 0;
}
.designOpenrtion_btn_bottom{
top: 100%;
}
.designOpenrtion_btn_left,.designOpenrtion_btn_right{
top: 50%;
transform: translate(-50%,-50%) ;
cursor: e-resize;
}
.designOpenrtion_btn_left{
left: 0;
}
.designOpenrtion_btn_right{
left: 100%;
}
.designOpenrtion_rotote{
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
width: 0;
height: 0;
}
.designOpenrtion_rotote::after{
position: absolute;
content: "";
background-color: #14bcff;
width: 2px;
height: 30px;
left: 50%;
bottom: 0;
transform: translateX(-50%);
}
.designOpenrtion_rotote::before{
position: absolute;
content: "";
background-color: #14bcff;
top: calc(50% - 30px);
left: 50%;
transform: translate(-50%,-50%) ;
width: calc(1.5rem*1.2);
height: calc(1.5rem*1.2);
border-radius: 50%;
}
}
}
.subitOkPreviewBtn{
z-index: 2;
// margin-bottom: calc(1rem*1.2);
margin-bottom: 4rem;
width: calc(10rem*1.2);
text-align: center;
bottom: 0;
position: relative;
}
}
.designOpenrtion_imgMask_open{
position: absolute;
width: 100%;
height: 100%;
}
}
</style>