2925 lines
93 KiB
Vue
2925 lines
93 KiB
Vue
<template>
|
||
<div ref="ExportModal">
|
||
<a-modal
|
||
class="modal_component Export generalModel"
|
||
v-model:visible="showUpgradePlan"
|
||
:footer="null"
|
||
:get-container="() => $refs.ExportModal"
|
||
width="78%"
|
||
:maskClosable="false"
|
||
:centered="true"
|
||
:closable="false"
|
||
:keyboard="false"
|
||
:destroyOnClose="true"
|
||
>
|
||
<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">
|
||
<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="white"/>
|
||
<rect x="34.6274" y="32.5059" width="3" height="29" rx="1.5" transform="rotate(135 34.6274 32.5059)" fill="white"/>
|
||
</svg>
|
||
|
||
</div>
|
||
</div>
|
||
<div class="UpgradePlan_content">
|
||
<div>{{ $t('exportModel.EditExport') }}</div>
|
||
</div>
|
||
<!-- <div>
|
||
<canvas ref="exportCanvas"></canvas>
|
||
</div> -->
|
||
<div class="exportCanvasBox">
|
||
<div class="exportCanvasBox_left">
|
||
<!-- <div class="exportCanvasBox_title">{{ $t('exportModel.CanvasSize') }}</div> -->
|
||
|
||
<!-- <label style="width: 10%">
|
||
<div>Width:</div>
|
||
<input type="number" @input="setMaxInput('width', 1000)" v-model="canvasWH.width"/>
|
||
</label> -->
|
||
<label style="width: 10%">
|
||
<div>{{ $t('exportModel.Height') }}:</div>
|
||
<input type="number" @input="setMaxInput('height', 30000)" v-model="canvasWH.height" style="max-width: 50%"/>
|
||
</label>
|
||
<div class="exportCanvasBox_title" @click.stop="setCloseNav('nav')">
|
||
{{ $t('exportModel.CanvasNav') }}
|
||
<div
|
||
:class="[
|
||
'icon',
|
||
'iconfont',
|
||
'icon-xiala',
|
||
closeNav.nav?'icon-rotate':''
|
||
]"
|
||
>
|
||
</div>
|
||
<div class="exportCanvasBox_imgbor exportCanvasBox_left_item" :class="{'closeNav':closeNav.nav}">
|
||
<div
|
||
class="exportCanvasBox_allItem"
|
||
v-for="(item,key) in allBoardData"
|
||
>
|
||
<div v-if="item[0] && key == 'disposeMoodboard'" class="exportCanvasBox_intro">Entirety Moodboard</div>
|
||
<div v-if="item[0] && key == 'printboardFiles'" class="exportCanvasBox_intro">Printboard</div>
|
||
<div v-if="item[0] && key == 'moodboardFiles'" class="exportCanvasBox_intro">Moodboard</div>
|
||
<div v-if="item[0] && key == 'colorBoards'" class="exportCanvasBox_intro">Color</div>
|
||
<div v-if="item[0] && key == 'sketchboardFiles'" class="exportCanvasBox_intro">Sketch</div>
|
||
<div v-if="item[0] && key == 'likeDesignCollectionList'" class="exportCanvasBox_intro">Selected Design</div>
|
||
<div v-if="item[0] && key == 'FinalizeImage'" class="exportCanvasBox_intro">Selected Product</div>
|
||
<div v-if="key == 'colorBoards'" class="exportCanvasBox_item_colorBor">
|
||
<div v-for="colorItem in item" class="exportCanvasBox_item_color" :class="{active:colorItem.upScaleChecked}" draggable="true" @dragstart="onDragstart(key,colorItem)" @click.stop="isMoible?setDragstart(key,colorItem):''">
|
||
<div class="color_content" v-if="colorItem.gradient" :style="{height:'10rem','background-image':colorItem?.gradient?`linear-gradient(${colorItem?.gradient.angle}deg,${setGradient(colorItem?.gradient)}`:'none'}"></div>
|
||
<div v-else>
|
||
<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>
|
||
</div>
|
||
<div
|
||
v-if="key != 'moodboardPosition' && key != 'colorBoards'"
|
||
class="exportCanvasBox_item"
|
||
v-for="imgItem in item"
|
||
:class="[key == 'disposeMoodboard'?'exportCanvasBox_item_dispose':'',imgItem?.upScaleChecked?'active':'']"
|
||
draggable
|
||
@dragstart="onDragstart(key,imgItem)"
|
||
@click.stop="isMoible?setDragstart(key,imgItem):''"
|
||
>
|
||
<div class="exportCanvasBox_img">
|
||
<img :src="key == 'likeDesignCollectionList'?imgItem?.designOutfitUrl:imgItem?.imgUrl" alt="" />
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="exportCanvasBox_operation_bor_item exportCanvasBox_left_tool_item_column">
|
||
<div class="label_item" v-show="operation != 'move' && operation != 'eraser' && operation != 'texture'">
|
||
<div >{{ $t('exportModel.Color') }}</div>
|
||
<input type="color" @input="setPencilColor" v-model="canvasPencilColor">
|
||
<div class="labelHover_show exportCanvasBox_imgbor">
|
||
<div v-for="item in colorHistoryList" :style="{'background':item}" @click="setColorHistory(item)"></div>
|
||
</div>
|
||
</div>
|
||
<div class="label_item" v-show="operation != 'move'">
|
||
<div >{{ $t('exportModel.Size') }}:</div>
|
||
<input @change="setFontFamily" type="range" @input="setPencilWidth" min="3" max="50" v-model="canvasPencilWidth[operation]">
|
||
</div>
|
||
<div class="label_item" v-show="operation == 'pencil'">
|
||
<div >{{ $t('exportModel.Brushwork') }}:</div>
|
||
<a-select ref="select" class="label_select" size="small" v-model:value="brushworkValue"
|
||
style="flex: 1"
|
||
@change="brushworkChange"
|
||
>
|
||
<a-select-option class="label_select_item" v-for="item in brushList" :value="item.value">
|
||
<img :src="item.url" alt="">
|
||
</a-select-option>
|
||
</a-select>
|
||
</div>
|
||
<div class="label_item texture" v-show="operation == 'texture'">
|
||
<div >{{ $t('exportModel.Texture') }}:</div>
|
||
<a-select ref="select" class="label_select" size="small" v-model:value="textureValue"
|
||
style="flex: 1"
|
||
@change="textureValueChange"
|
||
>
|
||
<!-- v-model:value="brushwork" -->
|
||
<a-select-option class="label_select_item" v-for="item in textureList" :value="item.value">
|
||
<img :src="item.url" alt="">
|
||
</a-select-option>
|
||
</a-select>
|
||
</div>
|
||
<div class="label_item" v-show="operation != 'pencil' && operation != 'eraser'&&operation != 'move'&&operation != 'text'&&operation != 'texture'&&operation != ''">
|
||
<div >{{ $t('exportModel.FillBack') }}:</div>
|
||
<div class="exportCanvasBox_left_tool_item leftAlign">
|
||
<i class="icon iconfont icon-tuceng1" @click="setOperationMode('fill')" :class="{active:operationMode == 'fill'}"></i>
|
||
<i class="icon iconfont icon-tuceng" @click="setOperationMode('border')" :class="{active:operationMode == 'border'}"></i>
|
||
</div>
|
||
</div>
|
||
<div class="label_item" v-show="operation === 'move'">
|
||
<div >{{ $t('exportModel.Layer') }}:</div>
|
||
<div class="exportCanvasBox_left_tool_item top">
|
||
<i class="icon iconfont icon-shangyiceng" @click="setLayerIndex('Front')"></i>
|
||
<i class="icon iconfont icon-shangyiceng2" @click="setLayerIndex('Forward')"></i>
|
||
<i class="icon iconfont icon-xiayiceng" @click="setLayerIndex('Backwards')"></i>
|
||
<i class="icon iconfont icon-shangyiceng1" @click="setLayerIndex('Back')"></i>
|
||
</div>
|
||
</div>
|
||
<!-- <div class="label_item" v-show="allSelectWidth > -1 && operation != 'move'">
|
||
<div >{{ $t('exportModel.Width') }}</div>
|
||
<input type="number" @input="setAllSelectWidth" v-model="allSelectWidth">
|
||
</div> -->
|
||
<div class="label_item" v-show="(operation == '' || operation == 'text' || textDataShow) && operation != 'move'">
|
||
<div>Font Family</div>
|
||
<a-select ref="select" class="label_select" size="small" v-model:value="fontFamily"
|
||
style="flex: 1"
|
||
@change="setFontFamily"
|
||
>
|
||
<!-- v-model:value="brushwork" -->
|
||
<a-select-option class="label_select_item" v-for="item in textFontFamilyList" :style="{'font-family':item.value}" :value="item.value">
|
||
{{item.name}}
|
||
</a-select-option>
|
||
</a-select>
|
||
</div>
|
||
<!-- <label v-show="operation != 'move' && operation != 'eraser' && operation != 'texture'">
|
||
<div >{{ $t('exportModel.Height') }}</div>
|
||
<input type="number" @input="setPencilColor" v-model="canvasPencilColor">
|
||
</div> -->
|
||
</div>
|
||
<div class="shortcutKeys_box">
|
||
<div class="gallery_btn white" @click.stop="setCloseNav('shortcut')">
|
||
{{ $t('exportModel.ShortcutKeys') }}
|
||
<i class="icon iconfont icon-xiala" :class="closeNav.shortcut?'icon-rotate-tool':''" ></i>
|
||
</div>
|
||
<div class="shortcutKeys_list">
|
||
<div class="shortcutKeys_list_item" v-for="item in keysList" :key="item.name">
|
||
<div class="name">{{ item.name }}</div>
|
||
<div class="key">
|
||
<div v-if="!isWindow">{{ item.macKey }}</div>
|
||
<div v-else>{{ item.winDowKey }}</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- <div class="exportCanvasBox_title" @click.stop="setCloseNav('move')">
|
||
{{ $t('exportModel.More') }}
|
||
</div>
|
||
-->
|
||
</div>
|
||
<!-- <div @click="toSvg">12312312312</div> -->
|
||
<div class="exportCanvasBox_center_box exportCanvasBox_left">
|
||
<div class="exportCanvasBox_left_tool exportCanvasBox_title">
|
||
<div class="exportCanvasBox_left_tool_item">
|
||
<i class="icon iconfont icon-chehui" @click="historyState('')" :title="isWindow?'Ctrl+Z':'Command+Z'"></i>
|
||
<i class="icon iconfont icon-fanchehui" @click="historyState('reverse')" :title="isWindow?'Ctrl+Shift+Z':'Command+Ctrl+Z'"></i>
|
||
<i class="icon iconfont icon-move" @click="setOperation('move')" :class="{active:operation == 'move'}" :title="isWindow?'M':'M'"></i>
|
||
<i class="icon iconfont icon-bianji" @click="setOperation('pencil')" :class="{active:operation == 'pencil'}" :title="isWindow?'B':'B'"></i>
|
||
<i class="icon iconfont icon-xiangpi_huaban1" @click="setOperation('eraser')" :class="{active:operation == 'eraser'}" :title="isWindow?'E':'E'"></i>
|
||
<i class="icon iconfont icon-caizhi" @click="setOperation('texture')" :class="{active:operation == 'texture'}"></i>
|
||
|
||
<label class="uploadImage" :title="isWindow?'Ctrl+O':'Command+O'">
|
||
<i class="fi fi-br-upload" ></i>
|
||
<input type="file" @change="uploadImage" accept="image/*">
|
||
</label>
|
||
<i class="icon iconfont" @click="setOperation('text')" :class="{active:operation == 'text'}">T</i>
|
||
<i class="icon iconfont icon-IC-yehua" @click="setLiquefaction()"></i>
|
||
<!-- <i class="fi fi-rr-zoom-in" @click="setOperation('zoomIn')" :class="{active:operation == 'zoomIn'}"></i>
|
||
<i class="fi fi-rr-zoom-out" @click="setOperation('zoomOut')" :class="{active:operation == 'zoomOut'}"></i> -->
|
||
<i class="icon iconfont icon-xiala" :class="closeNav.tool?'icon-rotate-tool':''" @click.stop="setCloseNav('tool')"></i>
|
||
</div>
|
||
<div class="exportCanvasBox_left_tool exportCanvasBox_left_item" :class="{'closeNav' :closeNav.tool}">
|
||
<div class="exportCanvasBox_left_tool_item exportCanvasBox_left_tool_item_more">
|
||
<i class="icon iconfont icon-xian" @click="setOperation('fold')" :class="{active:operation == 'fold'}"></i>
|
||
<i class="icon iconfont icon-checkbox-full" @click="setOperation('rect')" :class="{active:operation == 'rect'}"></i>
|
||
<!-- <i class="icon iconfont icon-zhixian" @click="setOperation('line')" :class="{active:operation == 'line'}"></i> -->
|
||
<!-- <i class="icon iconfont icon-circle" @click="setOperation('circle')" :class="{active:operation == 'circle'}"></i> -->
|
||
<i class="icon iconfont icon-sanjiaoxing" @click="setOperation('triangle')" :class="{active:operation == 'triangle'}"></i>
|
||
<i class="icon iconfont icon-tx-fill-tuoyuanxing" @click="setOperation('ellipse')" :class="{active:operation == 'ellipse'}"></i>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="exportCanvasBox_center">
|
||
<div class="editFrontBack_pencilbtn" v-show="!isShowMark" :style="pencilbtnStyle"></div>
|
||
<!-- <div>
|
||
<div>
|
||
<div></div>
|
||
<span>16:9</span>
|
||
</div>
|
||
</div> -->
|
||
</div>
|
||
<div class="exportCanvasBox_scroll">
|
||
<div></div>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
<div class="exportCanvasBox_bottom">
|
||
|
||
<div class="exportCanvasBox_left_btn Guide_1_38">
|
||
<div class="exportCanvasBox_left_credits" v-show="credits<1">
|
||
<div><span class="icon iconfont icon-zhuyi"></span>{{ $t('exportModel.insufficient') }}</div>
|
||
</div>
|
||
<!-- <div class="subitOkPreviewBtn" :class="{active:allBoardData.printboardFiles.length<=0}" :title="allBoardData.printboardFiles.length<=0?$t('exportModel.jsContent2'):''" @click="setHDExport">{{ $t('exportModel.HDExport') }}</div> -->
|
||
<div class="subitOkPreviewBtn" @click="setSubmit">{{ $t('exportModel.Save') }}</div>
|
||
<div class="subitOkPreviewBtn" @click="setShare">{{ $t('exportModel.Share') }}</div>
|
||
<div class="subitOkPreviewBtn" @click="setExport">{{ $t('exportModel.Export') }}</div>
|
||
</div>
|
||
</div>
|
||
<!-- <div class="exportCanvasBox_right">
|
||
<div class="exportCanvasBox_title">
|
||
High-definition Download
|
||
</div>
|
||
<div class="exportCanvasBox_right_definition">
|
||
<label>
|
||
<div>Scale:</div>
|
||
<input type="number" @input="setMaxInput('scale', 500)" v-model="scaleSR"/>
|
||
</label>
|
||
</div>
|
||
<div class="" @click="multiselect">all</div>
|
||
<div class="exportCanvasBox_right_credits" v-show="credits<1">
|
||
<div><span class="icon iconfont icon-zhuyi"></span>Your points balance is insufficient, if you need to use this feature, please click the top left corner to recharge</div>
|
||
</div>
|
||
</div> -->
|
||
<!-- <div @click="toSvg()">2312312312</div> -->
|
||
|
||
<div class="mark_loading" v-show="isShowMark">
|
||
<a-spin size="large" />
|
||
</div>
|
||
</div>
|
||
<a-modal
|
||
v-model:visible="showSRExport"
|
||
class="modal_component SRExport generalModel"
|
||
width="48%"
|
||
:maskClosable="false"
|
||
:centered="true"
|
||
:closable="false"
|
||
:keyboard="false"
|
||
:footer="null"
|
||
:mask="false"
|
||
>
|
||
<div class="generalModel_btn">
|
||
<div class="generalModel_closeIcon" @click.stop="cancelDsign()">
|
||
<i class="fi fi-rr-cross-small"></i>
|
||
</div>
|
||
</div>
|
||
<div class="modal_title_text">
|
||
<div class="modal_title_text_max">{{ $t('exportModel.SR') }}</div>
|
||
<div class="modal_title_text_intro">{{ $t('exportModel.requiresCredits',{data:(allExportSR.filter(item=> item.checked ).length*5)}) }}</div>
|
||
</div>
|
||
<div class="SRExport_operate">
|
||
<div class="SRExport_operate_box">
|
||
<div>{{ $t('exportModel.Scale') }}:</div>
|
||
<!-- <input type="number" @input="setMaxInput('scale', 500)" v-model="scaleSR"/> -->
|
||
<!-- <a-select ref="select" class="SRExport_operate_sclae" size="small" v-model:value="scaleSR"
|
||
style="flex: 1"
|
||
@change="setScaleSR"
|
||
>
|
||
<a-select-option class="label_select_item" v-for="item in scaleSRList" :value="item.value">
|
||
</a-select-option>
|
||
</a-select> -->
|
||
<div class="SRExport_operate_item_sclae" :class="{active:scaleSR==2}" @click="setScaleSR(2)">2</div>
|
||
<div class="SRExport_operate_item_sclae" :class="{active:scaleSR==4}" @click="setScaleSR(4)">4</div>
|
||
<!-- <div class="SRExport_operate_item_sclae" :class="{active:scaleSR==8}" @click="setScaleSR(8)">8</div> -->
|
||
</div>
|
||
<div :class="['check_all_block',allChecked ? 'check_all' : '']" @click="selectAllImg()">
|
||
<div class="check_block"><div class="check_block_body"></div></div>
|
||
<div>all</div>
|
||
</div>
|
||
</div>
|
||
<div class="SRExport_img">
|
||
<div class="SRExport_img_item_box" v-for="item in allExportSR" @click="selectImg(item)">
|
||
<input type="checkbox" v-model="item.checked">
|
||
<img class="SRExport_img_item" :src="item.imgUrl" alt="">
|
||
</div>
|
||
</div>
|
||
<div class="generalModelOperate_endBtn">
|
||
<div class="generalModelOperate_btn_cancel" @click="cancelSRExport">{{ $t('exportModel.Cancel') }}</div>
|
||
<div class="generalModelOperate_btn_ok" :class="[credits < (allExportSR.filter(item=> item.checked ).length*5)?'active':'']" @click="setExportSR">OK</div>
|
||
</div>
|
||
</a-modal>
|
||
<publish ref="publish" @clearPublish="clearPublish"></publish>
|
||
<liquefaction ref="liquefaction" @submitLiquefaction="submitLiquefaction" @clearLiquefaction="clearLiquefaction"></liquefaction>
|
||
</a-modal>
|
||
</div>
|
||
</template>
|
||
<script>
|
||
import {defineComponent, computed, h, ref, nextTick, inject, reactive, onMounted,onBeforeUnmount
|
||
} from "vue";
|
||
import { Https } from "@/tool/https";
|
||
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
|
||
import scaleImage from "@/component/HomePage/scaleImage.vue";
|
||
import ExportNewCoolection from "@/component/HomePage/ExportNewCoolection.vue";
|
||
import { useStore } from "vuex";
|
||
import JSZip, { forEach } from "jszip";
|
||
// import fabric from 'fabric';
|
||
import { message, Modal } from "ant-design-vue";
|
||
import domTurnImg from '@/tool/domTurnImg'
|
||
import { openGuide,driverObj__ } from "@/tool/guide";
|
||
const FileSaver = require("file-saver");
|
||
import { exportSele,JSRectUpdata,JSchangeType,JScanvasMouseDown,JScanvasMouseMove,JScreateCheck,JSSetTexture,JSSetRemoveImage } from "@/tool/canvasDrawing";
|
||
import { useI18n } from "vue-i18n";
|
||
import {isMoible,calculateGradientCoordinate,base64ToFile} from '@/tool/util'
|
||
import publish from "@/component/WorksPage/publish.vue";
|
||
import liquefaction from "@/component/modules/liquefaction.vue";
|
||
import { getMousePosition } from "@/tool/mdEvent";
|
||
|
||
export default defineComponent({
|
||
components: {
|
||
scaleImage,
|
||
ExportNewCoolection,
|
||
publish,
|
||
liquefaction,
|
||
},
|
||
props: ["msg", "sketchCatecoryList",'setTask'],
|
||
setup(props,{emit}) {
|
||
const {t} = useI18n()
|
||
const store = useStore();
|
||
let driver__ = computed(()=>{
|
||
return store.state.Guide.guide
|
||
})
|
||
let isWindow = true
|
||
let showUpgradePlan = ref(false);
|
||
let canvas = ref({});
|
||
// let canvasDom = ref()
|
||
let canvasWH = ref({
|
||
width: 400,
|
||
height: 0,
|
||
});
|
||
let pencilbtnStyle = ref({
|
||
background:'',
|
||
width:0+'px',
|
||
height:0+'px',
|
||
display:'none',
|
||
left:0+'px',
|
||
top:0+'px',
|
||
})
|
||
let publish = ref()
|
||
// canvasWH.value.width = [window.innerWidth/2.4]
|
||
// canvasWH.value.width = canvasWH.value.width.map(num => Math.round(num / 100) * 100)[0];
|
||
let credits = computed(() => {
|
||
return store.state.UserHabit.credits.value;
|
||
});
|
||
|
||
let allBoardData = computed(() => {
|
||
return store.state.UploadFilesModule.allBoardData;
|
||
});
|
||
let likeDesignCollectionList = computed(() => {
|
||
return store.state.HomeStoreModule.likeDesignCollectionList;
|
||
});
|
||
let isShowMark = ref(false);
|
||
// let allImage = Object.assign(allBoardData.value,{likeDesignCollectionList:likeDesignCollectionList.value})
|
||
let position = {
|
||
//设置每个图形位置的初始值
|
||
x: 0,
|
||
y: 0,
|
||
height: 0,
|
||
};
|
||
let canvasScale = 1; //canvas放大缩小倍率
|
||
let sketchGrouping = 6; //sketch分组
|
||
let likeDesign = 4; //整体图分组
|
||
let disposeMoodboardShow = true;
|
||
let canvasState = ref()//存放canvas操作
|
||
let reverseCanvasState = ref([])//存放canvas操作
|
||
let normalCanvasState = ref([])//存放canvas操作
|
||
let isLoadCanvas = false//撤回或者反撤回false为撤回
|
||
let userlikeGroupId = 0
|
||
let imgWidth = {} //这是设置画布等宽
|
||
let submitCanvasContent = null
|
||
let contentKeyList = []
|
||
let init = (productData)=>{
|
||
userlikeGroupId = productData.userlikeGroupId
|
||
allBoardData.value[productData.key] = productData.imgList;
|
||
contentKeyList = [
|
||
"disposeMoodboard",
|
||
"moodboardFiles",
|
||
"printboardFiles",
|
||
"colorBoards",
|
||
"sketchboardFiles",
|
||
"likeDesignCollectionList",
|
||
productData.key,
|
||
];
|
||
const userAgent = navigator.userAgent.toLowerCase();
|
||
if (userAgent.indexOf('windows') !== -1) {
|
||
isWindow = true
|
||
}else if(userAgent.indexOf('macintosh') !== -1 || userAgent.indexOf('mac os') !== -1) {
|
||
isWindow = false
|
||
}
|
||
createCanvas()
|
||
}
|
||
let setCanvasData = async (oldExportCanvas)=>{
|
||
let oldKey = "";
|
||
let margin = 20; //每个图形边距
|
||
let maxHeight = 0
|
||
let sketchXy = {x:0,y:0}
|
||
|
||
contentKeyList.forEach((item)=>{
|
||
if(item !== 'likeDesignCollectionList')imgWidth[item] = setImageWidth(item)
|
||
})
|
||
|
||
// arr.forEach((item,index)=>{
|
||
if(oldExportCanvas){
|
||
canvasWH.value.height = oldExportCanvas.canvasHeight
|
||
canvas.setHeight(canvasWH.value.height);
|
||
canvas.loadFromJSON(oldExportCanvas, () => {});
|
||
isShowMark.value = false
|
||
}else{
|
||
canvasWH.value.height = 500
|
||
canvas.setHeight(canvasWH.value.height);
|
||
isShowMark.value = false
|
||
await nextTick(async ()=>{
|
||
for (const item of contentKeyList) {
|
||
for (const key in allBoardData.value) {
|
||
if (item == key) {
|
||
//循环渲染顺序
|
||
let sketchGroupingItem = [];
|
||
if (
|
||
item == "moodboardFiles" &&
|
||
!disposeMoodboardShow
|
||
) {
|
||
continue;
|
||
}
|
||
for (const [allItemIndex, allItem,] of allBoardData.value[key].entries()) {
|
||
await new Promise(async (resolve, reject) => {
|
||
if(!allItem){
|
||
resolve()
|
||
}
|
||
maxHeight = position.y + position.height>maxHeight?position.y +position.height:maxHeight
|
||
if (key == "colorBoards") {
|
||
let rect = setGroup(allItem)
|
||
if (position.x + rect.width > canvasWH.value.width || oldKey != key) {
|
||
position.x = 0;
|
||
position.y = maxHeight;
|
||
}
|
||
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) => {
|
||
if(item == 'likeDesignCollectionList')imgWidth[item] = setImageWidth(key,img);
|
||
let scaleWH = imgWidth[item] / img.width; //计算放到画布上缩小倍率
|
||
if(key == "sketchboardFiles"){
|
||
if(allItemIndex == 0){
|
||
position.x = 0;
|
||
position.y = maxHeight;
|
||
}
|
||
}else{
|
||
if (position.x + img.width * scaleWH > canvasWH.value.width || oldKey != key) {
|
||
position.x = 0;
|
||
position.y = maxHeight;
|
||
}
|
||
}
|
||
setCanvasImage(img,key,position.x,position.y,allItem)//设置图片
|
||
position.height = img.height * scaleWH + margin;
|
||
if (key == "sketchboardFiles") {
|
||
if (sketchGroupingItem.length <sketchGrouping+1) {
|
||
sketchGroupingItem.push(JSON.parse(JSON.stringify(position)));
|
||
}
|
||
if (sketchGroupingItem.length >sketchGrouping) {
|
||
let sketchXyIndex = {
|
||
maxIndex: 0,
|
||
maxNum: 0,
|
||
minNum: 999999,
|
||
minIndex: 0,
|
||
};
|
||
sketchGroupingItem.forEach(
|
||
(sketchItem,sketchIndex) => {
|
||
if (sketchItem.y + sketchItem.height < sketchXyIndex.minNum) {
|
||
sketchXyIndex.minNum = sketchItem.y + sketchItem.height
|
||
sketchXyIndex.minIndex = sketchIndex;
|
||
}
|
||
if (sketchItem.y + sketchItem.height > sketchXyIndex.maxNum) {
|
||
sketchXyIndex.maxNum = sketchItem.y + sketchItem.height
|
||
sketchXyIndex.maxIndex = sketchIndex;
|
||
}
|
||
}
|
||
);
|
||
sketchGroupingItem[sketchXyIndex.minIndex].y = sketchXyIndex.minNum
|
||
// sketchGroupingItem[sketchXyIndex.maxIndex].y = sketchXyIndex.maxNum
|
||
if (allBoardData.value[key].length == allItemIndex + 1) {
|
||
maxHeight = sketchXyIndex.maxNum
|
||
} else {
|
||
position = sketchGroupingItem[sketchXyIndex.minIndex];
|
||
}
|
||
|
||
}
|
||
}
|
||
if(key == "sketchboardFiles" && sketchGroupingItem.length >sketchGrouping){
|
||
}else{
|
||
position.x += img.width * scaleWH + margin;
|
||
}
|
||
img.lock_rotation = true;
|
||
oldKey = key;
|
||
resolve()
|
||
canvas.add(img);
|
||
|
||
},{ crossOrigin: "Anonymous" });
|
||
}
|
||
});
|
||
}
|
||
}
|
||
}
|
||
if(position.y+position.height>canvasWH.value.height){
|
||
canvasWH.value.height = Math.floor(position.y+position.height)
|
||
canvas.setHeight(canvasWH.value.height);
|
||
}
|
||
}
|
||
})
|
||
isShowMark.value = false
|
||
}
|
||
updateCanvasState('')//加载完成后记录一下
|
||
}
|
||
let createCanvas = (oldExportCanvas) => {
|
||
showUpgradePlan.value = true;
|
||
clearTimeout(submitCanvasContent)
|
||
setCanvasKeyDown()
|
||
// document.addEventListener("keydown", setCanvasKeyDown);
|
||
// document.addEventListener("keyup", clearCanvasKeyDown);
|
||
normalCanvasState.value = []
|
||
reverseCanvasState.value = []
|
||
allBoardData.value.likeDesignCollectionList =
|
||
likeDesignCollectionList;
|
||
nextTick().then(async () => {
|
||
let canvasBox = document.querySelector(".Export .exportCanvasBox_center");
|
||
canvasWH.value.width = canvasBox.offsetWidth - 10
|
||
let oldCanvasDom = canvasBox.querySelector('.canvas-container')
|
||
let oldCanvasDom1 = canvasBox.querySelector('canvas')
|
||
var canvasDom = document.createElement("canvas");
|
||
if(oldCanvasDom)oldCanvasDom.remove()
|
||
if(oldCanvasDom)loadingShow.value = false
|
||
if(oldCanvasDom1)oldCanvasDom1.remove()
|
||
|
||
canvasBox.appendChild(canvasDom);
|
||
canvas = new fabric.Canvas(canvasDom, {
|
||
backgroundColor: "rgba(255, 255, 255)",
|
||
width: canvasWH.value.width,
|
||
height: canvasWH.value.height,
|
||
isDrawingMode: false, // 开启绘图模式
|
||
selectionFullyContained: true,
|
||
selectionKey:'ctrlKey',
|
||
includeDefaultValues: false,//尚未测试 精简导出JSON
|
||
});
|
||
canvasOnDrop()//开启鼠标到画布事件
|
||
if(!fabric.Object.prototype.controls.deleteControl){//设置元素删除
|
||
JSSetRemoveImage(deleteObject)
|
||
}else{
|
||
fabric.Object.prototype.controls.deleteControl.mouseUpHandler = deleteObject
|
||
}
|
||
// setRemoveImage()//设置元素删除
|
||
canvas.on("object:modified", ()=>{
|
||
updateCanvasState()
|
||
});
|
||
canvas.preserveObjectStacking = true;
|
||
//鼠标移动
|
||
canvas.on("mouse:move", event =>setCanvasMove(event));
|
||
canvas.on("mouse:down", event=>setCanvasDown(event));
|
||
canvas.on("mouse:up", event=>setCanvasUp(event));
|
||
|
||
//双击
|
||
canvas.on("mouse:dblclick", event=>{
|
||
if(operation.value == 'fold'){
|
||
foldEnd('Enter')
|
||
}
|
||
});
|
||
// canvas.on('path:created', (event)=>{updateCanvasState()});
|
||
// canvas.on("selection:created", (event)=>{setZIndex(event)});
|
||
// canvas.on('object:removed', function() {
|
||
// });
|
||
// canvas.on("object:added", (obj)=>{
|
||
// obj.target.cornerSize = 10
|
||
// obj.target.transparentCorners = false
|
||
// });
|
||
initAligningGuidelines(canvas,true)
|
||
JSchangeType(canvas,'init')
|
||
pencilbtnStyle.value.background = '#fff'
|
||
fabric.Object.prototype.cornerSize = 10
|
||
fabric.Object.prototype.transparentCorners = false
|
||
// setCanvasOperation()//设置监听添加修改画布元素,用来做撤回功能
|
||
|
||
|
||
setOperation('move')
|
||
submitCanvasContent = setInterval(()=>{
|
||
let data = setCanvasContent(true)
|
||
if(data.objects.length == 0){
|
||
clearTimeout(submitCanvasContent)
|
||
return
|
||
}
|
||
data.canvasHeight = canvasWH.value.height
|
||
localStorage.setItem('canvasContent',JSON.stringify(data))
|
||
localStorage.setItem('userlikeGroupId',userlikeGroupId)
|
||
localStorage.setItem('currentTime',new Date().getTime())
|
||
},3000)
|
||
if(driver__.value.driver){
|
||
driverObj__.moveNext()
|
||
}
|
||
nextTick(async ()=>{
|
||
let oldExportCanvas
|
||
let localCanvas = localStorage.getItem('canvasContent')
|
||
let localUserlikeGroupId = localStorage.getItem('userlikeGroupId')
|
||
let currentTime = localStorage.getItem('currentTime')
|
||
oldExportCanvas = await new Promise((resolve, reject) => {
|
||
if(localUserlikeGroupId == userlikeGroupId && (new Date().getTime() - currentTime < 21600000)){
|
||
Modal.confirm({
|
||
title: useI18.t('exportModel.jsContent8'),
|
||
okText: 'Yes',
|
||
cancelText: 'No',
|
||
mask:false,
|
||
centered:true,
|
||
onOk() {
|
||
localCanvas = localCanvas?JSON.parse(localCanvas):null
|
||
resolve(localCanvas)
|
||
},
|
||
onCancel(){
|
||
resolve(null)
|
||
}
|
||
});
|
||
}else{
|
||
resolve(null)
|
||
}
|
||
})
|
||
if(!oldExportCanvas){
|
||
let data = {
|
||
userLikeGroupId:userlikeGroupId
|
||
}
|
||
oldExportCanvas = await new Promise((resolve, reject) => {
|
||
Https.axiosPost(Https.httpUrls.exportSearch, data)
|
||
.then((rv) => {
|
||
resolve(rv)
|
||
})
|
||
.catch((rv) => {
|
||
resolve(null)
|
||
});
|
||
})
|
||
}
|
||
setCanvasData(oldExportCanvas)
|
||
})
|
||
});
|
||
|
||
};
|
||
let deleteObject = ()=> {
|
||
// var target = [transform.target];
|
||
if(!canvas.getActiveObjects()){
|
||
return
|
||
}
|
||
let target = canvas.getActiveObjects()
|
||
|
||
target.forEach((item)=>{
|
||
// var canvas = item.canvas;
|
||
// canvas.remove(item);
|
||
canvas.fxRemove(item, {
|
||
onComplete(){
|
||
canvas.discardActiveObject(); // 丢弃当前选中的对象
|
||
canvas.renderAll(); // 重新渲染 Canvas
|
||
}
|
||
})
|
||
canvas.FX_DURATION = 300
|
||
})
|
||
// canvas.requestRenderAll();
|
||
// canvas.discardActiveObject() // 丢弃当前活动的对象和触发事件。 如果fabric作为鼠标事件的结果调用该函数,则将该事件作为参数传递给自定义事件的fire函数。 当作为一个方法使用时,参数没有任何应用。
|
||
// canvas.discardActiveObject(); // 丢弃当前选中的对象
|
||
// canvas.renderAll(); // 重新渲染 Canvas
|
||
updateCanvasState('remove')
|
||
}
|
||
|
||
|
||
let setImageWidth = (key,img)=>{
|
||
let imgWidth = canvasWH.value.width; //这是设置画布等宽
|
||
if (
|
||
disposeMoodboardShow &&
|
||
key == "disposeMoodboard" &&
|
||
allBoardData.value[key].length != 0 &&
|
||
allBoardData.value[key][0] != null
|
||
) {
|
||
//如果是mood 需要判断用户是否点击layout
|
||
disposeMoodboardShow = false;
|
||
|
||
imgWidth = canvasWH.value.width / 2;
|
||
}
|
||
if(key == 'upImgFiles'){
|
||
imgWidth = canvasWH.value.width / 8;
|
||
// imgWidth = canvasWH.value.width / 4;
|
||
}
|
||
if (key == "printboardFiles") {
|
||
imgWidth = canvasWH.value.width / 14;
|
||
// imgWidth = canvasWH.value.width / 8;
|
||
}
|
||
if (key == "sketchboardFiles"||key == 'moodboardFiles'||key == 'FinalizeImage') {
|
||
imgWidth =
|
||
(canvasWH.value.width -
|
||
(sketchGrouping - 1) * 20) /
|
||
sketchGrouping;
|
||
}
|
||
if (key == "likeDesignCollectionList") {
|
||
if(img){
|
||
let imgObj = JSON.parse(JSON.stringify(img))
|
||
let height = imgObj.height
|
||
imgObj.height = canvasWH.value.width / 8 * 1.8
|
||
let heightScale = imgObj.height / height
|
||
imgWidth = imgObj.width * heightScale
|
||
}
|
||
}
|
||
return imgWidth
|
||
}
|
||
let setCanvasImage = (img,key,left,top,data)=>{
|
||
// data
|
||
let imgId = 0
|
||
let minioUrl = ''//表示收藏或者generate
|
||
let imgUrl = data.imgUrl
|
||
if (key == "likeDesignCollectionList") {
|
||
imgUrl = data.designOutfitUrl;
|
||
imgWidth[key] = setImageWidth(key,img);
|
||
}
|
||
if(key == 'upImgFiles')imgWidth[key] = setImageWidth(key,img);
|
||
|
||
let url = imgUrl.split('?')[0]
|
||
var match = url.match(/:(\d+)\/(.*)/);
|
||
minioUrl = match[2]
|
||
// let id =
|
||
let proportion = img.height / img.width; //计算图形宽高比例
|
||
// let imgWidth = setImageWidth(key)
|
||
let scaleWH = imgWidth[key] / img.width; //计算放到画布上缩小倍率
|
||
img.set({
|
||
// width: imgWidth[key]/img.width,
|
||
// height: canvasWH.value.height/img.height,
|
||
left,
|
||
top,
|
||
imgId,
|
||
minioUrl,
|
||
scaleX:
|
||
imgWidth[key] / img.width,
|
||
scaleY:(img.width * proportion * scaleWH) / img.height,
|
||
// cornerSize: 10, // 选中时,角的大小为20
|
||
// transparentCorners: false, // 选中时,角是被填充了。true 空心;false 实心
|
||
lockRotation: true,
|
||
});
|
||
}
|
||
let setExportCanvas = async ()=>{
|
||
await calculateHeight()
|
||
canvas.setDimensions({ height: canvasWH.value.height });
|
||
canvas.renderAll();
|
||
return canvas.toDataURL({
|
||
format: "png", // 导出格式为 PNG
|
||
quality: 1, // 图片质量为 1(最高质量)
|
||
});
|
||
}
|
||
let calculateHeight = ()=>{
|
||
return new Promise((resolve, reject) =>{
|
||
var objects = canvas.getObjects();
|
||
var maxHeight = 0;
|
||
Modal.confirm({
|
||
title: useI18.t('exportModel.jsContent9'),
|
||
okText: 'Yes',
|
||
cancelText: 'No',
|
||
mask:false,
|
||
centered:true,
|
||
onOk() {
|
||
objects.forEach(function(obj) {
|
||
var objBottom = obj.top + obj.height*obj.scaleY;
|
||
if (objBottom > maxHeight) {
|
||
maxHeight = objBottom;
|
||
}
|
||
});
|
||
canvasWH.value.height = Math.round(maxHeight)+30
|
||
|
||
resolve(canvasWH.value.height)
|
||
},
|
||
onCancel(){
|
||
resolve(canvasWH.value.height)
|
||
}
|
||
});
|
||
})
|
||
}
|
||
//设置导出
|
||
let setExport = async () => {
|
||
initAligningGuidelines(canvas,false)
|
||
var imageDataURL = await setExportCanvas()
|
||
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") {
|
||
if(!(allBoardData.value[key] instanceof Array)) continue
|
||
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 + "." + data.imgUrl.split(".").pop().split("?").shift();
|
||
}
|
||
if (key == "FinalizeImage") {
|
||
data.imgUrl = item.url;
|
||
data.name = "Finalize" + index + "." + data.imgUrl.split(".").pop().split("?").shift();
|
||
}
|
||
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.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)
|
||
});
|
||
};
|
||
//关闭画布
|
||
let useI18 = useI18n()
|
||
let cancelDsign = () => {
|
||
Modal.confirm({
|
||
title: useI18.t('exportModel.jsContent1'),
|
||
okText: 'Yes',
|
||
cancelText: 'No',
|
||
mask:false,
|
||
centered:true,
|
||
onOk() {
|
||
showUpgradePlan.value = false;
|
||
canvas.dispose();
|
||
position = {
|
||
//设置每个图形位置的初始值
|
||
x: 0,
|
||
y: 0,
|
||
height: 0,
|
||
};
|
||
canvasWH.value.height = 0
|
||
operation.value = 'move'
|
||
operation.value = 'fill'
|
||
},
|
||
// onCancel(){
|
||
// _this.isShowMark.value = false
|
||
// resolve(false)
|
||
// }
|
||
});
|
||
};
|
||
//设置画布宽高
|
||
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;
|
||
}else if(str == 'scale'){
|
||
scaleSR.value = scaleSR.value < 1 ? 1:scaleSR.value>4? 4:scaleSR.value
|
||
}
|
||
canvas.setHeight(canvasWH.value.height);
|
||
canvas.setWidth(canvasWH.value.width);
|
||
};
|
||
|
||
let closeNav = ref({
|
||
nav:false,
|
||
tool:false,
|
||
shortcut:false,
|
||
})
|
||
let setCloseNav = (key)=>{
|
||
closeNav.value[key] = !closeNav.value[key]
|
||
// for (const iterator in closeNav.value) {
|
||
// if(key != iterator){
|
||
// closeNav.value[iterator] = false
|
||
// }
|
||
// }
|
||
}
|
||
function multiselect() {//获取整体宽高
|
||
canvas.discardActiveObject() // 丢弃当前活动的对象和触发事件。 如果fabric作为鼠标事件的结果调用该函数,则将该事件作为参数传递给自定义事件的fire函数。 当作为一个方法使用时,参数没有任何应用。
|
||
const sel = new fabric.ActiveSelection(canvas.getObjects(), {
|
||
canvas
|
||
})
|
||
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 present = {}
|
||
let setDragstart = (type,imgItem)=>{
|
||
currentType.value.type = type
|
||
present.upScaleChecked = false
|
||
present = {}
|
||
if(imgItem.upScaleChecked){
|
||
}else{
|
||
imgItem.upScaleChecked = true
|
||
present = imgItem
|
||
}
|
||
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':
|
||
createImage(pointerVpt.y, pointerVpt.x,currentType.value.type)
|
||
break
|
||
default :
|
||
createImage(pointerVpt.y, pointerVpt.x,currentType.value.type)
|
||
break
|
||
}
|
||
// 创建完元素,把当前操作的元素类型设置回 null
|
||
currentType.value.type = null
|
||
currentType.value.data = null
|
||
|
||
})
|
||
}
|
||
let setGroup = (data)=>{
|
||
let rect
|
||
if(data.gradient){
|
||
let colorStops = []
|
||
data.gradient.gradientList.forEach(item=>{
|
||
let obj = {
|
||
offset:item.left.split('%')[0]/100,
|
||
color:`rgba(${item.rgba.r},${item.rgba.g},${item.rgba.b},${item.rgba.a})`
|
||
}
|
||
colorStops.push(obj)
|
||
})
|
||
let { x0, y0, x1, y1 } = calculateGradientCoordinate(100,120,data.gradient.angle)
|
||
let linear = new fabric.Gradient({
|
||
type: 'linear', // 线性渐变
|
||
// coords: { x1: 0, y1: 0, x2: 200, y2: 0 }, // 渐变方向
|
||
coords: { x1:x0, y1:y0, x2:x1, y2:y1 }, // 渐变方向
|
||
colorStops: colorStops,
|
||
})
|
||
var color = new fabric.Rect({
|
||
top:0,
|
||
left:0,
|
||
width: 110,
|
||
height: 130,
|
||
textAlign: "left",
|
||
fill: linear // 设置渐变填充
|
||
// fill: `rgb(${data.rgbValue.r},${data.rgbValue.g},${data.rgbValue.b})`,
|
||
});
|
||
var text = new fabric.Text('',{
|
||
left: 0,
|
||
top: 0,
|
||
fontSize: 0,
|
||
fontFamily: "Arial",
|
||
textAlign: "left",
|
||
fill: "black",
|
||
});
|
||
let text1 = new fabric.Text('',{
|
||
left: 0,
|
||
top: 0,
|
||
width: 20,
|
||
fontSize: 0,
|
||
fontFamily: "Arial",
|
||
textAlign: "left",
|
||
});
|
||
rect = {text,text1,color,width:110}
|
||
}else{
|
||
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})`,
|
||
});
|
||
rect = {text,text1,color,width}
|
||
}
|
||
|
||
|
||
return rect
|
||
}
|
||
let setCanvasColor = (top,left,rect)=>{
|
||
let group
|
||
group = new fabric.Group([rect.color,rect.text,rect.text1],{
|
||
left,
|
||
top,
|
||
width: rect.width,
|
||
fill: "rgb(255,255,255)",
|
||
stroke: "#212121",
|
||
strokeWidth: 1,
|
||
});
|
||
canvas.add(group);
|
||
return group
|
||
}
|
||
// 创建矩形
|
||
let createImage = async (top, left,key)=> {
|
||
let itemCanvasImg = currentType.value.data.imgUrl
|
||
let data = JSON.parse(JSON.stringify(currentType.value.data))
|
||
if(key == 'likeDesignCollectionList'){
|
||
itemCanvasImg = currentType.value.data.designOutfitUrl;
|
||
}
|
||
await new Promise((resolve,reject)=>{
|
||
fabric.Image.fromURL(itemCanvasImg,(img) => {
|
||
setCanvasImage(img,key,left,top,data)//设置图片
|
||
canvas.add(img);
|
||
resolve()
|
||
},{ crossOrigin: "Anonymous" });
|
||
})
|
||
updateCanvasState()
|
||
}
|
||
//设置画布监听修改添加事件,用来做撤回功能
|
||
let updateCanvasState = (str) =>{
|
||
const canvasAsJson = JSON.stringify(canvas.toJSON());
|
||
if(str == 'loadingCompleted'){
|
||
// reverseCanvasState.value.push(canvasAsJson);
|
||
}
|
||
normalCanvasState.value.push(canvasAsJson);
|
||
if (isLoadCanvas) {
|
||
reverseCanvasState.value = []
|
||
isLoadCanvas = false;
|
||
canvasState.value = canvasAsJson
|
||
}
|
||
}
|
||
//撤回
|
||
let historyState = (str)=> {
|
||
if(str == 'reverse' && reverseCanvasState.value.length > 0){//反撤回
|
||
let obj = reverseCanvasState.value.pop()
|
||
// canvasState.value = reverseCanvasState.value[reverseCanvasState.value.length-1]
|
||
canvasState.value = obj
|
||
normalCanvasState.value.push(obj);
|
||
}else if(str == '' && normalCanvasState.value.length > 1){
|
||
let obj = normalCanvasState.value.pop()
|
||
canvasState.value = normalCanvasState.value[normalCanvasState.value.length-1]
|
||
reverseCanvasState.value.push(obj);
|
||
isLoadCanvas = true;
|
||
}else{
|
||
return
|
||
}
|
||
canvas.loadFromJSON(canvasState.value, () => {});
|
||
}
|
||
|
||
//在画布进行画画
|
||
let operation = ref('move')
|
||
let operationMode = ref('fill')
|
||
let textureValue = ref(0)//材质信息
|
||
|
||
let textureValueChange = (value)=>{
|
||
textureValue.value = value
|
||
setTexture()
|
||
}
|
||
//铅笔颜色 大小
|
||
let brushworkValue = ref('PencilBrush')
|
||
let brushworkChange = (value)=>{
|
||
brushworkValue.value = value
|
||
setPencil()
|
||
}
|
||
|
||
// let brushwork = ref('')
|
||
// 监听键盘的 keydown 和 keyup 事件
|
||
let keyDown = []
|
||
const keysList = [
|
||
{
|
||
name:useI18.t('exportModel.Painting'),
|
||
winDowKey:'B',
|
||
macKey:'B',
|
||
},{
|
||
name:useI18.t('exportModel.Eraser'),
|
||
winDowKey:'E',
|
||
macKey:'E',
|
||
},{
|
||
name:useI18.t('exportModel.Uncheck'),
|
||
winDowKey:'Ctrl + D',
|
||
macKey:'Command + D',
|
||
},{
|
||
name:useI18.t('exportModel.Revoke'),
|
||
winDowKey:'Ctrl + Z',
|
||
macKey:'Command + Z',
|
||
},{
|
||
name:useI18.t('exportModel.Retreat'),
|
||
winDowKey:'Ctrl + Shift + Z',
|
||
macKey:'Command + Ctrl + Z',
|
||
},{
|
||
name:useI18.t('exportModel.ReduceBrushSize'),
|
||
winDowKey:'[',
|
||
macKey:'[',
|
||
},{
|
||
name:useI18.t('exportModel.IncreaseBrushSize'),
|
||
winDowKey:']',
|
||
macKey:']',
|
||
},{
|
||
name:useI18.t('exportModel.DrinkingStraw'),
|
||
winDowKey:'I',
|
||
macKey:'I',
|
||
},{
|
||
name:useI18.t('exportModel.Copy'),
|
||
winDowKey:'Ctrl + C',
|
||
macKey:'Command + C',
|
||
},{
|
||
name:useI18.t('exportModel.Paste'),
|
||
winDowKey:'Ctrl + V',
|
||
macKey:'Command + V',
|
||
},{
|
||
name:useI18.t('exportModel.UploadOpenimage'),
|
||
winDowKey:'Ctrl + O',
|
||
macKey:'Command + O',
|
||
},
|
||
]
|
||
let canvasKeyDown = (event) => {
|
||
let keys = ['Enter','Delete','ControlLeft','KeyZ','ShiftLeft','KeyC','KeyV','BracketLeft','BracketRight','KeyI','KeyD','KeyO','KeyE','KeyB','MetaLeft']
|
||
if(keys.indexOf(event.code) > -1){
|
||
event.preventDefault();
|
||
}
|
||
if(keyDown.indexOf(event.code)>-1){
|
||
}else{
|
||
keyDown.push(event.code)
|
||
// console.log(keyDown.indexOf('ControlLeft') > -1 , keyDown.indexOf('MetaLeft') > -1, event.code == 'KeyC')
|
||
if(event.code === 'Enter' && operation.value == 'fold'){
|
||
foldEnd('Enter')
|
||
}else if(event.key === 'Delete'){
|
||
deleteObject()
|
||
}else if((keyDown.indexOf('ControlLeft') > -1 || keyDown.indexOf('MetaLeft') > -1) && event.code == 'KeyZ' && keyDown.indexOf('ShiftLeft') > -1){
|
||
historyState('reverse')
|
||
}else if((keyDown.indexOf('ControlLeft') > -1 || keyDown.indexOf('MetaLeft') > -1) && event.code == 'KeyZ'){
|
||
historyState('')
|
||
}else if((keyDown.indexOf('ControlLeft') > -1 || keyDown.indexOf('MetaLeft') > -1) && event.code == 'KeyC'){
|
||
copy()
|
||
}else if((keyDown.indexOf('ControlLeft') > -1 || keyDown.indexOf('MetaLeft') > -1) && event.code == 'KeyV'){
|
||
paste()
|
||
}else if(keyDown.indexOf('BracketLeft') > -1){
|
||
let width = canvasPencilWidth.value[operation.value]
|
||
canvasPencilWidth.value[operation.value] = (width - 5) < 3?3:(width - 5)
|
||
setPencilWidth()
|
||
}else if(keyDown.indexOf('BracketRight') > -1){
|
||
let width = canvasPencilWidth.value[operation.value]
|
||
canvasPencilWidth.value[operation.value] = (width + 5) > 50?50:(width + 5)
|
||
setPencilWidth()
|
||
}else if(keyDown.indexOf('KeyI') > -1){
|
||
getColor()//吸色
|
||
}else if(keyDown.indexOf('KeyM') > -1){
|
||
setOperation('move')
|
||
}else if((keyDown.indexOf('ControlLeft') > -1 || keyDown.indexOf('MetaLeft') > -1) && event.code == 'KeyD'){
|
||
canvas.discardActiveObject().renderAll();
|
||
}else if((keyDown.indexOf('ControlLeft') > -1 || keyDown.indexOf('MetaLeft') > -1) && event.code == 'KeyO'){
|
||
let input = document.querySelector('.uploadImage input')
|
||
input.click()
|
||
}else if(keyDown.indexOf('KeyB') > -1){
|
||
// if(operation.value == 'pencil' || operation.value == 'texture'){
|
||
setOperation('pencil')
|
||
// }
|
||
}else if(keyDown.indexOf('KeyE') > -1){
|
||
// if(operation.value == 'pencil' || operation.value == 'texture'){
|
||
setOperation('eraser')
|
||
// }
|
||
}
|
||
}
|
||
}
|
||
let getColor = 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);
|
||
canvasPencilColor.value = result.sRGBHex;
|
||
setPencilColor()
|
||
} catch (e) {
|
||
message.info(this.t('ColorboardUpload.jsContent1'))
|
||
}
|
||
}
|
||
let canvasKeyUp = (event) =>{
|
||
let keys = ['Enter','Delete','ControlLeft','KeyZ','ShiftLeft','KeyC','KeyV','BracketLeft','BracketRight','KeyI','KeyD','KeyO','KeyE','KeyB','MetaLeft']
|
||
if(keys.indexOf(event.code) > -1){
|
||
event.preventDefault();
|
||
}
|
||
keyDown = keyDown.filter(function(item) {
|
||
return event.code !== item;
|
||
})
|
||
}
|
||
let setCanvasKeyDown = (event)=>{
|
||
// let e = event || window.event
|
||
// e.stopPropagation();
|
||
document.addEventListener('keydown',canvasKeyDown);
|
||
document.addEventListener('keyup', canvasKeyUp);
|
||
}
|
||
let clearCanvasKeyDown = (pointer)=>{
|
||
// var pointer = canvas.getPointer(pointer);
|
||
if(!pointer?.target){
|
||
document.removeEventListener('keydown',canvasKeyDown);
|
||
document.removeEventListener('keyup', canvasKeyUp);
|
||
}
|
||
// var x = pointer.x;
|
||
// var y = pointer.y;
|
||
|
||
// 检查是否鼠标离开了画布
|
||
// if (x < 0 || x > canvas.width || y < 0 || y > canvas.height) {
|
||
// // 执行你的操作
|
||
// }
|
||
// if(!x || !y){
|
||
// document.removeEventListener('keydown',canvasKeyDown);
|
||
// document.removeEventListener('keyup', canvasKeyUp);
|
||
// }
|
||
}
|
||
let canvasPencilColor = ref('#000000')//画笔颜色
|
||
// let canvasPencilWidth = ref(20)//画笔大小
|
||
let canvasPencilWidth = ref({
|
||
|
||
})
|
||
let fontFamily = ref({})
|
||
let textFontFamilyList = ref([])
|
||
let allSelectWidth = ref(-1)//多选或单选的宽度
|
||
let allSelect = ref([])//多选或单选的宽度
|
||
let setOperation = (str)=>{
|
||
operation.value = str
|
||
//折线图的时候切换其他形状或者笔触需要把未完成的折线图删掉
|
||
canvas.discardActiveObject();//取消所有选中边框
|
||
if(createPatterningIs){
|
||
canvas.remove(currentPatterning)
|
||
}
|
||
removeSetText()
|
||
initAligningGuidelines(canvas,false)
|
||
canvas.remove(polyLineBtn)
|
||
if(str == 'pencil'){
|
||
setPencil()
|
||
pencilbtnStyle.value.display = `block`
|
||
}else if(str == 'move'){
|
||
JSchangeType(canvas,'init')
|
||
initAligningGuidelines(canvas,true)
|
||
setMove()
|
||
pencilbtnStyle.value.display = `none`
|
||
}else if(str == 'texture'){
|
||
setTexture()
|
||
pencilbtnStyle.value.display = `block`
|
||
}else if(str == 'eraser'){
|
||
setEraser()
|
||
pencilbtnStyle.value.display = `block`
|
||
}else if(str == 'text'){
|
||
setMove()
|
||
setText()
|
||
JSchangeType(canvas,'init')
|
||
pencilbtnStyle.value.display = `none`
|
||
}else if(str == 'zoomIn' || str == 'zoomOut'){
|
||
pencilbtnStyle.value.display = `none`
|
||
canvas.forEachObject((obj) =>obj.selectable = false);
|
||
}else if(str){
|
||
pencilbtnStyle.value.display = `none`
|
||
canvas.forEachObject((obj) =>obj.selectable = false);
|
||
canvas.isDrawingMode = false
|
||
}
|
||
setPencilWidth()
|
||
}
|
||
let _setAllSelectTime = null
|
||
let setAllSelectWidth = ()=>{
|
||
clearTimeout(_setAllSelectTime)
|
||
allSelect.value.forEach((item)=>{
|
||
// item.width = allSelectWidth.value
|
||
item.scaleX = allSelectWidth.value/item.width
|
||
item.scaleY = item.scaleX
|
||
item.setCoords()
|
||
})
|
||
_setAllSelectTime = setTimeout(() => {
|
||
updateCanvasState('')//加载完成后记录一下
|
||
}, 1500);
|
||
}
|
||
let _clipboard = null // 复制到的内容
|
||
let copy = () => {//复制
|
||
var activeObject = canvas.getActiveObject();
|
||
if(!activeObject){
|
||
return
|
||
}
|
||
activeObject.clone(function(cloned) {
|
||
_clipboard = cloned;
|
||
})
|
||
}
|
||
let paste = () => {//粘贴
|
||
if(!_clipboard){
|
||
return
|
||
}
|
||
_clipboard.clone(clonedObj => {
|
||
canvas.discardActiveObject() // 取消选择
|
||
|
||
// 设置新内容的坐标位置
|
||
clonedObj.set({
|
||
left: clonedObj.left + 10,
|
||
top: clonedObj.top + 10,
|
||
evented: true
|
||
})
|
||
|
||
if (clonedObj.type === 'activeSelection') {
|
||
// 活动选择需要一个对画布的引用
|
||
clonedObj.canvas = canvas;
|
||
clonedObj.forEachObject(function(obj) {
|
||
canvas.add(obj)
|
||
})
|
||
|
||
clonedObj.setCoords()
|
||
} else {
|
||
canvas.add(clonedObj)
|
||
}
|
||
_clipboard.top += 10
|
||
_clipboard.left += 10
|
||
canvas.setActiveObject(clonedObj)
|
||
canvas.requestRenderAll()
|
||
})
|
||
updateCanvasState()
|
||
}
|
||
let textureList = ref([])
|
||
for (let index = 0; index < 20; index++) {
|
||
textureList.value.push({value:index,url:`/image/texture/texture${index}.webp`})
|
||
}
|
||
let setTexture = async ()=>{
|
||
canvas.isDrawingMode = true//开启绘画模式
|
||
let img = await JSSetTexture(textureList.value[textureValue.value].url)
|
||
|
||
let patternBrush = new fabric.PatternBrush(canvas)
|
||
patternBrush.source = img
|
||
patternBrush.width = canvasPencilWidth.value[operation.value]?canvasPencilWidth.value[operation.value]:20; // 设置画笔大小
|
||
canvas.freeDrawingBrush = patternBrush
|
||
}
|
||
let setOperationMode = (str) =>{
|
||
operationMode.value = str
|
||
}
|
||
let uploadImage = (event)=>{
|
||
let input = document.querySelector('.uploadImage input')
|
||
const file = event.target.files[0];
|
||
setOperation('move')
|
||
if (file) {
|
||
const reader = new FileReader();
|
||
reader.onload = (e) => {
|
||
let file = base64ToFile(e.target.result,'upload')
|
||
let formData = new FormData();
|
||
formData.append("file", file);
|
||
let config = {headers:{'Content-Type':'multipart/form-data','Accept':'*/*' }}
|
||
Https.axiosPost(Https.httpUrls.canvasElementUpload, formData,config).then((rv)=>{
|
||
rv.imgUrl = rv.minioUrl
|
||
fabric.Image.fromURL(rv.minioUrl,(img) => {
|
||
console.log(canvas.wrapperEl.parentNode.scrollTop);
|
||
setCanvasImage(img,"upImgFiles",0,canvas.wrapperEl.parentNode.scrollTop,rv)
|
||
canvas.add(img);
|
||
},{ crossOrigin: "Anonymous" })
|
||
})
|
||
input.value = ''
|
||
};
|
||
reader.readAsDataURL(file);
|
||
}
|
||
}
|
||
let setLayerIndex = (str) =>{//设置优先级
|
||
var activeObject = canvas.getActiveObject();
|
||
switch (str) {
|
||
case 'Front':
|
||
canvas.bringToFront(activeObject)//顶层
|
||
break
|
||
case 'Back':
|
||
canvas.sendToBack(activeObject)//底层
|
||
break
|
||
case 'Forward':
|
||
canvas.bringForward(activeObject)
|
||
break
|
||
case 'Backwards':
|
||
canvas.sendBackwards(activeObject)
|
||
break
|
||
}
|
||
|
||
}
|
||
let hexToRgba=(hex, alpha)=> {
|
||
const r = parseInt(hex.slice(1, 3), 16);
|
||
const g = parseInt(hex.slice(3, 5), 16);
|
||
const b = parseInt(hex.slice(5, 7), 16);
|
||
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
|
||
}
|
||
let brushList = ref([
|
||
{
|
||
value:'PencilBrush',
|
||
url:'/image/brush/PencilBrush.jpg'
|
||
},{
|
||
value:'Marking',
|
||
url:'/image/brush/PencilBrush-2.jpg'
|
||
},{
|
||
value:'InkBrush',
|
||
url:'/image/brush/InkBrush.jpg'
|
||
},{
|
||
value:'CrayonBrush',
|
||
url:'/image/brush/CrayonBrush.jpg'
|
||
},{
|
||
value:'RibbonBrush',
|
||
url:'/image/brush/RibbonBrush.jpg'
|
||
},{
|
||
value:'MarkerBrush',
|
||
url:'/image/brush/MarkerBrush.jpg'
|
||
},{
|
||
value:'WritingBrush',
|
||
url:'/image/brush/WritingBrush.jpg'
|
||
},{
|
||
value:'LongfurBrush',
|
||
url:'/image/brush/LongfurBrush.jpg'
|
||
},{
|
||
value:'SpraypaintBrush',
|
||
url:'/image/brush/SpraypaintBrush.jpg'
|
||
},
|
||
])
|
||
let setPencil =()=>{
|
||
let pencil
|
||
canvas.isDrawingMode = true//开启绘画模式
|
||
if(brushworkValue.value == 'PencilBrush'){
|
||
pencil = new fabric.PencilBrush(canvas,{}); //普通笔
|
||
}else if(brushworkValue.value == 'Marking'){
|
||
pencil = new fabric.PencilBrush(canvas,); //记号笔
|
||
}else if(brushworkValue.value == 'InkBrush'){
|
||
pencil = new fabric.InkBrush(canvas,{}); //油画笔
|
||
}else if(brushworkValue.value=='CrayonBrush'){
|
||
pencil = new fabric.CrayonBrush(canvas,{}); //蜡笔
|
||
}else if(brushworkValue.value == 'RibbonBrush'){
|
||
pencil = new fabric.RibbonBrush(canvas,{width: 1,}); //色带
|
||
}else if(brushworkValue.value == 'MarkerBrush'){
|
||
pencil = new fabric.MarkerBrush(canvas,{}); //书写笔
|
||
// pencil = new fabric.PenBrush(canvas,{}); //书写笔
|
||
}else if(brushworkValue.value == 'WritingBrush'){
|
||
pencil = new fabric.WritingBrush(canvas,{}); //毛笔
|
||
}else if(brushworkValue.value == 'LongfurBrush'){
|
||
pencil = new fabric.LongfurBrush(canvas,{width: 1,}); //色带
|
||
}else if(brushworkValue.value == 'SpraypaintBrush'){
|
||
pencil = new fabric.SpraypaintBrush(canvas,{}); //长毛刷
|
||
}
|
||
|
||
canvas.freeDrawingBrush = pencil
|
||
canvas.freeDrawingBrush.width = canvasPencilWidth.value[operation.value]?canvasPencilWidth.value[operation.value]:20;
|
||
|
||
if(brushworkValue.value == 'RibbonBrush' || brushworkValue.value == 'LongfurBrush'){
|
||
canvas.freeDrawingBrush.width = 1;
|
||
}
|
||
if(brushworkValue.value == 'Marking'){
|
||
canvas.freeDrawingBrush.color = hexToRgba(canvasPencilColor.value,.5);
|
||
// }else if(brushworkValue.value == 'InkBrush'){
|
||
// canvas.freeDrawingBrush.color = hexToRgba(canvasPencilColor.value,.2);
|
||
}else{
|
||
canvas.freeDrawingBrush.color = hexToRgba(canvasPencilColor.value,1);
|
||
}
|
||
|
||
pencilbtnStyle.value.background = canvasPencilColor.value
|
||
canvas.freeDrawingBrush.isEraser = false
|
||
|
||
}
|
||
|
||
let setMove = () =>{
|
||
canvas.isDrawingMode = false
|
||
canvas.forEachObject((obj) =>obj.selectable = true);
|
||
}
|
||
let setEraser = ()=>{
|
||
canvas.isDrawingMode = true
|
||
let eraser = new fabric.EraserBrush(canvas)
|
||
canvas.freeDrawingBrush = eraser
|
||
pencilbtnStyle.value.background = '#fff'
|
||
canvas.requestRenderAll();
|
||
canvas.freeDrawingBrush.isEraser = true
|
||
canvas.freeDrawingBrush.width = canvasPencilWidth.value[operation.value]?canvasPencilWidth.value[operation.value]:20;
|
||
}
|
||
let createText = {}
|
||
let setTextFun = (e)=>{
|
||
if(operation.value != 'text'){
|
||
return
|
||
}
|
||
var clickedObject = e.target;
|
||
if (clickedObject instanceof fabric.Textbox) {
|
||
createText = clickedObject
|
||
}else{
|
||
var pointer = canvas.getPointer(e.pointer);
|
||
var x = pointer.x;
|
||
var y = pointer.y;
|
||
createText = new fabric.Textbox('', {
|
||
left: x,
|
||
top: y,
|
||
width: 150,
|
||
fontSize: canvasPencilWidth.value[operation.value]?canvasPencilWidth.value[operation.value]:20,
|
||
fontFamily:fontFamily.value,
|
||
fill:canvasPencilColor.value,
|
||
|
||
})
|
||
canvas.add(createText)
|
||
createText.enterEditing();
|
||
canvas.setActiveObject(createText).renderAll();
|
||
operation.value = ''
|
||
removeSetText()
|
||
}
|
||
|
||
}
|
||
let setText = ()=>{
|
||
canvas.on('mouse:down',setTextFun)
|
||
// if(isMoible()){
|
||
// canvas.on('mouse:down',setTextFun)
|
||
// }else{
|
||
// canvas.on('mouse:dblclick',setTextFun)
|
||
// }
|
||
}
|
||
let removeSetText = ()=>{
|
||
canvas.off('mouse:down',setTextFun)
|
||
// if(isMoible()){
|
||
// canvas.off('mouse:down',setTextFun)
|
||
// }else{
|
||
// canvas.off('mouse:dblclick',setTextFun)
|
||
// }
|
||
}
|
||
// let setTextStyle = (x,y)=>{
|
||
// var group = new fabric.Group([rect.color, rect.text, rect.text1],{
|
||
// left,
|
||
// top,
|
||
// width: rect.width,
|
||
// fill: "rgb(255,255,255)",
|
||
// stroke: "#212121",
|
||
// strokeWidth: 1,
|
||
// });
|
||
// canvas.add(group);
|
||
// }
|
||
|
||
|
||
let setTimeOut = {
|
||
color:null,
|
||
width:null,
|
||
colorHistory:null,
|
||
}//给切换颜色设置防抖
|
||
let colorHistoryList = ref(['rgb(0, 0, 0)'])
|
||
let setColorHistory = (value)=>{
|
||
canvasPencilColor.value = value
|
||
pencilColor()
|
||
}
|
||
let pencilColor = ()=>{
|
||
if(createText.set){
|
||
setFontFamily()
|
||
return
|
||
}
|
||
console.log(canvasPencilColor.value);
|
||
// brushIndicator.fill = canvasPencilColor.value;
|
||
if(canvas.freeDrawingBrush.isEraser){
|
||
}else{
|
||
pencilbtnStyle.value.background = canvasPencilColor.value
|
||
}
|
||
if(brushworkValue.value == 'Marking'){
|
||
canvas.freeDrawingBrush.color = hexToRgba(canvasPencilColor.value,.5);
|
||
}else if(brushworkValue.value == 'InkBrush'){
|
||
canvas.freeDrawingBrush.color = hexToRgba(canvasPencilColor.value,.2);
|
||
}else{
|
||
canvas.freeDrawingBrush.color = hexToRgba(canvasPencilColor.value,1);
|
||
}
|
||
}
|
||
let setPencilColor = ()=>{//切换颜色给铅笔设置颜色
|
||
clearTimeout(setTimeOut.color)
|
||
clearTimeout(setTimeOut.colorHistory)
|
||
setTimeOut.color = setTimeout(()=>{
|
||
pencilColor()
|
||
},200)
|
||
setTimeOut.colorHistory = setTimeout(()=>{
|
||
colorHistoryList.value.push(canvasPencilColor.value)
|
||
},1000)
|
||
}
|
||
let setPencilWidth = ()=>{//切换颜色给铅笔设置颜色
|
||
clearTimeout(setTimeOut.width)
|
||
canvasPencilWidth.value[operation.value] = Number(canvasPencilWidth.value[operation.value]?canvasPencilWidth.value[operation.value]:20)
|
||
setTimeOut.width = setTimeout(()=>{
|
||
if(brushworkValue.value == 'LongfurBrush' || brushworkValue.value == 'RibbonBrush'){
|
||
canvas.freeDrawingBrush.width = 1;
|
||
}else{
|
||
canvas.freeDrawingBrush.width = canvasPencilWidth.value[operation.value];
|
||
}
|
||
pencilbtnStyle.value.height = canvasPencilWidth.value[operation.value]+'px'
|
||
pencilbtnStyle.value.width = canvasPencilWidth.value[operation.value]+'px'
|
||
// setPencil()
|
||
},300)
|
||
}
|
||
let downPoint = null;//鼠标按下位置
|
||
let upPoint = null;//鼠标抬起位置
|
||
let currentPatterning = null//临时图形
|
||
let polyLineBtn = null
|
||
let createPatterningIs = false
|
||
let clearPatterning = () =>{
|
||
if(createPatterningIs){
|
||
canvas.remove(currentPatterning)
|
||
}
|
||
currentPatterning = null
|
||
canvas.remove(polyLineBtn)
|
||
updateCanvasState()
|
||
}
|
||
//设置再画布上移动
|
||
let setCanvasMove = (event)=>{
|
||
|
||
var pointer = canvas.getPointer(event.e);
|
||
if(canvas.isDrawingMode){
|
||
canvas.setCursor('none');
|
||
|
||
}else{
|
||
if(createPatterningIs){
|
||
JScanvasMouseMove(operation.value,event,currentPatterning,downPoint,keyDown)
|
||
}
|
||
}
|
||
let canvasBox = document.querySelector(".Export .canvas-container");
|
||
const rect = canvasBox.getBoundingClientRect();
|
||
const parentRect = canvasBox.parentElement.getBoundingClientRect();
|
||
let parentX = rect.left - parentRect.left
|
||
let parentY = rect.top - parentRect.top
|
||
pencilbtnStyle.value.left = parentX + pointer.x+'px'
|
||
pencilbtnStyle.value.top = parentY + canvasBox.parentElement.scrollTop + pointer.y+'px'
|
||
canvas.requestRenderAll()
|
||
}
|
||
let setCanvasZoom = (opt)=>{
|
||
console.log(123);
|
||
|
||
let zoom = canvas.getZoom() // 获取画布当前缩放值
|
||
let num = -100
|
||
if(operation.value == 'zoomOut') num = 100
|
||
|
||
zoom *= 0.999 ** num
|
||
if (zoom > 20) zoom = 20
|
||
if (zoom < 0.01) zoom = 0.01
|
||
|
||
// console.log(zoom);
|
||
canvas.zoomToPoint(
|
||
{ // 关键点
|
||
x: opt.e.offsetX,
|
||
y: opt.e.offsetY
|
||
},
|
||
zoom
|
||
)
|
||
opt.e.preventDefault()
|
||
opt.e.stopPropagation()
|
||
}
|
||
//设置再画布上按下
|
||
let setCanvasDown = (event)=>{
|
||
//设置移动端按下添加元素
|
||
if(operation.value == 'zoomIn' || operation.value == 'zoomOut'){
|
||
setCanvasZoom(event)
|
||
return
|
||
}
|
||
if(isMoible && present.upScaleChecked){
|
||
present.upScaleChecked = false
|
||
present = {}
|
||
let pointerVpt = canvas.restorePointerVpt(event.pointer)
|
||
switch (currentType.value.type) {
|
||
case 'colorBoards':
|
||
let rect = setGroup(currentType.value.data)
|
||
setCanvasColor(pointerVpt.y, pointerVpt.x,rect)
|
||
break
|
||
case 'moodboardFiles':
|
||
createImage(pointerVpt.y, pointerVpt.x,currentType.value.type)
|
||
break
|
||
default :
|
||
createImage(pointerVpt.y, pointerVpt.x,currentType.value.type)
|
||
break
|
||
}
|
||
// 创建完元素,把当前操作的元素类型设置回 null
|
||
currentType.value.type = null
|
||
currentType.value.data = null
|
||
}
|
||
downPoint = event.absolutePointer
|
||
let arr = ['rect','line','circle','triangle','ellipse','fold']
|
||
if(arr.indexOf(operation.value) > -1){
|
||
JSchangeType(canvas,operation.value)
|
||
createPatterningIs = true
|
||
if(currentPatterning && operation.value == 'fold'){
|
||
canvas.skipTargetFind = false
|
||
currentPatterning.points.push({
|
||
x: downPoint.x,
|
||
y: downPoint.y
|
||
})
|
||
// currentPatterning = JScanvasMouseDown(operation.value,event,canvasPencilWidth.value,currentPatterning)
|
||
}else{
|
||
currentPatterning = JScanvasMouseDown(operation.value,event,canvasPencilWidth.value[operation.value]?canvasPencilWidth.value[operation.value]:20,currentPatterning)
|
||
canvas.add(currentPatterning)
|
||
canvas.bringToFront(currentPatterning);//设置优先级最高
|
||
if(operation.value == 'fold'){
|
||
polyLineBtn = JScreateCheck(event)
|
||
polyLineBtn.on('mousedown',foldEnd)
|
||
canvas.add(polyLineBtn)
|
||
}
|
||
}
|
||
}else{
|
||
var clickedObject = event.target;
|
||
if (clickedObject instanceof fabric.Textbox && operation.value != 'text') {
|
||
textDataShow.value = true
|
||
createText = clickedObject
|
||
setTextData(clickedObject)
|
||
}else{
|
||
textDataShow.value = false
|
||
createText = {}
|
||
}
|
||
createPatterningIs = false
|
||
}
|
||
}
|
||
let foldEnd = (key)=>{
|
||
canvas.skipTargetFind = true
|
||
let points = currentPatterning.points
|
||
if(key == 'Enter'){
|
||
}else{
|
||
points.pop()
|
||
}
|
||
points.pop()
|
||
canvas.remove(currentPatterning)
|
||
let polyline = new fabric.Polyline(points, {
|
||
fill: operationMode.value == 'fill'? canvasPencilColor.value : 'transparent',
|
||
stroke: canvasPencilColor.value,
|
||
strokeWidth:canvasPencilWidth.value[operation.value]?canvasPencilWidth.value[operation.value]:20,
|
||
selection:false,
|
||
})
|
||
canvas.add(polyline)
|
||
// currentPatterning.set({stroke: canvasPencilColor.value})
|
||
createPatterningIs = false
|
||
clearPatterning()//临时图形置为空并且添加撤回对象里面
|
||
setOperation('move')
|
||
}
|
||
//设置再画布上抬起
|
||
let setCanvasUp = (event)=>{
|
||
upPoint = event.absolutePointer
|
||
if(canvas.isDrawingMode){
|
||
setTimeout(() => {
|
||
// pencilbtnStyle.value.display = `none`
|
||
updateCanvasState()
|
||
}, 100);
|
||
}else{
|
||
// event.target && (event.target.bringToFront())//设置优先级
|
||
}
|
||
var selectedObjects = canvas.getActiveObjects();//获取多选选中的内容
|
||
if (selectedObjects.length >= 1) {
|
||
allSelect.value = selectedObjects
|
||
// allSelectWidth.value = 0
|
||
allSelectWidth.value = (selectedObjects[0].width * selectedObjects[0].scaleX).toFixed(0)
|
||
}else{
|
||
allSelectWidth.value = -1
|
||
}
|
||
if(createPatterningIs){
|
||
|
||
switch (operation.value) {
|
||
case 'line':
|
||
currentPatterning.set({stroke: canvasPencilColor.value})
|
||
break
|
||
case 'fold':
|
||
// currentPatterning.set({stroke: canvasPencilColor.value})
|
||
break
|
||
default :
|
||
if(operationMode.value == 'fill'){
|
||
currentPatterning.set({fill: canvasPencilColor.value})
|
||
}else if (operationMode.value == 'border'){
|
||
currentPatterning.set({fill: 'transparent',stroke: canvasPencilColor.value,strokeWidth: canvasPencilWidth.value[operation.value]?canvasPencilWidth.value[operation.value]:20})
|
||
}
|
||
if(JSON.stringify(downPoint) == JSON.stringify(upPoint)){
|
||
canvas.remove(currentPatterning)
|
||
}
|
||
break
|
||
}
|
||
if(operation.value == 'fold'){
|
||
canvas.forEachObject((obj) =>obj.selectable = false);
|
||
canvas.bringToFront(polyLineBtn);//设置优先级最高
|
||
}else if(operation.value){
|
||
createPatterningIs = false
|
||
clearPatterning()//临时图形置为空并且添加撤回对象里面
|
||
canvas.renderAll();
|
||
setOperation('move')
|
||
}
|
||
}
|
||
}
|
||
let setHDExport = async ()=>{//获取选中内容的位置信息
|
||
// if(allBoardData.value.printboardFiles.length <= 0){
|
||
// message.info('Your print is empty')
|
||
// return
|
||
// }
|
||
if(allBoardData.value.printboardFiles.length<=0){
|
||
return
|
||
}
|
||
if(credits.value < 30){
|
||
message.info( useI18.t('exportModel.jsContent3'))
|
||
// return
|
||
}
|
||
showSRExport.value = true
|
||
let arr = []
|
||
if(allBoardData.value.printboardFiles){
|
||
allBoardData.value.printboardFiles.forEach((item)=>{
|
||
arr.push({
|
||
imgUrl:item.imgUrl,
|
||
checked:false,
|
||
})
|
||
})
|
||
}
|
||
allExportSR.value = arr
|
||
allChecked.value = false
|
||
|
||
//多选导出转高清暂时不用
|
||
|
||
// let {url,imageType} = await exportSele(canvas,'jpeg')
|
||
// if(!imageType){
|
||
// message.info('Please select the region of SR')
|
||
// return
|
||
// }
|
||
// let img = new Image
|
||
// img.src = url
|
||
// let imgStyle = {
|
||
// 'width': '80%',
|
||
// 'max-height': '30rem',
|
||
// 'object-fit': 'contain',
|
||
// 'position': 'relative',
|
||
// 'left': '50%',
|
||
// 'transform': 'translateX(-50%)',
|
||
// }
|
||
// let imgElement = createVNode('img',{src:url,style:imgStyle})
|
||
// img.onload = ()=>{
|
||
// Modal.confirm({
|
||
// title: 'SR needs 300 points, whether to continue?',
|
||
// icon: false,
|
||
// okText: 'Yes',
|
||
// cancelText: 'No',
|
||
// content: imgElement,
|
||
// mask:false,
|
||
// centered:true,
|
||
// onOk() {
|
||
// if(img.width*scaleSR.value>4069 || img.height*scaleSR.value>4069){
|
||
// message.info('Your selected area and SR magnification are more than 4096 pixels,Please re-select.')
|
||
// return
|
||
// }
|
||
// let data = {
|
||
// images: url,
|
||
// scale: scaleSR.value,
|
||
// uniqueId: "",
|
||
// imageType:imageType,
|
||
// }
|
||
// Https.axiosPost(Https.httpUrls.prepareForSR, data).then((rv) => {
|
||
// console.log(rv);
|
||
// store.dispatch('getCredits')
|
||
// emit('setTask')
|
||
// });
|
||
// },
|
||
// // onCancel(){
|
||
// // _this.isShowMark.value = false
|
||
// // resolve(false)
|
||
// // }
|
||
// });
|
||
// }
|
||
}
|
||
let allExportSR = ref([])
|
||
let scaleSR = ref(2);
|
||
|
||
let setScaleSR = (value)=>{
|
||
scaleSR.value = value
|
||
}
|
||
let showSRExport = ref(false)
|
||
let cancelSRExport = ()=>{
|
||
allExportSR.value = []
|
||
showSRExport.value = false
|
||
}
|
||
let allChecked = ref(false)
|
||
let selectImg = (item)=>{
|
||
item.checked = !item.checked
|
||
let arr = allExportSR.value.filter((item)=>item.checked)
|
||
if(arr.length == allExportSR.value.length){
|
||
allChecked.value = true
|
||
}else{
|
||
allChecked.value = false
|
||
}
|
||
}
|
||
let selectAllImg = ()=>{
|
||
allChecked.value = !allChecked.value
|
||
allExportSR.value.forEach((item)=>{
|
||
item.checked = allChecked.value
|
||
})
|
||
}
|
||
let setExportSR = ()=>{
|
||
let arr = []
|
||
let data = []
|
||
// if(allExportSR.value.filter(item=> item.checked ).length <= 0){
|
||
// message.info('Your print is empty')
|
||
// return
|
||
// }
|
||
if(credits < (allExportSR.value.filter(item=> item.checked ).length*30)){
|
||
message.info(useI18.t('exportModel.jsContent4'))
|
||
return
|
||
}
|
||
let allPromise = allExportSR.value.map(async (item,index)=>{
|
||
if(item.checked){
|
||
return await new Promise((resolve,reject)=>{
|
||
let obj = {}
|
||
obj = {
|
||
images:item.imgUrl,
|
||
scale: scaleSR.value,
|
||
uniqueId: "",
|
||
}
|
||
data.push(obj)
|
||
let img = new Image
|
||
img.onload = ()=>{
|
||
if(img.width*scaleSR.value>2048 || img.height*scaleSR.value>2048){
|
||
arr.push(index)
|
||
}
|
||
img.remove()
|
||
resolve(img)
|
||
}
|
||
img.src = item.imgUrl
|
||
})
|
||
}else{
|
||
return
|
||
}
|
||
})
|
||
Promise.all(allPromise)
|
||
.then(promiseArr => {
|
||
if(arr.length > 0){
|
||
arr.forEach((item,index)=>arr[index]+=1)
|
||
let str = arr.join(',')
|
||
message.info(useI18.t('exportModel.jsContent5',{str:str}))
|
||
return
|
||
}
|
||
let aa = promiseArr.filter(item=> item == undefined)
|
||
if(aa.length == promiseArr.length){
|
||
message.info(useI18.t('exportModel.jsContent6'))
|
||
|
||
}else{
|
||
Https.axiosPost(Https.httpUrls.prepareForSR, data).then((rv) => {
|
||
emit('setTask',rv)
|
||
cancelSRExport()
|
||
});
|
||
}
|
||
|
||
})
|
||
.catch(error => {
|
||
});
|
||
|
||
}
|
||
|
||
let toSvg = ()=>{
|
||
// console.log(canvas.toSvg());
|
||
}
|
||
let setShare = async ()=>{
|
||
initAligningGuidelines(canvas,false)
|
||
let publishModal = publish.value
|
||
publishModal.publishMask = true
|
||
var imageDataURL = await setExportCanvas()
|
||
let data = {
|
||
"imgUrl":imageDataURL,
|
||
userlikeGroupId:userlikeGroupId,
|
||
}
|
||
publishModal.init(data)
|
||
document.removeEventListener('keydown',canvasKeyDown);
|
||
document.removeEventListener('keyup', canvasKeyUp);
|
||
}
|
||
const clearPublish = ()=>{
|
||
document.addEventListener('keydown',canvasKeyDown);
|
||
document.addEventListener('keyup', canvasKeyUp);
|
||
}
|
||
let setSubmit = ()=>{
|
||
let data = setCanvasContent(false)
|
||
data.canvasHeight = canvasWH.value.height
|
||
let blob = new Blob([JSON.stringify(data)], { type: "application/json" });
|
||
let formData = new FormData();
|
||
formData.append("file", blob, "data.json");
|
||
formData.append('userLikeGroupId', userlikeGroupId);
|
||
let config = {headers:{'Content-Type':'multipart/form-data','Accept':'*/*' }}
|
||
Https.axiosPost(Https.httpUrls.exportSave, formData,config).then((rv)=>{
|
||
message.success(t('exportModel.jsContent7'))
|
||
})
|
||
}
|
||
let setCanvasContent = (isSaveImg)=>{
|
||
var json = canvas.toJSON(['imgId','minioUrl']);
|
||
// console.log(JSON.stringify(json));
|
||
if(!isSaveImg){
|
||
json.objects.forEach(item=>{
|
||
if(item.type == 'image'){
|
||
delete item.src
|
||
}
|
||
})
|
||
}
|
||
return json
|
||
}
|
||
let textDataShow = ref(false)
|
||
let setTextData = (obj)=>{
|
||
fontFamily.value = obj.fontFamily
|
||
canvasPencilWidth.value['text'] = obj.fontSize
|
||
canvasPencilColor.value = obj.fill
|
||
}
|
||
let setFontFamily = ()=>{
|
||
if(createText.set){
|
||
createText.set({
|
||
fontFamily:fontFamily.value,
|
||
fontSize:canvasPencilWidth.value[operation.value]?canvasPencilWidth.value[operation.value]:20,
|
||
fill:canvasPencilColor.value,
|
||
})
|
||
canvas.renderAll();
|
||
}
|
||
}
|
||
|
||
//液化
|
||
//当前选择的液化对象
|
||
let liquefactionData = ref(null)
|
||
let liquefaction = ref(null)
|
||
let submitLiquefaction = (rv)=>{
|
||
const originalWidth = liquefactionData.width * liquefactionData.scaleX; // 保存原始宽度
|
||
const originalHeight = liquefactionData.height * liquefactionData.scaleY; // 保存原始高度
|
||
liquefactionData.setSrc(rv, function() {
|
||
liquefactionData.scaleToWidth(originalWidth);
|
||
liquefactionData.scaleToHeight(originalHeight);
|
||
delete liquefactionData.minioUrl
|
||
canvas.renderAll();
|
||
updateCanvasState()
|
||
});
|
||
}
|
||
const clearLiquefaction = ()=>{
|
||
setCanvasKeyDown()
|
||
}
|
||
let setLiquefaction = ()=>{
|
||
const activeObjects = canvas.getActiveObjects(); // 获取选中的对象
|
||
if (activeObjects.length === 1 && activeObjects[0].type === 'image') {
|
||
liquefactionData = activeObjects[0]
|
||
liquefaction.value.init(activeObjects[0])
|
||
clearCanvasKeyDown()
|
||
} else {
|
||
message.info(useI18.t('exportModel.jsContent6'))
|
||
return null;
|
||
}
|
||
}
|
||
onMounted(() => {
|
||
let arr = [
|
||
{ value: 'Arial', name: 'select font' },
|
||
{ value: 'EN_slogan_art1', name: 'select font' },
|
||
{ value: 'EN_slogan_art2', name: 'select font' },
|
||
{ value: 'EN_slogan_art3', name: 'select font' },
|
||
{ value: 'EN_slogan_art4', name: 'select font' },
|
||
{ value: 'EN_slogan_art5', name: 'select font' },
|
||
{ value: 'EN_slogan_art6', name: 'select font' },
|
||
{ value: 'EN_slogan_art7', name: 'select font' },
|
||
{ value: '微软雅黑', name: '请选择字体' },
|
||
{ value: 'CN_slogan_art1', name: '请选择字体' },
|
||
{ value: 'CN_slogan_art2', name: '请选择字体' },
|
||
{ value: 'CN_slogan_art3', name: '请选择字体' },
|
||
{ value: 'CN_slogan_art4', name: '请选择字体' },
|
||
{ value: '华文行楷', name: '请选择字体' },
|
||
{ value: '隶书', name: '请选择字体' },
|
||
]
|
||
textFontFamilyList.value = arr
|
||
fontFamily.value = arr[0].value
|
||
|
||
});
|
||
onBeforeUnmount(()=>{
|
||
clearCanvasKeyDown()
|
||
})
|
||
return {
|
||
toSvg,
|
||
t,
|
||
toSvg,
|
||
isWindow,//判断是window还是mac
|
||
showUpgradePlan,//当前弹窗是否打开
|
||
canvasWH,//画布初始宽高
|
||
pencilbtnStyle,//笔触按钮
|
||
publish,//发布作品广场
|
||
credits,//积分 用来判断HD导出积分是否够用
|
||
init,//首页点击导出后初始化
|
||
setExport,//导出所有内容
|
||
cancelDsign,//关闭画布
|
||
setMaxInput,//设置画布宽高
|
||
isShowMark,//加载遮罩
|
||
allBoardData,//选择画布所有内容
|
||
closeNav,//导航展开或者收起来状态
|
||
setCloseNav,//给图片导航或者工具收起来或者展开
|
||
multiselect,//获取整体高度
|
||
onDragstart,//拖拽函数
|
||
setDragstart,//的移动端拖拽改为按下
|
||
historyState,//执行撤回或者反撤回
|
||
operation,//设置当前鼠标状态绘画或者矩形或者移动
|
||
operationMode,//设置矩形是边框还是填充
|
||
setOperation,//设置当前鼠标状态绘画或者矩形或者移动方法
|
||
setOperationMode,//设置矩形是边框还是填充方法
|
||
uploadImage,//上传图帕
|
||
setLayerIndex,//设置选中元素的层级
|
||
brushList,//笔触列表
|
||
clearPublish,
|
||
textureList,//材质列表
|
||
canvasPencilColor,//input选择颜色
|
||
canvasPencilWidth,//input选择宽度
|
||
setAllSelectWidth,//多选设置宽度
|
||
allSelectWidth,//多选设置宽度的值
|
||
colorHistoryList,//历史颜色
|
||
setColorHistory,//设置历史颜色
|
||
setPencilColor,//切换颜色执行函数 给当前矩形或者笔触设置颜色
|
||
setPencilWidth,//切换宽度执行函数 给当前矩形或者笔触设置宽度
|
||
setHDExport,//高清导出选择的图片
|
||
brushworkChange,//切换笔触的回调
|
||
keysList,
|
||
textureValueChange,//切换材质信息
|
||
brushworkValue,//当前笔触
|
||
textureValue,//当前材质
|
||
scaleSR,
|
||
setScaleSR,
|
||
//SR页面
|
||
showSRExport,
|
||
allExportSR,
|
||
cancelSRExport,//关闭高清导出
|
||
allChecked,//全选
|
||
selectAllImg,//控制全选
|
||
selectImg,//选中单个图片
|
||
setExportSR,//设置SR导出
|
||
setShare,
|
||
setSubmit,
|
||
textFontFamilyList,
|
||
fontFamily,
|
||
textDataShow,
|
||
setFontFamily,
|
||
//液化
|
||
liquefaction,
|
||
submitLiquefaction,
|
||
clearLiquefaction,
|
||
setLiquefaction,
|
||
};
|
||
},
|
||
data(prop) {
|
||
return {
|
||
isMoible:isMoible()
|
||
};
|
||
},
|
||
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: {
|
||
'canvasWH.height':{
|
||
handler(newVal,oldVal){
|
||
|
||
let canvasBox = document.querySelector('.exportCanvasBox .exportCanvasBox_center')
|
||
let scrollBox = document.querySelector('.exportCanvasBox_scroll div')
|
||
if(!canvasBox || !scrollBox)return
|
||
canvasBox.scroll({
|
||
top: 0, // 纵向滚动距离
|
||
left: 0, // 横向滚动距离
|
||
});
|
||
scrollBox.style.marginTop = 0+'px'
|
||
let height = canvasBox.offsetHeight / (newVal / canvasBox.offsetHeight )
|
||
scrollBox.style.height = height +'px'
|
||
if(oldVal != 0)return
|
||
let canvasBoxDom = document.querySelector('.exportCanvasBox .exportCanvasBox_center')
|
||
let scale = (newVal - canvasBoxDom.offsetHeight) / (canvasBoxDom.offsetHeight - height)
|
||
let mouseDownOperation = (event)=>{//按下
|
||
let position = {
|
||
y:event.screenY,
|
||
top : scrollBox.style.marginTop?scrollBox.style.marginTop.split('px')[0]*1:0
|
||
}
|
||
// let top =
|
||
let scrollMousemove = (e)=>{
|
||
let height = scrollBox.style.height.split('px')[0]*1
|
||
let offsetTop = position.top+e.screenY - position.y
|
||
offsetTop = offsetTop <= 0? 0 : offsetTop
|
||
offsetTop = height+offsetTop >= canvasBoxDom.offsetHeight? canvasBoxDom.offsetHeight - height : offsetTop
|
||
scrollBox.style.marginTop = offsetTop+'px'
|
||
canvasBoxDom.scroll({
|
||
top: offsetTop*scale, // 纵向滚动距离
|
||
left: 0, // 横向滚动距离
|
||
});
|
||
}
|
||
let mouseMove = function(event){
|
||
let e = getMousePosition(event,false)
|
||
scrollMousemove(e)
|
||
}
|
||
let touchmove = function(event){
|
||
let e = getMousePosition(event,true)
|
||
scrollMousemove(e)
|
||
}
|
||
let mouseup = function(){
|
||
document.removeEventListener('mousemove',mouseMove)
|
||
document.removeEventListener('touchmove',touchmove)
|
||
document.removeEventListener('mouseup',mouseup)
|
||
document.removeEventListener('touchend',mouseup)
|
||
//移动端
|
||
}
|
||
document.addEventListener('mousemove', mouseMove);
|
||
document.addEventListener('touchmove', touchmove);
|
||
document.addEventListener('mouseup', mouseup);
|
||
document.addEventListener('touchend', mouseup);
|
||
|
||
// document.addEventListener('touchmove',scrollMousemove)
|
||
// scrollBox.addEventListener('touchend',mouseup)
|
||
}
|
||
canvasBoxDom.addEventListener('scroll', ()=> {
|
||
let height = canvasBox.offsetHeight / (this.canvasWH.height / canvasBox.offsetHeight )
|
||
let scale = (this.canvasWH.height - canvasBoxDom.offsetHeight) / (canvasBoxDom.offsetHeight - height)
|
||
const scrollTop = canvasBoxDom.scrollTop;
|
||
scrollBox.style.marginTop = scrollTop/scale+'px'
|
||
});
|
||
let mousedown = function(event){
|
||
let e = getMousePosition(event,false)
|
||
mouseDownOperation(e)
|
||
}
|
||
|
||
let touchstart = function(event){
|
||
let e = getMousePosition(event,true)
|
||
mouseDownOperation(e)
|
||
}
|
||
scrollBox.addEventListener('mousedown',mousedown)
|
||
scrollBox.addEventListener('touchstart',touchstart)
|
||
}
|
||
},
|
||
},
|
||
mounted() {
|
||
|
||
},
|
||
|
||
methods: {
|
||
|
||
},
|
||
});
|
||
</script>
|
||
<style lang="less" scoped>
|
||
|
||
:deep(.Export) {
|
||
flex: 1;
|
||
// height: 30rem;
|
||
// overflow-x: hidden;
|
||
>.ant-modal-content {
|
||
.ant-modal-body{
|
||
display: flex;
|
||
flex-direction: column;
|
||
background: #f9fafb;
|
||
border-radius: 3rem;
|
||
}
|
||
}
|
||
.icon{
|
||
transition: all .3s;
|
||
}
|
||
.icon-rotate{
|
||
transform: rotate(-180deg);
|
||
}
|
||
|
||
.exportCanvasBox {
|
||
flex: 1;
|
||
overflow-x: hidden;
|
||
display: flex;
|
||
margin-top: 2rem;
|
||
justify-content: space-between;
|
||
flex-direction: column;
|
||
.exportCanvasBox_title {
|
||
margin-bottom: .5rem;
|
||
font-size: 1.8rem;
|
||
// font-weight: 600;
|
||
// margin-top: 2rem;
|
||
padding-top: 2rem;
|
||
display: flex;
|
||
top: -1rem;
|
||
justify-content: space-between;
|
||
cursor: pointer;
|
||
position: sticky;
|
||
z-index: 2;
|
||
align-items: flex-start;
|
||
margin: 0 2rem;
|
||
|
||
}
|
||
.exportCanvasBox_intro{
|
||
margin-bottom: 1rem;
|
||
font-size: 1.6rem;
|
||
font-weight: 600;
|
||
width: 100%;
|
||
}
|
||
.exportCanvasBox_right,
|
||
.exportCanvasBox_left {
|
||
width: 100%;
|
||
height: auto;
|
||
.exportCanvasBox_left_tool{
|
||
margin: 0;
|
||
}
|
||
.shortcutKeys_box{
|
||
position: relative;
|
||
.shortcutKeys_list{
|
||
display: none;
|
||
position: absolute;
|
||
z-index: 2;
|
||
width: 30rem;
|
||
max-height: 45rem;
|
||
background: #f7f8fa;
|
||
border-radius: 2rem;
|
||
right: 0;
|
||
overflow-y: auto;
|
||
padding: 2rem;
|
||
.shortcutKeys_list_item{
|
||
display: flex;
|
||
font-size: 1.8rem;
|
||
justify-content: space-between;
|
||
margin-bottom: 2rem;
|
||
>.key{
|
||
display: flex;
|
||
}
|
||
}
|
||
.shortcutKeys_list_item:last-child{
|
||
margin-bottom: 0;
|
||
}
|
||
}
|
||
&:hover{
|
||
.shortcutKeys_list{
|
||
display: block;
|
||
}
|
||
}
|
||
}
|
||
|
||
.label_item,label {
|
||
display: flex;
|
||
align-items: center;
|
||
width: 23%;
|
||
div {
|
||
width: auto;
|
||
margin-right: 2rem;
|
||
white-space: nowrap;
|
||
}
|
||
input,select {
|
||
// width: 10em;
|
||
flex: 1;
|
||
overflow: hidden !important;
|
||
height: 4.5rem;
|
||
}
|
||
|
||
.label_select{
|
||
img{
|
||
width: 100%;
|
||
max-height: 100%;
|
||
object-fit: contain;
|
||
}
|
||
}
|
||
}
|
||
.texture{
|
||
.label_select{
|
||
img{
|
||
max-height: none;
|
||
}
|
||
}
|
||
}
|
||
.exportCanvasBox_left_item{
|
||
width: 20rem;
|
||
.exportCanvasBox_title{
|
||
.exportCanvasBox_left_tool_item{
|
||
display: flex;
|
||
}
|
||
}
|
||
|
||
}
|
||
.exportCanvasBox_left_item.closeNav{
|
||
// max-height: 1000rem;
|
||
// height: auto;
|
||
display: block;
|
||
}
|
||
}
|
||
.exportCanvasBox_left::-webkit-scrollbar,
|
||
.exportCanvasBox_right::-webkit-scrollbar{display: none;}
|
||
.exportCanvasBox_left {
|
||
padding-right: 1rem;
|
||
margin-right: 2rem;
|
||
// height: 7rem;
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
align-items: flex-start;
|
||
position: relative;
|
||
flex-direction: row;
|
||
>label{
|
||
width: 20%;
|
||
}
|
||
.exportCanvasBox_title {
|
||
// margin: 0 4rem;
|
||
position: relative;
|
||
.exportCanvasBox_left_tool_item{
|
||
display: flex;
|
||
flex-direction: column;
|
||
|
||
}
|
||
.exportCanvasBox_left_tool_item_more{
|
||
flex-wrap: wrap;
|
||
flex-direction: row;
|
||
justify-content: flex-start;
|
||
padding: 1rem;
|
||
}
|
||
}
|
||
.exportCanvasBox_left_item{
|
||
overflow: hidden;
|
||
transition: all .3s;
|
||
// max-height: 0;
|
||
transform: translate3d(0, 0, 0);
|
||
position: absolute;
|
||
}
|
||
.exportCanvasBox_left_item,.exportCanvasBox_imgbor,.exportCanvasBox_operation_bor{
|
||
background: #fff;
|
||
height: auto;
|
||
max-height: 30rem;
|
||
border: 1px solid;
|
||
display: none;
|
||
top: 7rem;
|
||
position: absolute;
|
||
}
|
||
.exportCanvasBox_left_item.exportCanvasBox_left_tool{
|
||
top: 100%;
|
||
transform: translateY(-110%);
|
||
left: 100%;
|
||
}
|
||
|
||
.exportCanvasBox_imgbor {
|
||
// height: auto;
|
||
width: 20rem;
|
||
overflow-y: auto;
|
||
padding: 1rem;
|
||
&.exportCanvasBox_imgbor::-webkit-scrollbar{display: none;}
|
||
|
||
.exportCanvasBox_allItem {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
// justify-content: space-between;
|
||
justify-content: flex-start;
|
||
.exportCanvasBox_item {
|
||
text-align: center;
|
||
margin-right: 1rem;
|
||
.exportCanvasBox_img{
|
||
position: relative;
|
||
margin-bottom: 2rem;
|
||
img {
|
||
max-width: 7rem;
|
||
max-height: 14rem;
|
||
object-fit: contain;
|
||
|
||
}
|
||
.exportCanvasBox_img_SR{
|
||
position: absolute;
|
||
bottom: 0;
|
||
height: 2rem;
|
||
background: rgba(0, 0, 0, 0.3);
|
||
color: #fff;
|
||
width: 100%;
|
||
text-align: center;
|
||
font-weight: 600;
|
||
cursor: pointer;
|
||
}
|
||
}
|
||
|
||
}
|
||
.exportCanvasBox_item_colorBor{
|
||
width: 100%;
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
justify-content: space-between;
|
||
}
|
||
.exportCanvasBox_item_color{
|
||
width: 8rem;
|
||
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%;
|
||
}
|
||
}
|
||
.active{
|
||
opacity: .5;
|
||
transform: scale(.9);
|
||
}
|
||
}
|
||
}
|
||
.exportCanvasBox_operation_bor_item{
|
||
flex: 1;
|
||
margin-left: 8rem;
|
||
display: flex;
|
||
.label_item{
|
||
margin-right: 2rem;
|
||
position: relative;
|
||
.labelHover_show{
|
||
position: absolute;
|
||
width: 100%;
|
||
height: 10rem;
|
||
top: 100%;
|
||
z-index: 2;
|
||
flex-wrap: wrap;
|
||
div{
|
||
width: 3rem;
|
||
height: 3rem;
|
||
margin-right: 1rem;
|
||
margin-bottom: 1rem;
|
||
cursor: pointer;
|
||
}
|
||
}
|
||
}
|
||
.label_item:hover{
|
||
.labelHover_show{
|
||
display: flex;
|
||
}
|
||
}
|
||
}
|
||
.exportCanvasBox_left_tool_item{
|
||
display: flex;
|
||
flex: 1;
|
||
flex-wrap: wrap;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
|
||
flex-direction: row;
|
||
flex-wrap: nowrap;
|
||
&.leftAlign{
|
||
justify-content: flex-start;
|
||
}
|
||
&.leftAlign{
|
||
justify-content: flex-start;
|
||
}
|
||
|
||
i{
|
||
font-size: 2.5rem;
|
||
cursor: pointer;
|
||
width: 4rem;
|
||
height: 4rem;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
flex-shrink: 0;
|
||
&.active{
|
||
border: 1px solid;
|
||
border-radius: .4rem;
|
||
}
|
||
}
|
||
.icon-xiala{
|
||
transform: rotate(-90deg);
|
||
&.icon-rotate-tool{
|
||
transform: rotate(90deg);
|
||
}
|
||
}
|
||
.uploadImage{
|
||
width: 4rem;
|
||
height: 4rem;
|
||
input{
|
||
height: 0;
|
||
width: 0;
|
||
border: none;
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|
||
.exportCanvasBox_bottom{
|
||
width: 100%;
|
||
flex-shrink: 0;
|
||
background: #f9fafb;
|
||
z-index: 2;
|
||
padding-top: 2rem;
|
||
.exportCanvasBox_left_credits{
|
||
margin-right: auto
|
||
}
|
||
.exportCanvasBox_left_btn{
|
||
display: flex;
|
||
justify-content: flex-end;
|
||
flex-wrap: wrap;
|
||
align-items: flex-start;
|
||
.subitOkPreviewBtn{
|
||
position: initial;
|
||
transform: none;
|
||
margin-bottom: 0rem;
|
||
width: auto;
|
||
text-align: center;
|
||
&.active{
|
||
opacity: .7;
|
||
cursor: not-allowed;
|
||
}
|
||
}
|
||
.subitOkPreviewBtn:nth-child(2n){
|
||
margin: 0 1rem;
|
||
}
|
||
}
|
||
}
|
||
.exportCanvasBox_center_box{
|
||
display: flex;
|
||
overflow: hidden;
|
||
}
|
||
.exportCanvasBox_center {
|
||
flex: 1;
|
||
height: 100%;
|
||
overflow-y: auto;
|
||
overflow-x: hidden;
|
||
// overflow: hidden;
|
||
position: relative;
|
||
.editFrontBack_pencilbtn{
|
||
position: absolute;
|
||
z-index: 1;
|
||
border-radius: 50%;
|
||
border: 1px solid #000;
|
||
pointer-events: none;
|
||
transform: translate(-50%,-50%);
|
||
}
|
||
&.exportCanvasBox_center::-webkit-scrollbar {
|
||
/* 竖轴的宽度 */
|
||
display: none
|
||
}
|
||
}
|
||
.exportCanvasBox_scroll{
|
||
height: 100%;
|
||
width: 2rem;
|
||
background: #d6cfe3;
|
||
position: absolute;
|
||
right: 0;
|
||
top: 0;
|
||
border-radius: 1rem;
|
||
div{
|
||
background: #543087;
|
||
border-radius: 1rem;
|
||
width: 100%;
|
||
height: 30rem;
|
||
}
|
||
}
|
||
.export_new_collection_review {
|
||
position: initial;
|
||
margin: 10rem auto;
|
||
margin-bottom: 0;
|
||
}
|
||
}
|
||
}
|
||
</style>
|
||
<style lang="less">
|
||
.Export {
|
||
.ant-modal-content {
|
||
.ant-modal-body {
|
||
height: calc(65rem * 1.2);
|
||
}
|
||
}
|
||
|
||
}
|
||
.label_select_item{
|
||
img{
|
||
width: 100%;
|
||
max-height: 100%;
|
||
object-fit: contain;
|
||
}
|
||
}
|
||
</style>
|
||
<style lang="less">
|
||
.SRExport{
|
||
.ant-modal-body{
|
||
height: calc(35rem* 1.2);
|
||
}
|
||
.SRExport_img{
|
||
margin-bottom: 2rem;
|
||
flex: 1;
|
||
overflow-x: hidden;
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
min-height: 12rem;
|
||
.SRExport_img_item_box{
|
||
position: relative;
|
||
margin-right: 2rem;
|
||
margin-bottom: 2rem;
|
||
input{
|
||
position: absolute;
|
||
top: .5rem;
|
||
right: .5rem;
|
||
z-index: 2;
|
||
height: 2rem;
|
||
width: 2rem;
|
||
}
|
||
}
|
||
img{
|
||
width: 10rem;
|
||
max-height: 10rem;
|
||
object-fit: contain;
|
||
text-align: center;
|
||
cursor: pointer;
|
||
&.active{
|
||
transform: scale(.8);
|
||
opacity: .6;
|
||
}
|
||
}
|
||
}
|
||
.check_all_block{
|
||
display: flex;
|
||
align-items: center;
|
||
font-size: 1.6rem;
|
||
color: #64686D;
|
||
cursor: pointer;
|
||
justify-content: flex-end;
|
||
&.check_all{
|
||
color: #1A1A1A;
|
||
.check_block{
|
||
.check_block_body{
|
||
opacity: 1;
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
.check_block{
|
||
width: 2.4rem;
|
||
height: 2.4rem;
|
||
background: #EBECF4;
|
||
border: 0.1rem solid #64686D;
|
||
padding: 0.3rem;
|
||
margin-right: 0.7rem;
|
||
.check_block_body{
|
||
width: 100%;
|
||
opacity: 0;
|
||
height: 100%;
|
||
background: #343579;
|
||
}
|
||
}
|
||
}
|
||
.SRExport_operate{
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
.SRExport_operate_box {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-bottom: 1rem;
|
||
width: 100%;
|
||
>div {
|
||
width: 5rem;
|
||
}
|
||
.SRExport_operate_item_sclae{
|
||
width: 4rem;
|
||
height: 3rem;
|
||
border: .2rem solid rgba(0, 0, 0, 0.3);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
margin-right: 1rem;
|
||
cursor: pointer;
|
||
border-radius: .4rem;
|
||
font-weight: 600;
|
||
&.active{
|
||
border-color: rgba(152, 139, 247);
|
||
color: rgba(152, 139, 247);
|
||
}
|
||
}
|
||
.SRExport_operate_sclae{
|
||
max-width: 15rem;
|
||
|
||
}
|
||
|
||
// input {
|
||
// // width: 10em;
|
||
// overflow: hidden;
|
||
// }
|
||
// label{
|
||
// display: flex;
|
||
// align-items: center;
|
||
// margin-right: 2rem;
|
||
// span{
|
||
// margin-right: 1rem;
|
||
// }
|
||
// }
|
||
}
|
||
}
|
||
.generalModelOperate_endBtn{
|
||
.generalModelOperate_btn_ok{
|
||
&.active{
|
||
opacity: .6;
|
||
cursor: no-drop;
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
</style> |