922 lines
31 KiB
Vue
922 lines
31 KiB
Vue
<template>
|
||
<a-modal
|
||
class="modal_component Export"
|
||
v-model:visible="showUpgradePlan"
|
||
:footer="null"
|
||
width="78%"
|
||
:maskClosable="false"
|
||
:centered="true"
|
||
:closable="false"
|
||
:keyboard="false"
|
||
>
|
||
<div class="UpgradePlan_closeIcon">
|
||
<i class="fi fi-rr-cross-small" @click.stop="cancelDsign()"></i>
|
||
</div>
|
||
<div class="UpgradePlan_content">
|
||
<div>Export</div>
|
||
</div>
|
||
<!-- <div>
|
||
<canvas ref="exportCanvas"></canvas>
|
||
</div> -->
|
||
<div class="exportCanvasBox">
|
||
<div class="exportCanvasBox_left">
|
||
<div class="exportCanvasBox_title">Canvas Size</div>
|
||
<label>
|
||
<div>Width:</div>
|
||
<input type="number" @input="setMaxInput('width', 500)" v-model="canvasWH.width"/>
|
||
</label>
|
||
<label>
|
||
<div>Height:</div>
|
||
<input type="number" @input="setMaxInput('height', 10000)" v-model="canvasWH.height"/>
|
||
</label>
|
||
<div class="exportCanvasBox_title" @click.stop="setCloseNav(0)">
|
||
Canvas Nav
|
||
<div
|
||
:class="[
|
||
'icon',
|
||
'iconfont',
|
||
'icon-xiala',
|
||
closeNav==0?'icon-rotate':''
|
||
]"
|
||
>
|
||
</div>
|
||
</div>
|
||
<div class="exportCanvasBox_img" :class="{'closeNav' :closeNav==0}">
|
||
<div
|
||
class="exportCanvasBox_allItem"
|
||
v-for="(item,key) in allBoardData"
|
||
>
|
||
<div v-if="item[0]" class="exportCanvasBox_intro">{{ key }}</div>
|
||
<div class="exportCanvasBox_item_color" v-if="key == 'colorBoards'" v-for="colorItem in item" draggable="true" @dragstart="onDragstart(key,colorItem)">
|
||
<img src="" alt="">
|
||
<div class="exportCanvasBox_item_BGcolor" :style="{'background-color': 'rgb('+colorItem.rgbValue.r+','+colorItem.rgbValue.g+','+colorItem.rgbValue.b+')'}"></div>
|
||
<div>{{colorItem.tcx}}</div>
|
||
<div>{{colorItem.name}}</div>
|
||
</div>
|
||
|
||
<div
|
||
class="exportCanvasBox_item"
|
||
:class="[key == 'disposeMoodboard'?'exportCanvasBox_item_dispose':'']"
|
||
v-for="imgItem in item"
|
||
draggable
|
||
@dragstart="onDragstart(key,imgItem)"
|
||
>
|
||
<img :src="key == 'likeDesignCollectionList'?imgItem.designOutfitUrl:imgItem.imgUrl" alt="" />
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="exportCanvasBox_title" @click.stop="setCloseNav(1)">
|
||
Canvas Tool
|
||
<div
|
||
:class="[
|
||
'icon',
|
||
'iconfont',
|
||
'icon-xiala',
|
||
closeNav==1?'icon-rotate':''
|
||
]"
|
||
>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="exportCanvasBox_center">
|
||
<!-- <canvas ref="canvasDom" id="exportCanvas"></canvas> -->
|
||
</div>
|
||
<!-- <ExportNewCoolection ref="ExportNewCoolection"></ExportNewCoolection> -->
|
||
<div class="exportCanvasBox_right">
|
||
<div class="exportCanvasBox_title">
|
||
High-definition Download
|
||
</div>
|
||
<div @click="historyState(stateIndex - 1)">123</div>
|
||
<div @click="historyState(stateIndex + 1)">321</div>
|
||
<div class="exportCanvasBox_right_definition">
|
||
<label>
|
||
<div>Width:</div>
|
||
<input type="number" @input="setMaxInput('width', 500)" v-model="canvasWH.width"/>
|
||
</label>
|
||
<label>
|
||
<div>Height:</div>
|
||
<input type="number" @input="setMaxInput('height', 10000)" v-model="canvasWH.height" />
|
||
</label>
|
||
</div>
|
||
<div class="" @click="multiselect">all</div>
|
||
<div class="exportCanvasBox_right_btn">
|
||
<div class="subitOkPreviewBtn" @click="setExport">HD Export</div>
|
||
<div class="subitOkPreviewBtn" @click="setExport">Export</div>
|
||
</div>
|
||
</div>
|
||
<div class="mark_loading" v-show="isShowMark">
|
||
<a-spin size="large" />
|
||
</div>
|
||
</div>
|
||
</a-modal>
|
||
</template>
|
||
<script>
|
||
import {defineComponent, computed, h, ref, nextTick, inject, reactive, onMounted,
|
||
} from "vue";
|
||
import { Https } from "@/tool/https";
|
||
import { multiselectJS } from "@/tool/canvasDrawing";
|
||
import scaleImage from "@/component/HomePage/scaleImage.vue";
|
||
import ExportNewCoolection from "@/component/HomePage/ExportNewCoolection.vue";
|
||
import { useStore } from "vuex";
|
||
import JSZip, { forEach } from "jszip";
|
||
import { message, Modal } from "ant-design-vue";
|
||
const FileSaver = require("file-saver");
|
||
export default defineComponent({
|
||
components: {
|
||
scaleImage,
|
||
ExportNewCoolection,
|
||
},
|
||
props: ["msg", "sketchCatecoryList"],
|
||
setup() {
|
||
const store = useStore();
|
||
|
||
let showUpgradePlan = ref(false);
|
||
let canvas = reactive({});
|
||
// let canvasDom = ref()
|
||
let canvasWH = ref({
|
||
width: 400,
|
||
height: 1200,
|
||
});
|
||
canvasWH.value.width = [window.innerWidth/2.4]
|
||
canvasWH.value.width = canvasWH.value.width.map(num => Math.round(num / 100) * 100)[0];
|
||
let sketch = computed(() => {
|
||
return store.state.HomeStoreModule.showSketchList;
|
||
});
|
||
let sketchList = computed(() => {
|
||
return store.state.UploadFilesModule.showSketchboard;
|
||
});
|
||
let allBoardData = computed(() => {
|
||
return store.state.UploadFilesModule.allBoardData;
|
||
});
|
||
let likeDesignCollectionList = computed(() => {
|
||
return store.state.HomeStoreModule.likeDesignCollectionList;
|
||
});
|
||
let isShowMark = false;
|
||
// let allImage = Object.assign(allBoardData.value,{likeDesignCollectionList:likeDesignCollectionList.value})
|
||
let position = {
|
||
//设置每个图形位置的初始值
|
||
x: 0,
|
||
y: 0,
|
||
height: 0,
|
||
};
|
||
let sketchGrouping = 3; //sketch分组
|
||
let likeDesign = 4; //整体图分组
|
||
let disposeMoodboardShow = true;
|
||
|
||
|
||
let canvasState = ref([])//存放canvas操作
|
||
let stateIndex = ref(-1)//表示撤回数量
|
||
let isLoadCanvas = false//撤回或者反撤回false为撤回
|
||
let init = () => {
|
||
showUpgradePlan.value = true;
|
||
nextTick().then(async () => {
|
||
allBoardData.value.likeDesignCollectionList =
|
||
likeDesignCollectionList;
|
||
let canvasBox = document.querySelector(
|
||
".Export .exportCanvasBox_center"
|
||
);
|
||
canvasBox.innerHTML = ""; // 清空原有内容
|
||
var canvasDom = document.createElement("canvas");
|
||
canvasBox.appendChild(canvasDom);
|
||
canvas = new fabric.Canvas(canvasDom, {
|
||
backgroundColor: "rgba(255, 255, 255)",
|
||
// fill: '#ffde7d',
|
||
// selection: false, //设置多选
|
||
width: canvasWH.value.width,
|
||
height: canvasWH.value.height,
|
||
isDrawingMode: false, // 开启绘图模式
|
||
// preserveObjectStacking: true,
|
||
});
|
||
canvasOnDrop()//开启鼠标到画布事件
|
||
setRemoveImage()//设置元素删除
|
||
canvas.on("object:modified", ()=>{
|
||
updateCanvasState()
|
||
});
|
||
canvas.on('selection:created', ()=>{
|
||
updateCanvasState('created')
|
||
});
|
||
// canvas.on("object:added", updateCanvasState);
|
||
// setCanvasOperation()//设置监听添加修改画布元素,用来做撤回功能
|
||
let arr = [
|
||
"disposeMoodboard",
|
||
"moodboardFiles",
|
||
"printboardFiles",
|
||
"colorBoards",
|
||
"sketchboardFiles",
|
||
"likeDesignCollectionList",
|
||
];
|
||
|
||
|
||
let oldKey = "";
|
||
let margin = 20; //每个图形边距
|
||
// arr.forEach((item,index)=>{
|
||
for (const item of arr) {
|
||
for (const key in allBoardData.value) {
|
||
if (item == key) {
|
||
//循环渲染顺序
|
||
let imgWidth = setImageWidth(key); //这是设置画布等宽
|
||
let sketchGroupingItem = [];
|
||
if (
|
||
item == "moodboardFiles" &&
|
||
!disposeMoodboardShow
|
||
) {
|
||
continue;
|
||
}
|
||
for (const [allItemIndex, allItem,] of allBoardData.value[key].entries()) {
|
||
await new Promise((resolve, reject) => {
|
||
if (key == "colorBoards") {
|
||
let rect = setGroup(allItem)
|
||
if (position.x + rect.width > canvasWH.value.width || oldKey != key) {
|
||
position.x = 0;
|
||
position.y += position.height;
|
||
}
|
||
let group = setCanvasColor(position.y,position.x,rect)
|
||
oldKey = key;
|
||
position.x += rect.width + margin;
|
||
position.height = group.height + margin;
|
||
resolve();
|
||
} else {
|
||
let itemCanvasImg = allItem.imgUrl;
|
||
if (key == "likeDesignCollectionList") {
|
||
itemCanvasImg =
|
||
allItem.designOutfitUrl;
|
||
}
|
||
fabric.Image.fromURL(itemCanvasImg,(img) => {
|
||
let scaleWH = imgWidth / img.width; //计算放到画布上缩小倍率
|
||
if (position.x + img.width * scaleWH > canvasWH.value.width || oldKey != key) {
|
||
position.x = 0;
|
||
position.y += position.height;
|
||
}
|
||
setCanvasImage(img,key,position.x,position.y)//设置图片
|
||
|
||
position.height = img.height * scaleWH + margin;
|
||
if (key == "sketchboardFiles") {
|
||
position.x +=
|
||
img.width * scaleWH +
|
||
margin;
|
||
if (sketchGroupingItem.length >= 3) {
|
||
} else {
|
||
sketchGroupingItem.push(JSON.parse(JSON.stringify(position)));
|
||
}
|
||
if (sketchGroupingItem.length >=3) {
|
||
let sketchXyIndex = {
|
||
maxIndex: 0,
|
||
maxNum: 9999999999,
|
||
minNum: 0,
|
||
minIndex: 0,
|
||
};
|
||
sketchGroupingItem.forEach(
|
||
(sketchItem,sketchIndex) => {
|
||
if (sketchItem.height <sketchXyIndex.maxNum) {
|
||
sketchXyIndex.maxNum = sketchItem.height;
|
||
sketchXyIndex.maxIndex = sketchIndex;
|
||
}
|
||
if (sketchItem.height > sketchXyIndex.minNum) {
|
||
sketchXyIndex.minNum = sketchItem.height;
|
||
sketchXyIndex.minIndex = sketchIndex;
|
||
}
|
||
}
|
||
);
|
||
if (allBoardData.value[key].length == allItemIndex + 1) {
|
||
position = sketchGroupingItem[sketchXyIndex.minIndex];
|
||
} else {
|
||
position = sketchGroupingItem[ sketchXyIndex.maxIndex];
|
||
position.y += position.height;
|
||
position.x -= img.width * scaleWH + margin;
|
||
}
|
||
}
|
||
} else {
|
||
position.x += img.width * scaleWH;
|
||
}
|
||
img.lock_rotation = true;
|
||
canvas.add(img);
|
||
oldKey = key;
|
||
resolve();
|
||
},{ crossOrigin: "Anonymous" });
|
||
}
|
||
});
|
||
}
|
||
}
|
||
}
|
||
if(position.y+position.height>canvasWH.value.height){
|
||
canvasWH.value.height = Math.floor(position.y+position.height)
|
||
canvas.setHeight(canvasWH.value.height);
|
||
}
|
||
}
|
||
});
|
||
};
|
||
let setRemoveImage = ()=>{
|
||
let deleteObject = (eventData, transform)=> {
|
||
var target = [transform.target];
|
||
if(transform.target._objects){
|
||
target = transform.target._objects
|
||
}
|
||
// canvas.discardActiveObject() // 丢弃当前活动的对象和触发事件。 如果fabric作为鼠标事件的结果调用该函数,则将该事件作为参数传递给自定义事件的fire函数。 当作为一个方法使用时,参数没有任何应用。
|
||
// const sel = new fabric.ActiveSelection(canvas.getObjects(), {
|
||
// canvas
|
||
// })
|
||
target.forEach((item)=>{
|
||
var canvas = item.canvas;
|
||
canvas.remove(item);
|
||
})
|
||
canvas.requestRenderAll();
|
||
canvas.discardActiveObject() // 丢弃当前活动的对象和触发事件。 如果fabric作为鼠标事件的结果调用该函数,则将该事件作为参数传递给自定义事件的fire函数。 当作为一个方法使用时,参数没有任何应用。
|
||
}
|
||
const deleteIcon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAACXBIWXMAAACxAAAAsQHGLUmNAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAdBJREFUSImt1r1uU0EQBeDPFh1pgBQEEwFVAg9BROhCAh1FAg1gkMA8DA0oKOEB3IEIRQgF4SEQBIUC6ENSGgPFXaPx+udeSxxppPXOzJnZ8e7MrRmPWdzANZxPv+EbvmILL/G9hGcADayjgz8l0kUb56qSX8dhBeJcDrFSRv44ZRQdt3EPczieZB5NvB1ymta4zCP5J1yucOIFfM6CDJykob8s73GiAnkPJ7Eb/H9iJhpsZJlPQh6D7AWe9Z5iFr+CIpalhjWspnXZ/pXA01FURkv/HxpxK+g2UE+yGfZXM5+doHt4DEtB2R5dAXdD9nfG2LVxNa2XKGreiziXGefZ5rKZbCLmg/4jHIWNqSEZ1fC0IrnE0bM5qqdFGWoV92RBf/P/S3RRVqI3YaOZGd8eQpgHXMt8HgTd67qi5fZwMzOO5XuREmim9ShEji04q78tLwSDSR/aYuD599DgeVDsY3pMhqOQt4pnUXlGf7PbTQ5VcQofgv8BTudGK/rb9Z6it5RhEV+CX1cxYoeiZXDg7OC+4vpNJbmkuC3vMtsuHpVltKzo55OOzINxmeeYxhPVhn5H0ftnhhGNeu49NBSjdBkX9H+27Cvu+Sv8GEXwF9+O3b1zwZqdAAAAAElFTkSuQmCC"
|
||
// 创建删除图片元素
|
||
let deleteImg = document.createElement('img')
|
||
deleteImg.src = deleteIcon
|
||
function renderIcon(icon) {
|
||
return function (ctx, left, top, styleOverride, fabricObject) {
|
||
var size = this.cornerSize;
|
||
ctx.save();
|
||
ctx.translate(left, top);
|
||
ctx.rotate(fabric.util.degreesToRadians(fabricObject.angle));
|
||
ctx.drawImage(icon, -size/3, -size/3, size/1.5, size/1.5);
|
||
ctx.restore();
|
||
}
|
||
}
|
||
// 删除按钮控件
|
||
fabric.Object.prototype.controls.deleteControl = new fabric.Control({
|
||
x: 0.5,
|
||
y: -0.5,
|
||
offsetY: -16,
|
||
offsetX: 16,
|
||
cursorStyle: 'pointer',
|
||
mouseUpHandler: deleteObject,
|
||
render: renderIcon(deleteImg),
|
||
cornerSize: 24
|
||
})
|
||
}
|
||
//设置画布监听修改添加事件,用来做撤回功能
|
||
let updateCanvasState = (str) =>{
|
||
if (!isLoadCanvas) {
|
||
const canvasAsJson = JSON.stringify(canvas.toJSON());
|
||
if(str == 'created'){
|
||
if(canvasState.value.length == 0){
|
||
canvasState.value.push(canvasAsJson);
|
||
}
|
||
}else{
|
||
canvasState.value.push(canvasAsJson);
|
||
}
|
||
stateIndex.value = canvasState.value.length - 1;
|
||
} else {
|
||
isLoadCanvas = false;
|
||
}
|
||
}
|
||
let setImageWidth = (key)=>{
|
||
let imgWidth = canvasWH.value.width; //这是设置画布等宽
|
||
if (
|
||
disposeMoodboardShow &&
|
||
key == "disposeMoodboard" &&
|
||
allBoardData.value[key].length != 0 &&
|
||
allBoardData.value[key][0] != null
|
||
) {
|
||
//如果是mood 需要判断用户是否点击layout
|
||
disposeMoodboardShow = false;
|
||
}
|
||
|
||
if (key == "printboardFiles") {
|
||
imgWidth = canvasWH.value.width / 8;
|
||
}
|
||
if (key == "sketchboardFiles"||key == 'moodboardFiles') {
|
||
imgWidth =
|
||
(canvasWH.value.width -
|
||
(sketchGrouping - 1) * 20) /
|
||
sketchGrouping;
|
||
}
|
||
if (key == "likeDesignCollectionList") {
|
||
imgWidth =
|
||
(canvasWH.value.width -
|
||
(likeDesign - 1) * 20) /
|
||
likeDesign;
|
||
}
|
||
return imgWidth
|
||
}
|
||
let setCanvasImage = (img,key,left,top)=>{
|
||
let proportion = img.height / img.width; //计算图形宽高比例
|
||
let imgWidth = setImageWidth(key)
|
||
let scaleWH = imgWidth / img.width; //计算放到画布上缩小倍率
|
||
img.set({
|
||
// width: imgWidth/img.width,
|
||
// height: canvasWH.value.height/img.height,
|
||
left,
|
||
top,
|
||
scaleX:
|
||
imgWidth / img.width,
|
||
scaleY:(img.width * proportion * scaleWH) / img.height,
|
||
cornerSize: 10, // 选中时,角的大小为20
|
||
// lockRotation:true,
|
||
// lockScalingX:true,
|
||
lockRotation: true,
|
||
transparentCorners: false, // 选中时,角是被填充了。true 空心;false 实心
|
||
// cornerColor: "#a1de93", // 选中时,角的颜色是 青色
|
||
});
|
||
}
|
||
|
||
//设置导出
|
||
let setExport = async () => {
|
||
var imageDataURL = canvas.toDataURL({
|
||
format: "png", // 导出格式为 PNG
|
||
quality: 1, // 图片质量为 1(最高质量)
|
||
});
|
||
let a = document.createElement("a");
|
||
let img = [];
|
||
let index = 0;
|
||
img.push({
|
||
imgUrl: imageDataURL,
|
||
name: "collection.png",
|
||
});
|
||
let num = 0;
|
||
for (let key in allBoardData.value) {
|
||
if (key !== "colorBoards" && key !== "moodTemplateId") {
|
||
for (let item of allBoardData.value[key]) {
|
||
if (
|
||
key == "disposeMoodboard" &&
|
||
allBoardData.value[key][0] == undefined
|
||
) {
|
||
break;
|
||
}
|
||
|
||
let nameTail = item?.imgUrl
|
||
?.split(".")
|
||
.pop()
|
||
.split("?")
|
||
.shift();
|
||
|
||
let data = {
|
||
imgUrl: item.imgUrl,
|
||
name: item?.resData?.name + index + "." + nameTail,
|
||
};
|
||
if (key == "likeDesignCollectionList") {
|
||
data.imgUrl = item.designOutfitUrl;
|
||
data.name = "result" + index + "." + nameTail;
|
||
}
|
||
img.push(data);
|
||
index++;
|
||
}
|
||
num++;
|
||
}
|
||
}
|
||
let dataList = [];
|
||
likeDesignCollectionList.value.forEach((item) => {
|
||
dataList.push(item.designItemId);
|
||
index++;
|
||
});
|
||
let mannequinList = [];
|
||
await Https.axiosPost(Https.httpUrls.designGetModel, dataList)
|
||
.then((rv) => {
|
||
mannequinList = rv;
|
||
})
|
||
.catch((rv) => {});
|
||
mannequinList.forEach((item) => {
|
||
let nameTail = item?.split(".").pop().split("?").shift();
|
||
let data = {
|
||
imgUrl: item,
|
||
name: "mannequin" + index + "." + nameTail,
|
||
};
|
||
img.push(data);
|
||
index++;
|
||
});
|
||
downImg(img);
|
||
};
|
||
let getImgArrayBuffer = (url) => {
|
||
return new Promise((resolve, reject) => {
|
||
//通过请求获取文件blob格式
|
||
let xmlhttp = new XMLHttpRequest();
|
||
xmlhttp.open("GET", url, true);
|
||
xmlhttp.responseType = "blob";
|
||
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(() => {
|
||
zip.generateAsync({ type: "blob" }).then((content) => {
|
||
// 生成二进制流
|
||
FileSaver.saveAs(content, "DesignFiles"); // 利用file-saver保存文件 自定义文件名
|
||
isShowMark = false;
|
||
});
|
||
})
|
||
.catch((res) => {
|
||
// message.warning(t('HomeView.jsContent3'));
|
||
isShowMark = false;
|
||
});
|
||
};
|
||
//关闭画布
|
||
let cancelDsign = () => {
|
||
showUpgradePlan.value = false;
|
||
position = {
|
||
//设置每个图形位置的初始值
|
||
x: 0,
|
||
y: 0,
|
||
height: 0,
|
||
};
|
||
|
||
};
|
||
//设置画布宽高
|
||
let setMaxInput = (str, maxNum) => {
|
||
if (str == "width") {
|
||
// maxNum = window.innerWidth < 1100 ? 400 : maxNum;
|
||
maxNum = [window.innerWidth/2.4]
|
||
maxNum = maxNum.map(num => Math.round(num / 10) * 10)[0];
|
||
}else if(str == 'height'){
|
||
if(position.y+position.height>maxNum){
|
||
maxNum = Math.floor(position.y+position.height)
|
||
}
|
||
}
|
||
if (str == "width" && canvasWH.value.width >= maxNum) {
|
||
canvasWH.value.width = maxNum;
|
||
} else if (str == "height" && canvasWH.value.height >= maxNum) {
|
||
canvasWH.value.height = maxNum;
|
||
}
|
||
canvas.setHeight(canvasWH.value.height);
|
||
canvas.setWidth(canvasWH.value.width);
|
||
};
|
||
|
||
let closeNav = ref(0)
|
||
let setCloseNav = (num)=>{
|
||
if(closeNav.value == num){
|
||
closeNav.value = -1
|
||
}else{
|
||
closeNav.value = num
|
||
}
|
||
}
|
||
// let multiselect = ()=>{
|
||
// console.log(canvas);
|
||
// multiselectJS(canvas)
|
||
// }
|
||
function multiselect() {//获取整体宽高
|
||
canvas.discardActiveObject() // 丢弃当前活动的对象和触发事件。 如果fabric作为鼠标事件的结果调用该函数,则将该事件作为参数传递给自定义事件的fire函数。 当作为一个方法使用时,参数没有任何应用。
|
||
const sel = new fabric.ActiveSelection(canvas.getObjects(), {
|
||
canvas
|
||
})
|
||
// console.log(sel)
|
||
canvas.setActiveObject(sel)
|
||
canvas.requestRenderAll()
|
||
const activeObject = canvas.getActiveObject(); // 获取当前选中的整体对象
|
||
if (activeObject && activeObject.type === 'activeSelection') {
|
||
const totalWidth = activeObject.width * activeObject.scaleX;
|
||
const totalHeight = activeObject.height * activeObject.scaleY;
|
||
console.log('Total Width:', totalWidth);
|
||
console.log('Total Height:', totalHeight);
|
||
}
|
||
|
||
}
|
||
let currentType = ref({
|
||
type:'',
|
||
data:'',
|
||
})
|
||
let onDragstart = (type,imgItem)=>{
|
||
currentType.value.type = type
|
||
currentType.value.data = imgItem
|
||
}
|
||
let canvasOnDrop = ()=>{
|
||
canvas.on('drop', (opt)=> {
|
||
// 省略部分代码......
|
||
let offset = {
|
||
left: canvas.getSelectionElement().getBoundingClientRect().left,
|
||
top: canvas.getSelectionElement().getBoundingClientRect().top
|
||
}
|
||
let point = {
|
||
x: opt.e.x - offset.left,
|
||
y: opt.e.y - offset.top,
|
||
}
|
||
let pointerVpt = canvas.restorePointerVpt(point)
|
||
switch (currentType.value.type) {
|
||
case 'colorBoards':
|
||
let rect = setGroup(currentType.value.data)
|
||
setCanvasColor(pointerVpt.y, pointerVpt.x,rect)
|
||
break
|
||
case 'moodboardFiles':
|
||
createRect(pointerVpt.y, pointerVpt.x,currentType.value.type)
|
||
break
|
||
default :
|
||
createRect(pointerVpt.y, pointerVpt.x,currentType.value.type)
|
||
break
|
||
}
|
||
// 创建完元素,把当前操作的元素类型设置回 null
|
||
currentType.value.type = null
|
||
currentType.value.data = null
|
||
})
|
||
}
|
||
let setGroup = (data)=>{
|
||
var text = new fabric.Text(data.tcx,{
|
||
left: 0,
|
||
top: 60,
|
||
fontSize: 14,
|
||
fontFamily: "Arial",
|
||
textAlign: "left",
|
||
fill: "black",
|
||
});
|
||
let text1 = new fabric.Text(data.name,{
|
||
left: 0,
|
||
top: 80,
|
||
width: 20,
|
||
fontSize: 14,
|
||
fontFamily: "Arial",
|
||
textAlign: "left",
|
||
});
|
||
let width = 110 > text1.width ? 110 : text1.width;
|
||
var color = new fabric.Rect({
|
||
width: width,
|
||
height: 60,
|
||
textAlign: "left",
|
||
fill: `rgb(${data.rgbValue.r},${data.rgbValue.g},${data.rgbValue.b})`,
|
||
});
|
||
let rect = {text,text1,color,width}
|
||
return rect
|
||
}
|
||
let setCanvasColor = (top,left,rect)=>{
|
||
var group = new fabric.Group([rect.color, rect.text, rect.text1],{
|
||
left,
|
||
top,
|
||
width: rect.width,
|
||
fill: "rgb(255,255,255)",
|
||
cornerSize: 10, // 选中时,角的大小为20
|
||
transparentCorners: false, // 选中时,角是被填充了。true 空心;false 实心
|
||
stroke: "#212121",
|
||
strokeWidth: 1,
|
||
});
|
||
// 将矩形对象添加到 canvas 中
|
||
|
||
canvas.add(group);
|
||
return group
|
||
}
|
||
// 创建矩形
|
||
let createRect = (top, left,key)=> {
|
||
let itemCanvasImg = currentType.value.data.imgUrl
|
||
if(key == 'likeDesignCollectionList'){
|
||
itemCanvasImg = currentType.value.data.designOutfitUrl;
|
||
}
|
||
fabric.Image.fromURL(itemCanvasImg,(img) => {
|
||
setCanvasImage(img,key,left,top)//设置图片
|
||
canvas.add(img);
|
||
},{ crossOrigin: "Anonymous" });
|
||
}
|
||
//撤回
|
||
let historyState = (index)=> {
|
||
if(index<=0){
|
||
index = 0
|
||
}else if (index >canvasState.value.length){
|
||
index = canvasState.value.length-1
|
||
}
|
||
isLoadCanvas = true;
|
||
canvas.loadFromJSON(canvasState.value[index], () => {
|
||
canvas.forEachObject(function(obj) {
|
||
obj.cornerSize = 10
|
||
obj.transparentCorners=false
|
||
});
|
||
canvas.renderAll();
|
||
stateIndex.value = index;
|
||
});
|
||
}
|
||
onMounted(() => {});
|
||
|
||
return {
|
||
showUpgradePlan,
|
||
canvasWH,
|
||
init,
|
||
setExport,
|
||
cancelDsign,
|
||
setMaxInput,
|
||
isShowMark,
|
||
allBoardData,
|
||
closeNav,
|
||
setCloseNav,
|
||
multiselect,
|
||
onDragstart,
|
||
historyState,
|
||
stateIndex,
|
||
};
|
||
},
|
||
data(prop) {
|
||
return {};
|
||
},
|
||
|
||
mounted() {},
|
||
watch: {
|
||
// driver__:{
|
||
// handler(newVal,oldVal){
|
||
// if(this.type_.type2 == 'Printboard'){
|
||
// if(newVal.index >= 14 && newVal.index < 15){
|
||
// this.setKeyword(newVal.index-14)
|
||
// }else{
|
||
// }
|
||
// }else if(this.type_.type2 == 'Sketchboard'){
|
||
// }
|
||
// }
|
||
// },
|
||
},
|
||
methods: {
|
||
|
||
},
|
||
});
|
||
</script>
|
||
<style lang="less" scoped>
|
||
.Export {
|
||
flex: 1;
|
||
// height: 30rem;
|
||
// overflow-x: hidden;
|
||
display: flex;
|
||
flex-direction: column;
|
||
border-right: 1px solid #e5e5e5;
|
||
position: relative;
|
||
.UpgradePlan_content {
|
||
font-size: var(--aida-fsize2);
|
||
font-weight: 900;
|
||
color: rgba(0, 0, 0, 0.65);
|
||
}
|
||
.UpgradePlan_closeIcon {
|
||
top: calc(2rem * 1.2);
|
||
right: calc(2rem * 1.2);
|
||
cursor: pointer;
|
||
width: calc(4rem * 1.2);
|
||
height: calc(4rem * 1.2);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
position: absolute;
|
||
.fi-rr-cross-small::before {
|
||
padding: calc(0.2rem * 1.2);
|
||
border-radius: 5px;
|
||
border: solid 2px rgba(0, 0, 0, 0.25);
|
||
transition: 1s all;
|
||
color: rgba(0, 0, 0, 0.55);
|
||
}
|
||
&.UpgradePlan_closeIcon:hover .fi-rr-cross-small::before {
|
||
border: solid 2px rgba(0, 0, 0, 0.55);
|
||
color: rgba(0, 0, 0, 1);
|
||
}
|
||
}
|
||
.exportCanvasBox {
|
||
flex: 1;
|
||
overflow-x: hidden;
|
||
display: flex;
|
||
margin-top: 2rem;
|
||
justify-content: space-between;
|
||
.exportCanvasBox_title {
|
||
margin-bottom: .5rem;
|
||
font-size: 1.8rem;
|
||
font-weight: 600;
|
||
margin-top: 2rem;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
padding-right: 2rem;
|
||
cursor: pointer;
|
||
.icon{
|
||
transition: all .3s;
|
||
}
|
||
.icon-rotate{
|
||
transform: rotate(-180deg);
|
||
}
|
||
}
|
||
.exportCanvasBox_intro{
|
||
margin-bottom: 1rem;
|
||
font-size: 1.6rem;
|
||
font-weight: 600;
|
||
width: 100%;
|
||
}
|
||
.exportCanvasBox_right,
|
||
.exportCanvasBox_left {
|
||
width: 25rem;
|
||
height: 100%;
|
||
overflow-x: hidden;
|
||
label {
|
||
cursor: pointer;
|
||
display: flex;
|
||
align-items: center;
|
||
margin-bottom: 1rem;
|
||
div {
|
||
width: 5rem;
|
||
}
|
||
input {
|
||
width: 10em;
|
||
}
|
||
}
|
||
.exportCanvasBox_img.closeNav{
|
||
max-height: 1000rem;
|
||
}
|
||
}
|
||
.exportCanvasBox_left::-webkit-scrollbar,
|
||
.exportCanvasBox_right::-webkit-scrollbar{display: none;}
|
||
.exportCanvasBox_left {
|
||
|
||
.exportCanvasBox_img {
|
||
transition: all .3s;
|
||
overflow: hidden;
|
||
// height: auto;
|
||
max-height: 0;
|
||
transform: translate3d(0, 0, 0);
|
||
|
||
.exportCanvasBox_allItem {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
.exportCanvasBox_item {
|
||
text-align: center;
|
||
img {
|
||
max-width: 7rem;
|
||
max-height: 7rem;
|
||
object-fit: contain;
|
||
margin-right: 2rem;
|
||
margin-bottom: 2rem;
|
||
}
|
||
}
|
||
.exportCanvasBox_item_color{
|
||
width: 8rem;
|
||
margin-right: 2rem;
|
||
margin-bottom: 2rem;
|
||
.exportCanvasBox_item_BGcolor{
|
||
height: 5rem;
|
||
}
|
||
div{
|
||
// -webkit-user-select:none; /* Safari */
|
||
// -moz-user-select:none; /* Firefox */
|
||
// -ms-user-select:none; /* IE10+/Edge */
|
||
// user-select:none; /* Standard syntax */
|
||
}
|
||
}
|
||
.exportCanvasBox_item_dispose{
|
||
img{
|
||
max-width: 100%;
|
||
max-height: 100%;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
.exportCanvasBox_right{
|
||
display: flex;
|
||
flex-direction: column;
|
||
position: relative;
|
||
.exportCanvasBox_right_definition{
|
||
// display: flex;
|
||
flex: 1;
|
||
}
|
||
.exportCanvasBox_right_btn{
|
||
display: flex;
|
||
justify-content: space-between;
|
||
.subitOkPreviewBtn{
|
||
position: initial;
|
||
transform: none;
|
||
}
|
||
}
|
||
}
|
||
.exportCanvasBox_center {
|
||
height: 100%;
|
||
overflow-x: hidden;
|
||
}
|
||
.export_new_collection_review {
|
||
position: initial;
|
||
margin: 10rem auto;
|
||
margin-bottom: 0;
|
||
}
|
||
}
|
||
}
|
||
</style>
|
||
<style lang="less">
|
||
.Export {
|
||
.ant-modal-content {
|
||
border-radius: calc(1rem * 1.2);
|
||
overflow: hidden;
|
||
.ant-modal-header {
|
||
background-color: #fff;
|
||
border-bottom: none;
|
||
}
|
||
.ant-modal-body {
|
||
display: flex;
|
||
flex-direction: column;
|
||
padding: calc(5rem * 1.2) calc(5rem * 1.2) !important;
|
||
// height: calc(65vh - 6.4rem);
|
||
height: calc(65rem * 1.2);
|
||
background: #f9fafb;
|
||
}
|
||
//进度完成字体颜色
|
||
.ant-progress-circle.ant-progress-status-success .ant-progress-text {
|
||
color: #000;
|
||
}
|
||
.ant-progress-circle .ant-progress-text {
|
||
color: rgba(0, 0, 0, 0.55);
|
||
font-size: calc(1.6rem * 1.2);
|
||
}
|
||
}
|
||
}
|
||
</style> |