布局修改 部分bug修复
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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
@@ -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>
|
||||
@@ -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"/>
|
||||
|
||||
468
src/component/Detail/canvas/index.vue
Normal file
468
src/component/Detail/canvas/index.vue
Normal 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>
|
||||
416
src/component/Detail/detailLeft/colorBox/index.vue
Normal file
416
src/component/Detail/detailLeft/colorBox/index.vue
Normal 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 value(e.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>
|
||||
641
src/component/Detail/detailLeft/colorBox/pallet.vue
Normal file
641
src/component/Detail/detailLeft/colorBox/pallet.vue
Normal 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>
|
||||
258
src/component/Detail/detailLeft/colorBox/upload.vue
Normal file
258
src/component/Detail/detailLeft/colorBox/upload.vue
Normal 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>
|
||||
162
src/component/Detail/detailLeft/element.vue
Normal file
162
src/component/Detail/detailLeft/element.vue
Normal 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>
|
||||
79
src/component/Detail/detailLeft/index.vue
Normal file
79
src/component/Detail/detailLeft/index.vue
Normal 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>
|
||||
172
src/component/Detail/detailLeft/models.vue
Normal file
172
src/component/Detail/detailLeft/models.vue
Normal 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>
|
||||
135
src/component/Detail/detailLeft/module/currentList.vue
Normal file
135
src/component/Detail/detailLeft/module/currentList.vue
Normal 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>
|
||||
408
src/component/Detail/detailLeft/module/libraryList.vue
Normal file
408
src/component/Detail/detailLeft/module/libraryList.vue
Normal 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>
|
||||
207
src/component/Detail/detailLeft/module/selectList.vue
Normal file
207
src/component/Detail/detailLeft/module/selectList.vue
Normal 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>
|
||||
229
src/component/Detail/detailLeft/module/uploadList.vue
Normal file
229
src/component/Detail/detailLeft/module/uploadList.vue
Normal 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>
|
||||
309
src/component/Detail/detailLeft/module/uploadModel.vue
Normal file
309
src/component/Detail/detailLeft/module/uploadModel.vue
Normal 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>
|
||||
|
||||
203
src/component/Detail/detailLeft/module/uploadSegmentation.vue
Normal file
203
src/component/Detail/detailLeft/module/uploadSegmentation.vue
Normal 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>
|
||||
161
src/component/Detail/detailLeft/print.vue
Normal file
161
src/component/Detail/detailLeft/print.vue
Normal 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>
|
||||
181
src/component/Detail/detailLeft/sketch.vue
Normal file
181
src/component/Detail/detailLeft/sketch.vue
Normal 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>
|
||||
1124
src/component/Detail/detailRight/editPrintElement.vue
Normal file
1124
src/component/Detail/detailRight/editPrintElement.vue
Normal file
File diff suppressed because it is too large
Load Diff
116
src/component/Detail/detailRight/index.vue
Normal file
116
src/component/Detail/detailRight/index.vue
Normal 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>
|
||||
67
src/component/Detail/detailRight/modelsType.vue
Normal file
67
src/component/Detail/detailRight/modelsType.vue
Normal 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>
|
||||
112
src/component/Detail/detailRight/printType.vue
Normal file
112
src/component/Detail/detailRight/printType.vue
Normal 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>
|
||||
67
src/component/Detail/detailRight/sketchType.vue
Normal file
67
src/component/Detail/detailRight/sketchType.vue
Normal 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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
202
src/component/Detail/model/index.vue
Normal file
202
src/component/Detail/model/index.vue
Normal 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>
|
||||
311
src/component/Detail/model/modelNav.vue
Normal file
311
src/component/Detail/model/modelNav.vue
Normal 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>
|
||||
595
src/component/Detail/model/modelPosition.vue
Normal file
595
src/component/Detail/model/modelPosition.vue
Normal 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>
|
||||
@@ -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>
|
||||
Reference in New Issue
Block a user