360 lines
9.8 KiB
Vue
360 lines
9.8 KiB
Vue
<template>
|
|
<div class="generalCanvas">
|
|
<div class="argument-box">
|
|
<argument ref="argument" v-if="canvasObj.canvas" :elementList="elementList"></argument>
|
|
</div>
|
|
<div class="canvasBox">
|
|
<tool ref="tool" v-if="canvasObj.canvas" @toolLiquefaction="toolLiquefaction"></tool>
|
|
<div class="canvas">
|
|
<canvasContent ref="canvasContent"></canvasContent>
|
|
</div>
|
|
<div class="detail-box">
|
|
<detail ref="detail" v-if="canvasObj.canvas"></detail>
|
|
</div>
|
|
</div>
|
|
<div class="mark_loading" v-show="isShowMark">
|
|
<a-spin size="large" />
|
|
</div>
|
|
<div style="display: flex; justify-content: center; margin-top: 2rem;">
|
|
<div class="gallery_btn" style="margin: 0 2rem;" @click="setShare">{{ $t('exportModel.Share') }}</div>
|
|
<div class="gallery_btn" style="margin: 0 2rem;" @click="setExport">{{ $t('exportModel.Export') }}</div>
|
|
<div class="gallery_btn" style="margin: 0 2rem;" @click="setExport">{{ $t('exportModel.Export') }}</div>
|
|
</div>
|
|
<liquefaction ref="liquefaction" @submitLiquefaction="submitLiquefaction"></liquefaction>
|
|
<publish ref="publish" @clearPublish="()=>{}"></publish>
|
|
</div>
|
|
</template>
|
|
<script>
|
|
import {defineComponent, computed, provide, h, ref, watch, onBeforeUnmount, reactive, onMounted, toRefs,
|
|
} from "vue";
|
|
import {message} from 'ant-design-vue'
|
|
import { Https } from "@/tool/https";
|
|
import { useStore } from "vuex";
|
|
import { useI18n } from "vue-i18n";
|
|
import canvasGeneral from "@/tool/canvasGeneralCopy";
|
|
import tool from "./tool.vue"
|
|
import argument from "./argument.vue"
|
|
import detail from "./detail.vue"
|
|
import canvasContent from "./canvasContent.vue"
|
|
import liquefaction from "@/component/modules/liquefaction.vue";
|
|
|
|
import JSZip, { forEach } from "jszip";
|
|
import publish from "@/component/WorksPage/publish.vue";
|
|
|
|
export default defineComponent({
|
|
components: {
|
|
tool,
|
|
argument,
|
|
detail,
|
|
canvasContent,
|
|
liquefaction,publish
|
|
},
|
|
props: {
|
|
isState: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
},
|
|
setup(props,{emit}) {
|
|
watch(()=>props.isState,(newVal)=>{
|
|
if(!newVal && canvasObj)canvasObj.clearEvent()
|
|
})
|
|
const { t } = useI18n();
|
|
const store = useStore();
|
|
const isShowMark = ref(false)
|
|
let liquefaction = ref(null)
|
|
let liquefactionData = ref()
|
|
let groupDashed = ref(null)//用来判断是否需要对group添加img
|
|
let canvasType = 'export'
|
|
let canvasObj = reactive(new canvasGeneral('export'))
|
|
const dataDom = reactive({
|
|
argument:null,
|
|
canvasContent:null,
|
|
tool:null,
|
|
detail:null,
|
|
publish:null,
|
|
})
|
|
let data = reactive({
|
|
elementList:null,
|
|
showCanvas:false,
|
|
|
|
})
|
|
provide('canvasType',canvasType)
|
|
provide('canvasObj',canvasObj)
|
|
provide('isShowMark',isShowMark)
|
|
const close = ()=>{
|
|
dataDom.forEach((item)=>{
|
|
if(item.closeModal)item.closeModal()
|
|
})
|
|
}
|
|
|
|
let expoet = ()=>{
|
|
console.log( canvasObj.selectExport());
|
|
console.log( canvasObj.allExport());
|
|
|
|
}
|
|
const setLiquefaction = async ()=>{//进入液化页面
|
|
canvasObj.getLiquefactionImgObj().then((data)=>{
|
|
if(data?.img){
|
|
liquefactionData.value = data
|
|
liquefaction.value.init(data.img)
|
|
}else {
|
|
message.info(t('exportModel.jsContent6'))
|
|
return null;
|
|
}
|
|
})
|
|
|
|
}
|
|
const toolLiquefaction = ()=>{//工具点击按钮
|
|
setLiquefaction()
|
|
}
|
|
const submitLiquefaction = (rv)=>{//液化回参
|
|
canvasObj.setLiquefactionImgObj(liquefactionData.value,rv)
|
|
// liquefactionData.value.setSrc(rv, (value)=>{
|
|
// // liquefactionData.value.scaleToWidth(originalWidth);
|
|
// // liquefactionData.value.scaleToHeight(originalHeight);
|
|
// delete liquefactionData.value.minioUrl
|
|
// if(groupDashed.value && groupDashed.value._objects.length == 1){
|
|
// value.set({
|
|
// left:-groupDashed.value.width/2,
|
|
// top:-groupDashed.value.height/2,
|
|
// })
|
|
// groupDashed.value.insertAt(value)
|
|
// // canvasObj.addDashedImg(value)
|
|
// }
|
|
// canvasObj.canvas.renderAll();
|
|
// canvasObj.updateCanvasState()
|
|
// });
|
|
}
|
|
const getCanvasData = ()=>{
|
|
if(!canvasObj.canvas)return
|
|
var json = canvasObj.canvas.toJSON(['src','minioUrl','custom','perPixelTargetFind','hasBorders','selectable','hasControls','erasable']);
|
|
json.objects.forEach(item=>{
|
|
if(item.type == 'image'){
|
|
delete item.src
|
|
}
|
|
})
|
|
let canvasExport = {
|
|
canvas:json,
|
|
groupList: canvasObj.layer.list
|
|
}
|
|
return canvasExport
|
|
}
|
|
const openSetData = async ()=>{
|
|
//获取所有所选元素
|
|
let arr = store.state.Workspace.projectList
|
|
let obj = {}
|
|
for (let index = 0; index < arr.length; index++) {
|
|
const item = arr[index];
|
|
await new Promise((resolve, reject) => {
|
|
store.dispatch('getProjectCanvasData',item.value).then((value)=>{
|
|
const keys = Object.keys(value)[0];
|
|
if(!value[keys] || value[keys].length == 0){
|
|
resolve('')
|
|
return
|
|
}
|
|
if(keys == 'design'){
|
|
value[keys].forEach((designItem)=>{
|
|
let minioUrl = designItem.url
|
|
designItem.url = designItem.designOutfitUrl
|
|
designItem.minioUrl = designItem.minioUrl
|
|
})
|
|
}
|
|
let rv = {
|
|
list:value[keys],
|
|
name:item.name,
|
|
}
|
|
obj[keys] = rv
|
|
resolve('')
|
|
})
|
|
})
|
|
}
|
|
data.elementList = obj
|
|
//获取所有所选元素 END
|
|
|
|
if(data.showCanvas)return
|
|
data.showCanvas = true
|
|
dataDom.canvasContent.openSetData()
|
|
}
|
|
let setShare = async ()=>{
|
|
dataDom.publish.publishMask = true
|
|
canvasObj.detailSubmit().then((img)=>{
|
|
let data = {
|
|
"imgUrl":img,
|
|
userlikeGroupId:store.state.Workspace.probjects.id,
|
|
}
|
|
dataDom.publish.init(data)
|
|
})
|
|
|
|
}
|
|
//设置导出
|
|
let setExport = async () => {
|
|
var imageDataURL = await canvasObj.detailSubmit()
|
|
let a = document.createElement("a");
|
|
let img = [];
|
|
let index = 0;
|
|
img.push({
|
|
imgUrl: imageDataURL,
|
|
name: "collection.png",
|
|
});
|
|
let num = 0;
|
|
for (let key in data.elementList) {
|
|
for (let index = 0; index < data.elementList[key].list.length; index++) {
|
|
const item = data.elementList[key].list[index];
|
|
let url = item.imgUrl || item.url || item.designOutfitUrl || item.minioUrl
|
|
let name = url?.split(".").pop().split("?").shift();
|
|
img.push({imgUrl:url,name:`element${index}.${name}`})
|
|
}
|
|
}
|
|
downImg(img);
|
|
};
|
|
let getImgArrayBuffer = (url) => {
|
|
return new Promise((resolve, reject) => {
|
|
//通过请求获取文件blob格式
|
|
let xmlhttp = new XMLHttpRequest();
|
|
xmlhttp.open("GET", url, true);
|
|
xmlhttp.responseType = "blob";
|
|
xmlhttp.withCredentials = false;
|
|
xmlhttp.onload = function () {
|
|
if (this.status == 200) {
|
|
resolve(this.response);
|
|
} else {
|
|
reject(this.status);
|
|
}
|
|
};
|
|
xmlhttp.send();
|
|
});
|
|
};
|
|
let downImg = (imagesParams) => {
|
|
let zip = new JSZip();
|
|
let cache = {};
|
|
let promises = [];
|
|
for (let item of imagesParams) {
|
|
const promise = getImgArrayBuffer(item.imgUrl).then((data) => {
|
|
// 下载文件, 并存成ArrayBuffer对象(blob)
|
|
zip.file(item.name, data, { binary: true }); // 逐个添加文件
|
|
cache[item.title] = data;
|
|
})
|
|
promises.push(promise);
|
|
}
|
|
Promise.all(promises)
|
|
.then(() => {
|
|
function downloadBlob(blob, filename) {
|
|
const link = document.createElement('a');
|
|
const url = URL.createObjectURL(blob);
|
|
link.href = url;
|
|
link.download = filename;
|
|
document.body.appendChild(link);
|
|
link.click();
|
|
URL.revokeObjectURL(url);
|
|
document.body.removeChild(link);
|
|
}
|
|
zip.generateAsync({ type: "blob" }).then((content) => {
|
|
// 生成二进制流
|
|
downloadBlob(content,'DesignFiles')
|
|
// FileSaver.saveAs(content, "DesignFiles"); // 利用file-saver保存文件 自定义文件名
|
|
isShowMark.value = false;
|
|
|
|
});
|
|
setSubmit()//导出的时候保存
|
|
initAligningGuidelines(canvas,true)
|
|
|
|
})
|
|
.catch((res) => {
|
|
// message.warning(t('HomeView.jsContent3'));
|
|
isShowMark.value = false;
|
|
initAligningGuidelines(canvas,true)
|
|
});
|
|
};
|
|
onMounted(() => {
|
|
});
|
|
onBeforeUnmount(()=>{
|
|
canvasObj.canvasClear()
|
|
})
|
|
return {
|
|
isShowMark,
|
|
liquefaction,
|
|
...toRefs(dataDom),
|
|
...toRefs(data),
|
|
canvasObj,
|
|
close,
|
|
expoet,
|
|
toolLiquefaction,
|
|
submitLiquefaction,
|
|
getCanvasData,
|
|
openSetData,
|
|
setShare,
|
|
setExport,
|
|
};
|
|
},
|
|
data(prop) {
|
|
return {
|
|
};
|
|
},
|
|
computed: {
|
|
},
|
|
watch: {
|
|
|
|
},
|
|
mounted() {},
|
|
|
|
methods: {
|
|
|
|
},
|
|
});
|
|
</script>
|
|
<style lang="less" scoped>
|
|
.generalCanvas{
|
|
width: 100%;
|
|
height: 100%;
|
|
position: relative;
|
|
display: flex;
|
|
flex-direction: column;
|
|
overflow: hidden;
|
|
.argument-box,
|
|
.canvasBox,
|
|
.detail-box{
|
|
:deep(i){
|
|
font-size: 2.5rem;
|
|
cursor: pointer;
|
|
width: 5rem;
|
|
height: 5rem;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
flex-shrink: 0;
|
|
transition: all .3s;
|
|
margin-bottom: .5rem;
|
|
padding: 1rem;
|
|
&.active{
|
|
border: 1px solid;
|
|
border-radius: .4rem;
|
|
}
|
|
&.icon-xiala{
|
|
transform: rotate(-90deg);
|
|
}
|
|
&.icon-xialaActive{
|
|
transform: rotate(90deg);
|
|
}
|
|
}
|
|
}
|
|
.argument-box{
|
|
margin-left: 4rem;
|
|
height: 4rem;
|
|
margin-bottom: 1rem;
|
|
}
|
|
.canvasBox{
|
|
flex: 1;
|
|
overflow: hidden;
|
|
display: flex;
|
|
.canvas{
|
|
flex: 1;
|
|
overflow: hidden;
|
|
}
|
|
}
|
|
.detail-box{
|
|
width: 20%;
|
|
margin-left: 1rem;
|
|
}
|
|
}
|
|
</style> |