2025-02-17 15:24:01 +08:00
|
|
|
<template>
|
|
|
|
|
<div class="canvasBox">
|
|
|
|
|
<!-- designDetailShow -->
|
|
|
|
|
<!-- :class="[driver__.driver?'hideEvents':'']" -->
|
2025-06-23 09:27:29 +08:00
|
|
|
<div class="canvasContent" ref="canvasContent">
|
|
|
|
|
<!-- <div class="argument-box">
|
2025-02-25 15:32:55 +08:00
|
|
|
<argument
|
|
|
|
|
ref="argument"
|
|
|
|
|
class="argument"
|
|
|
|
|
v-if="canvasObj.id || frontBackCanvasObj.id"
|
|
|
|
|
@toolLiquefaction="toolLiquefaction"
|
|
|
|
|
@setFrontBackColor="setFrontBackColor"
|
|
|
|
|
:isEditFrontBack="isEditFrontBack">
|
|
|
|
|
</argument>
|
2025-06-23 09:27:29 +08:00
|
|
|
</div> -->
|
|
|
|
|
<div class="content-bottom" ref="canvasContent">
|
|
|
|
|
<!-- <div class="tool-box">
|
2025-02-25 15:32:55 +08:00
|
|
|
<tool ref="tool" class="tool" v-if="canvasObj.id || frontBackCanvasObj.id" @toolLiquefaction="toolLiquefaction" @editFront="editFront" :isEditFrontBack="isEditFrontBack"></tool>
|
2025-06-23 09:27:29 +08:00
|
|
|
</div> -->
|
2025-02-25 15:32:55 +08:00
|
|
|
<div class="contet">
|
2025-06-26 15:41:08 +08:00
|
|
|
<div class="canvas" v-if="!isEditFrontBack" @click.stop>
|
2025-06-23 09:27:29 +08:00
|
|
|
<editCanvas v-if="canvasLoad" :config="canvasConfig"
|
|
|
|
|
:clothingImageUrl="selectDetail.undividedLayer"
|
2025-06-26 15:41:08 +08:00
|
|
|
isFixedErasable
|
2025-06-23 09:27:29 +08:00
|
|
|
:clothing-image-opts="{
|
|
|
|
|
imageMode:'contains',
|
|
|
|
|
}"
|
|
|
|
|
ref="editCanvas"></editCanvas>
|
|
|
|
|
<!-- <canvasContent ref="canvasContent"></canvasContent> -->
|
2025-02-25 15:32:55 +08:00
|
|
|
</div>
|
|
|
|
|
<div class="editFrontBack" v-if="isEditFrontBack" @click.stop>
|
2025-06-23 09:27:29 +08:00
|
|
|
<!-- <editFrontBack
|
2025-02-25 15:32:55 +08:00
|
|
|
:patchData="frontBack"
|
|
|
|
|
:imgDomIndex="imgDomIndex"
|
|
|
|
|
|
|
|
|
|
ref="editFrontBack">
|
2025-06-23 09:27:29 +08:00
|
|
|
</editFrontBack> -->
|
2025-06-26 15:41:08 +08:00
|
|
|
<editCanvas v-if="canvasLoad" :config="canvasConfig"
|
2025-06-23 09:27:29 +08:00
|
|
|
:enabledRedGreenMode="true"
|
|
|
|
|
:clothingImageUrl="selectDetail.undividedLayer"
|
|
|
|
|
:redGreenImageUrl="frontBack.front[imgDomIndex].maskUrl"
|
|
|
|
|
@trigger-red-green-mouseup="frontBackChange"
|
|
|
|
|
:clothing-image-opts="{
|
|
|
|
|
imageMode:'contains',
|
|
|
|
|
}"
|
|
|
|
|
ref="editCanvasBackFront"></editCanvas>
|
2025-02-25 15:32:55 +08:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- <div class="Finish">
|
|
|
|
|
<div class="gallery_btn" @click="privewDetail">Finish</div>
|
|
|
|
|
</div> -->
|
2025-02-17 15:24:01 +08:00
|
|
|
</div>
|
2025-06-26 15:41:08 +08:00
|
|
|
<div class="Finish" style="text-align: right;margin-top:1rem;">
|
|
|
|
|
<div class="gallery_btn" style="line-height: 4rem;padding: 0 1rem;" @click="editFront">EditFrontBack</div>
|
2025-06-23 09:27:29 +08:00
|
|
|
</div>
|
2025-02-17 15:24:01 +08:00
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- <div class="mark_loading" v-show="isShowMark">
|
|
|
|
|
<a-spin size="large" />
|
|
|
|
|
</div> -->
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
</template>
|
|
|
|
|
<script lang="ts">
|
2025-02-25 15:32:55 +08:00
|
|
|
import { defineComponent,computed,onBeforeUnmount,provide,nextTick,watch,toRefs, reactive} from 'vue'
|
2025-02-17 15:24:01 +08:00
|
|
|
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'
|
2025-02-25 15:32:55 +08:00
|
|
|
import editFrontBack from '@/component/Detail/editFrontBack.vue'
|
2025-06-23 09:27:29 +08:00
|
|
|
import editCanvas from "@/component/Canvas/CanvasEditor/index.vue";
|
|
|
|
|
import { formatTime,segmentImage } from "@/tool/util";
|
2025-02-25 15:32:55 +08:00
|
|
|
|
2025-02-17 15:24:01 +08:00
|
|
|
|
|
|
|
|
import canvasGeneral from "@/tool/canvasGeneralCopy";
|
|
|
|
|
import argument from './argument.vue'
|
|
|
|
|
import canvasContent from './canvasContent.vue'
|
|
|
|
|
import tool from "./tool.vue"
|
|
|
|
|
|
|
|
|
|
export default defineComponent({
|
|
|
|
|
components:{
|
2025-06-23 09:27:29 +08:00
|
|
|
tool,argument,editFrontBack,editCanvas
|
2025-02-17 15:24:01 +08:00
|
|
|
},
|
|
|
|
|
setup(props,{emit}) {
|
|
|
|
|
const store = useStore();
|
2025-02-25 15:32:55 +08:00
|
|
|
const {t} = useI18n();
|
2025-02-17 15:24:01 +08:00
|
|
|
|
|
|
|
|
const detailDom = reactive({
|
2025-02-25 15:32:55 +08:00
|
|
|
editFrontBack:null as any,
|
|
|
|
|
model:null,
|
2025-06-23 09:27:29 +08:00
|
|
|
editCanvas:null as any,
|
2025-06-26 15:41:08 +08:00
|
|
|
editCanvasBackFront:null as any,
|
2025-06-23 09:27:29 +08:00
|
|
|
canvasContent:null as any,
|
2025-02-17 15:24:01 +08:00
|
|
|
})
|
|
|
|
|
const userDetail = computed(()=>{
|
|
|
|
|
return store.state.UserHabit.userDetail
|
|
|
|
|
})
|
|
|
|
|
const detailData = reactive({
|
2025-02-25 15:32:55 +08:00
|
|
|
canvasObj:new canvasGeneral('aa'),
|
|
|
|
|
frontBackCanvasObj:new canvasGeneral('vv'),
|
|
|
|
|
isShowMark:false,
|
|
|
|
|
liquefactionData:null as any,
|
|
|
|
|
liquefaction:null as any,
|
|
|
|
|
canvasType:'export',
|
|
|
|
|
imgDomIndex:-1,
|
|
|
|
|
isEditFrontBack:false,
|
|
|
|
|
selectDetail:computed(()=>store.state.DesignDetailCopy.selectDetail),
|
|
|
|
|
frontBack:computed(()=>store.state.DesignDetailCopy.frontBack),
|
2025-06-23 09:27:29 +08:00
|
|
|
canvasLoad:false,
|
|
|
|
|
canvasConfig:{
|
|
|
|
|
} as any,
|
2025-02-17 15:24:01 +08:00
|
|
|
})
|
2025-02-25 15:32:55 +08:00
|
|
|
watch(()=>detailData.selectDetail,(newValue,oldValue)=>{
|
|
|
|
|
detailData.imgDomIndex = detailData.frontBack.front.findIndex((item:any)=>item.id == newValue.id)
|
2025-04-09 14:09:19 +08:00
|
|
|
// privewDetail(oldValue)
|
2025-02-25 15:32:55 +08:00
|
|
|
},{immediate: true})
|
|
|
|
|
provide('frontBackCanvasObj',detailData.frontBackCanvasObj)
|
|
|
|
|
provide('canvasObj',detailData.canvasObj)
|
|
|
|
|
provide('isShowMark',detailData.isShowMark)
|
|
|
|
|
provide('canvasType',detailData.canvasType)
|
|
|
|
|
|
|
|
|
|
const setLiquefaction = async ()=>{//进入液化页面
|
|
|
|
|
detailData.canvasObj.getLiquefactionImgObj().then((data)=>{
|
|
|
|
|
if(data?.img){
|
|
|
|
|
detailData.liquefactionData = data
|
|
|
|
|
detailData.liquefaction.init(data.img)
|
|
|
|
|
}else {
|
|
|
|
|
message.info(t('exportModel.jsContent6'))
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
const toolLiquefaction = ()=>{//工具点击按钮
|
|
|
|
|
setLiquefaction()
|
|
|
|
|
}
|
|
|
|
|
const editFront = ()=>{//编辑前后片
|
2025-06-26 15:41:08 +08:00
|
|
|
|
|
|
|
|
let canvasJSON = '' as any
|
|
|
|
|
if(!detailData.isEditFrontBack){
|
|
|
|
|
sessionStorage.setItem('sketchEdit',detailDom.editCanvas.getJSON())
|
|
|
|
|
canvasJSON = sessionStorage.getItem('frontBackEdit');
|
|
|
|
|
}else{
|
|
|
|
|
sessionStorage.setItem('frontBackEdit',detailDom.editCanvasBackFront.getJSON())
|
|
|
|
|
canvasJSON = sessionStorage.getItem('sketchEdit');
|
|
|
|
|
}
|
|
|
|
|
detailData.canvasLoad = false
|
2025-02-25 15:32:55 +08:00
|
|
|
detailData.isEditFrontBack = !detailData.isEditFrontBack
|
2025-06-26 15:41:08 +08:00
|
|
|
if(canvasJSON){
|
|
|
|
|
detailData.canvasLoad = true
|
2025-02-25 15:32:55 +08:00
|
|
|
nextTick(()=>{
|
2025-06-26 15:41:08 +08:00
|
|
|
if(!detailData.isEditFrontBack){
|
|
|
|
|
detailDom.editCanvas.loadJSON(canvasJSON)
|
|
|
|
|
}else{
|
|
|
|
|
detailDom.editCanvasBackFront.loadJSON(canvasJSON)
|
|
|
|
|
}
|
2025-02-25 15:32:55 +08:00
|
|
|
})
|
|
|
|
|
}else{
|
2025-06-26 15:41:08 +08:00
|
|
|
if(!detailData.isEditFrontBack){
|
|
|
|
|
nextTick(()=>{
|
|
|
|
|
setCanvas(detailData.selectDetail.undividedLayer).then(()=>{
|
|
|
|
|
detailData.canvasLoad = true
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
}else{
|
|
|
|
|
nextTick(()=>{
|
|
|
|
|
setCanvas(detailData.frontBack.front[detailData.imgDomIndex].maskUrl).then(()=>{
|
|
|
|
|
detailData.canvasLoad = true
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
}
|
2025-02-25 15:32:55 +08:00
|
|
|
}
|
|
|
|
|
}
|
2025-04-09 14:09:19 +08:00
|
|
|
const privewDetail = async (oldSelectDetail = detailData.selectDetail)=>{
|
2025-06-26 15:41:08 +08:00
|
|
|
return new Promise((res,reject)=>{
|
|
|
|
|
detailDom.editCanvas.exportImage({isContainBg:false,isContainFixed:true}).then((rv)=>{
|
|
|
|
|
// let data = await detailData.canvasObj.detailSubmit()
|
|
|
|
|
if(oldSelectDetail.partialDesign)oldSelectDetail.partialDesign.partialDesignBase64 = rv
|
|
|
|
|
res('')
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
2025-02-25 15:32:55 +08:00
|
|
|
}
|
|
|
|
|
const setFrontBackColor = (data:any)=>{
|
|
|
|
|
detailDom.editFrontBack.setBackground(data)
|
|
|
|
|
}
|
2025-06-23 09:27:29 +08:00
|
|
|
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)=>{
|
|
|
|
|
detailData.frontBack.front[detailData.imgDomIndex].imageUrl = rv.targetFrontUrl
|
|
|
|
|
detailData.frontBack.back[detailData.imgDomIndex].imageUrl = rv.targetBackUrl
|
|
|
|
|
detailData.frontBack.front[detailData.imgDomIndex].maskUrl = value
|
|
|
|
|
store.commit('DesignDetailCopy/updataDetailItem',{maskUrl:value})
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
}
|
2025-02-17 15:24:01 +08:00
|
|
|
onBeforeUnmount(()=>{
|
2025-06-26 15:41:08 +08:00
|
|
|
console.log(12312)
|
|
|
|
|
sessionStorage.removeItem('frontBackEdit');
|
|
|
|
|
sessionStorage.removeItem('sketchEdit');
|
2025-06-23 09:27:29 +08:00
|
|
|
detailData.canvasLoad = false
|
2025-02-25 15:32:55 +08:00
|
|
|
privewDetail()
|
2025-02-17 15:24:01 +08:00
|
|
|
})
|
2025-06-23 09:27:29 +08:00
|
|
|
onMounted(()=>{
|
|
|
|
|
nextTick(()=>{
|
|
|
|
|
setCanvas(detailData.selectDetail.undividedLayer).then(()=>{
|
|
|
|
|
detailData.canvasLoad = true
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
})
|
2025-02-17 15:24:01 +08:00
|
|
|
return{
|
|
|
|
|
...toRefs(detailDom),
|
|
|
|
|
...toRefs(detailData),
|
2025-02-25 15:32:55 +08:00
|
|
|
toolLiquefaction,
|
|
|
|
|
editFront,
|
|
|
|
|
privewDetail,
|
|
|
|
|
setFrontBackColor,
|
2025-06-23 09:27:29 +08:00
|
|
|
frontBackChange,
|
2025-02-17 15:24:01 +08:00
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
provide() {
|
|
|
|
|
return {
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
mounted(){
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
})
|
|
|
|
|
</script>
|
|
|
|
|
<style lang="less" scoped>
|
|
|
|
|
.canvasBox{
|
|
|
|
|
flex: 1;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
// top: -100%;
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
2025-02-25 15:32:55 +08:00
|
|
|
.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;
|
|
|
|
|
}
|
2025-02-17 15:24:01 +08:00
|
|
|
.argument-box,
|
2025-02-25 15:32:55 +08:00
|
|
|
.content-bottom,
|
2025-02-17 15:24:01 +08:00
|
|
|
.detail-box{
|
2025-02-25 15:32:55 +08:00
|
|
|
|
2025-02-17 15:24:01 +08:00
|
|
|
:deep(i){
|
|
|
|
|
font-size: 2.5rem;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
width: 3rem;
|
|
|
|
|
height: 3rem;
|
|
|
|
|
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);
|
|
|
|
|
}
|
2025-02-25 15:32:55 +08:00
|
|
|
&.eventNone{
|
|
|
|
|
cursor: no-drop;
|
|
|
|
|
border: none;
|
|
|
|
|
opacity: .5;
|
|
|
|
|
}
|
2025-02-17 15:24:01 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
.canvasContent{
|
2025-03-03 14:52:05 +08:00
|
|
|
height: 100%;
|
|
|
|
|
// height: 70rem;
|
2025-02-17 15:24:01 +08:00
|
|
|
width: 100%;
|
|
|
|
|
border: 2px solid #000;
|
|
|
|
|
border-radius: 3rem;
|
|
|
|
|
padding: 4rem;
|
2025-02-25 15:32:55 +08:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-02-17 15:24:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
</style>
|