Files
aida_front/src/component/Canvas/index1.vue
X1627315083 c266967f16 接入画布
2025-06-09 10:25:54 +08:00

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>