Merge remote-tracking branch 'origin/StableVersion' into develop

This commit is contained in:
X1627315083
2024-09-25 11:07:49 +08:00
parent f840b03c0d
commit 309cdf16a9
33 changed files with 3462 additions and 748 deletions

View File

@@ -152,7 +152,7 @@
<div class="design_detail_perview_content" >
<!-- <div class="generate_button" v-show="designItemDetail.singleOverall == 'overall'" @click="generateHighDesign()">Generate Product lmage</div> -->
<setDesignItem ref="setDesignItem" @setParentLoadingShow=setParentLoadingShow @setDesignCoverage="setDesignCoverage" @setSubmit="setSubmit"></setDesignItem>
<setDesignItem ref="setDesignItem" :isBody="body" @setParentLoadingShow=setParentLoadingShow @setDesignCoverage="setDesignCoverage" @setSubmit="setSubmit"></setDesignItem>
<!-- <setDesignItemMobile v-else ref="setDesignItemMobile" @setParentLoadingShow=setParentLoadingShow @setDesignCoverage="setDesignCoverage" @setSubmit="setSubmit"></setDesignItemMobile> -->
</div>
@@ -507,15 +507,12 @@ export default defineComponent({
item.layersObject[0] = item.layersObject[1]
item.layersObject[1] = a
}
if(item.printObject.prints == null){
item.printObject.prints = []
}else{
item.printObject.prints.forEach((element:any) => {
if(!element.designType){
element.designType = 'Library'
}
});
}
if(item.printObject.prints == null)item.printObject.prints = []
item.printObject.prints.forEach((element:any) => {
if(!element.designType){
element.designType = 'Library'
}
});
})
this.currentIndex = 0
this.store.commit('setDesignItemDetail',rv)

View File

@@ -94,10 +94,8 @@
<div v-if="type_ == 2 && (current?.printObject?.prints?.length != 0 || printsList.length != 0 || exhibitionList.print.length != 0)" @click.stop="setPrint" class="subitOkPreviewBtn Guide_1_23">{{ $t('DesignDetailEnd.Layout') }}</div>
<!-- <div v-else-if="type_ == 2 && designItemDetail?.clothes?.[currentIndex]?.printObject?.prints?.[0]?.path != null && current?.printObject?.prints?.[0]?.path == null" @click.stop="setPreview" class="subitOkPreviewBtn">{{ $t('DesignDetailEnd.preview') }}</div> -->
<div v-if="type_ == 4 && (elementsList.length != 0 || exhibitionList.elements.length != 0)" @click.stop="setElemets" class="subitOkPreviewBtn">{{ $t('DesignDetailEnd.Layout') }}</div>
<DesignPrintOperation v-if="!moible" ref="DesignPrintOperation"></DesignPrintOperation>
<DesignPrintOperationMobile v-else ref="DesignPrintOperationMobile"></DesignPrintOperationMobile>
<DesignElementsOperation v-if="!moible" ref="DesignElementsOperation"></DesignElementsOperation>
<DesignPrintMobile v-else ref="DesignPrintMobile"></DesignPrintMobile>
<DesignPrintOperation ref="DesignPrintOperation"></DesignPrintOperation>
<DesignElementsOperation ref="DesignElementsOperation"></DesignElementsOperation>
</div>
<div class="mark_loading" v-show="loadingShow">
<a-spin size="large" />
@@ -112,7 +110,6 @@ import { Sketch} from '@ans1998/vue3-color'
import DesignPrintOperation from './DesignPrintOperation.vue';
import DesignPrintOperationMobile from './DesignPrintOperationMobile.vue';
import DesignElementsOperation from './DesignElements.vue';
import DesignPrintMobile from './DesignElementsMobile.vue';
import { message,Upload} from 'ant-design-vue';
import { openGuide,driverObj__ } from "@/tool/guide";
import {isMoible,setGradual} from '@/tool/util'
@@ -123,7 +120,7 @@ export default defineComponent({
props: ["msg"],
components:{
Draggable,Sketch,DesignPrintOperation,DesignPrintOperationMobile,
DesignElementsOperation,DesignPrintMobile,sketchCategory
DesignElementsOperation,sketchCategory
},
setup(prop) {
const store = useStore();
@@ -262,7 +259,8 @@ export default defineComponent({
setPrint(){
// if(this.current?.printObject?.prints?.[0]?.path){
let DesignPrintOperation = isMoible() ? this.$refs.DesignPrintOperationMobile : this.$refs.DesignPrintOperation
let DesignPrintOperation = this.$refs.DesignPrintOperation
// let DesignPrintOperation = isMoible() ? this.$refs.DesignPrintOperationMobile : this.$refs.DesignPrintOperation
DesignPrintOperation.init()
if(this.driver__.driver){
nextTick().then(()=>{

View File

@@ -99,7 +99,7 @@
</div>
<img :src="operationCurrent?.undividedLayer?operationCurrent.undividedLayer:operationCurrent.path" alt="" class="designOpenrtion_sketch">
<div class="designOpenrtion_btn">
<ul v-if="overallSingle" v-for="item,index in printStyleList[stateOverallSingle]" :key="item" :class="{active:item?.designOpenrtionBtn?item?.designOpenrtionBtn:false}" class="designOpenrtion_Mousingle" :style="item.style" @mousedown.stop="itemMoveMousedown(index,$event)">
<ul v-if="overallSingle" v-for="item,index in printStyleList[stateOverallSingle]" :key="item" :class="{active:item?.designOpenrtionBtn?item?.designOpenrtionBtn:false}" class="designOpenrtion_Mousingle" :style="item.style" @mousedown.stop="itemMoveMousedown(index,getMousePosition($event,false))" @touchstart.passive="itemMoveMousedown(index,getMousePosition($event,true))">
<li class="designOpenrtion_btn_top" @mousedown.stop="itemSizeMousedown('top',getMousePosition($event,false))" @touchstart.passive="itemSizeMousedown('top',getMousePosition($event,true))"></li>
<li class="designOpenrtion_btn_bottom" @mousedown.stop="itemSizeMousedown('bottom',getMousePosition($event,false))" @touchstart.passive="itemSizeMousedown('bottom',getMousePosition($event,true))"></li>
<li class="designOpenrtion_btn_left" @mousedown.stop="itemSizeMousedown('left',getMousePosition($event,false))" @touchstart.passive="itemSizeMousedown('left',getMousePosition($event,true))"></li>
@@ -110,7 +110,7 @@
</li>
</ul>
<div v-show="!overallSingle"></div>
<ul v-if="!overallSingle && printStyleList[stateOverallSingle][0]" class="designOpenrtion_Mouoverall active" :style="'left:'+printStyleList[stateOverallSingle][0]?.style?.left+';top:'+printStyleList[stateOverallSingle][0]?.style?.top+';'" @mousedown.stop="itemMoveMousedown(0,$event)">
<ul v-if="!overallSingle && printStyleList[stateOverallSingle][0]" class="designOpenrtion_Mouoverall active" :style="'left:'+printStyleList[stateOverallSingle][0]?.style?.left+';top:'+printStyleList[stateOverallSingle][0]?.style?.top+';'" @mousedown.stop="itemMoveMousedown(0,getMousePosition($event,false))" @touchstart.passive="itemMoveMousedown(0,getMousePosition($event,true))">
<i class="fi fi-rr-arrows animtion1"></i>
<i class="fi fi-rr-arrows animtion2"></i>
<li class="designOpenrtion_rotote" v-rotote.stop="[0,printStyleList[stateOverallSingle][0].transform]"></li>
@@ -294,7 +294,6 @@ export default defineComponent({
el.style.transform = "translate(-50%, -50%)rotateZ("+ angle + "deg)"
}
}
document.addEventListener('mousemove', mousemove);
// 添加鼠标松开事件监听器
let mouseup = () => {
value.instance.printStyleList[value.instance.stateOverallSingle][value.instance.imgDomIndex].transform.rotateZ = angle

View File

@@ -34,7 +34,12 @@
<input type="range" v-show="canvasState != 'move'" @input="setPencilWidth" min="1" max="50" v-model="canvasPencilWidth[canvasState]">
<!-- <div class="icon iconfont icon-xiala" :class="{btnRotate:spreadState}" @click="()=>spreadState = !spreadState"></div> -->
</div>
<div class="exportCanvasBox_center">
<div class="exportCanvasBox_center_box">
<div class="exportCanvasBox_center">
<!-- <div class="editFrontBack_bgImg" v-show="loadingShow">
<img :src="imgData?.undividedLayer" alt="">
</div> -->
</div>
<div class="editFrontBack_pencilbtn" v-show="loadingShow" :style="pencilbtnStyle"></div>
</div>
</div>
@@ -63,6 +68,7 @@ import allOrder from "@/component/Pay/allOrder.vue";
import creditsDetail from "@/component/Pay/creditsDetail.vue";
import { exportSele,JSRectUpdata,JSchangeType,JScanvasMouseDown,JSSetRemoveImage,JScreateCheck,JSSetTexture } from "@/tool/canvasDrawing";
import { useI18n } from "vue-i18n";
import { getMousePosition } from "@/tool/mdEvent";
export default defineComponent({
components: {
creditsDetail,
@@ -110,15 +116,8 @@ export default defineComponent({
exportWH = 512
nextTick(()=>{
let canvasBox = document.querySelector(".addDetails_modal .exportCanvasBox_center");
let oldCanvasDom = canvasBox.querySelector('.canvas-container')
let oldCanvasDom1 = canvasBox.querySelector('canvas')
var canvasDom = document.createElement("canvas");
document.addEventListener("keydown", canvasKeyDown);
document.addEventListener("keyup", canvasKeyUp);
if(oldCanvasDom)oldCanvasDom.remove()
if(oldCanvasDom)loadingShow.value = false
if(oldCanvasDom1)oldCanvasDom1.remove()
canvasBox.appendChild(canvasDom);
document.removeEventListener('mousemove', mouseMove);
document.removeEventListener('touchmove', touchmove);
let img = new Image();
img.onload = function(){
@@ -136,13 +135,11 @@ export default defineComponent({
exportWH = img.height
}
ratio = [wScale,hScale]
canvas = new fabric.Canvas(canvasDom, {
width: canvasWH.value * wScale,
height: canvasWH.value * hScale,
isDrawingMode: false, // 开启绘图模式
});
canvas = canvasGeneral.canvasInit(canvasBox,{
width:canvasWH.value * wScale,
height:canvasWH.value * hScale,
})
scale = img.height/canvas.height
JSchangeType(canvas,'init')
pencilbtnStyle.value.background = rgba
fabric.Object.prototype.cornerSize = 10
@@ -174,7 +171,8 @@ export default defineComponent({
});
//画布上移动
canvas.on("mouse:move", event =>setCanvasMove(event));
document.addEventListener('mousemove', mouseMove);
document.addEventListener('touchmove', touchmove);
setOperation('pencil')
img.remove()
}
@@ -206,20 +204,24 @@ export default defineComponent({
document.removeEventListener("keyup", canvasKeyUp);
}
let rgba = 'rgba(0, 0, 0, 1)'
let mouseMove = (event)=>{
let e = getMousePosition(event,false)
setCanvasMove(e)
}
let touchmove = (event)=>{
let e = getMousePosition(event,true)
setCanvasMove(e)
}
let setCanvasMove = (event)=>{
var pointer = canvas.getPointer(event.e);
if(canvas.isDrawingMode){
canvas.setCursor('none');
}
let canvasBox = document.querySelector(".addDetails_canvasCenter .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 + pointer.y+'px'
canvas.requestRenderAll()
let canvasCenterBox = document.querySelector(".addDetails_modal .exportCanvasBox_center_box");
if(!canvasCenterBox)return
let parentX = event.clientX - canvasCenterBox.getBoundingClientRect().left
let parentY = event.clientY - canvasCenterBox.getBoundingClientRect().top
pencilbtnStyle.value.left = parentX + "px"
pencilbtnStyle.value.top = parentY+'px'
}
let setOperation = (str)=>{
canvasBtn.canvasState = str
@@ -339,26 +341,17 @@ export default defineComponent({
}
)
exportCanvas.add(obj)
// if(allObjects.length-1 == index){
// let data = exportCanvas.toDataURL('jpg')
// cancelDsign()
// clearCanvas()
// emit('setSloganData',data)
// }
})
let data = exportCanvas.toDataURL('jpg')
cancelDsign()
clearCanvas()
emit('setSloganData',data)
})
}
let cancelDsign = ()=>{
canvas.dispose();
showPayOrder.value = false
document.removeEventListener('keydown',canvasKeyDown);
document.removeEventListener('keyup', canvasKeyUp);
showPayOrder.value = false
}
return {
presentState,
@@ -473,6 +466,25 @@ export default defineComponent({
position: relative;
margin: 0 auto;
}
.exportCanvasBox_center_box{
padding: 3rem;
height: 100%;
flex: 1;
position: relative;
width: 100%;
background: #e6e6e6;
&:hover{
cursor: none;
}
.editFrontBack_pencilbtn{
position: absolute;
z-index: 1;
border-radius: 50%;
border: 1px solid #000;
pointer-events: none;
transform: translate(-50%,-50%);
}
}
.exportCanvasBox_center{
height: 100%;
flex: 1;

View File

@@ -6,7 +6,7 @@
</div> -->
<i class="icon iconfont icon-chehui" @click="historyState('')"></i>
<i class="icon iconfont icon-fanchehui" @click="historyState('reverse')"></i>
<i class="icon iconfont icon-move" @click="setOperation('move')" :class="{active:canvasState == 'move'}"></i>
<!-- <i class="icon iconfont icon-move" @click="setOperation('move')" :class="{active:canvasState == 'move'}"></i> -->
<i class="icon iconfont icon-bianji" @click="setOperation('pencil')" :class="{active:canvasState == 'pencil'}"></i>
<i class="icon iconfont icon-xiangpi_huaban1" @click="setOperation('eraser')" :class="{active:canvasState == 'eraser'}"></i>
<div class="editFrontBack_center_btn_colorRed" @click="setOperationColor('rgb(255,0,0)')" :class="{active:rgba == 'rgb(255,0,0)'}" title="front"></div>
@@ -14,9 +14,11 @@
<input type="range" v-show="canvasState != 'move'" @input="setPencilWidth" min="1" max="50" v-model="canvasPencilWidth[canvasState]">
<!-- <div class="icon iconfont icon-xiala" :class="{btnRotate:spreadState}" @click="()=>spreadState = !spreadState"></div> -->
</div>
<div class="exportCanvasBox_center">
<div class="editFrontBack_bgImg" v-show="loadingShow">
<img :src="imgData?.undividedLayer" alt="">
<div class="exportCanvasBox_center_box">
<div class="exportCanvasBox_center">
<div class="editFrontBack_bgImg" v-show="loadingShow">
<img :src="imgData?.undividedLayer" alt="">
</div>
</div>
<div class="editFrontBack_pencilbtn" v-show="loadingShow" :style="pencilbtnStyle"></div>
</div>
@@ -32,6 +34,7 @@ import { ExclamationCircleOutlined } from "@ant-design/icons-vue";
import allOrder from "@/component/Pay/allOrder.vue";
import creditsDetail from "@/component/Pay/creditsDetail.vue";
import { exportSele,JSRectUpdata,JSchangeType,JScanvasMouseDown,JSSetRemoveImage,JScreateCheck,JSSetTexture } from "@/tool/canvasDrawing";
import { getMousePosition } from "@/tool/mdEvent";
import { useI18n } from "vue-i18n";
export default defineComponent({
components: {
@@ -92,18 +95,14 @@ export default defineComponent({
var canvasDom = document.createElement("canvas");
document.addEventListener("keydown", canvasKeyDown);
document.addEventListener("keyup", canvasKeyUp);
let oldCanvasDom = canvasBox.querySelector('.canvas-container')
let oldCanvasDom1 = canvasBox.querySelector('canvas')
if(oldCanvasDom)oldCanvasDom.remove()
if(oldCanvasDom)loadingShow.value = false
if(oldCanvasDom1)oldCanvasDom1.remove()
document.removeEventListener('mousemove', mouseMove);
document.removeEventListener('touchmove', touchmove);
canvasBox.appendChild(canvasDom);
let img = new Image();
img.onload = function(){
loadingShow.value = true
let height = canvasBox.offsetHeight;
canvasWH.value = height
console.log(canvasBox.offsetHeight);
canvasBox.style.width = height+'px'
let wScale = 1
let hScale = 1
@@ -117,13 +116,10 @@ export default defineComponent({
exportWH = img.height
}
ratio = [wScale,hScale]
canvas = new fabric.Canvas(canvasDom, {
width: canvasWH.value * wScale,
height: canvasWH.value * hScale,
isDrawingMode: false, // 开启绘图模式
});
JSchangeType(canvas,'init')
console.log(rgba.value);
canvas = canvasGeneral.canvasInit(canvasBox,{
width:canvasWH.value * wScale,
height:canvasWH.value * hScale,
})
pencilbtnStyle.value.background = rgba.value
fabric.Object.prototype.cornerSize = 10
fabric.Object.prototype.transparentCorners = false
@@ -159,7 +155,9 @@ export default defineComponent({
});
//画布上移动
canvas.on("mouse:move", event =>setCanvasMove(event));
// canvas.on("mouse:move", event =>setCanvasMove(event));
document.addEventListener('mousemove', mouseMove);
document.addEventListener('touchmove', touchmove);
setOperation('pencil')
createSetTimeSubmit()
img.remove()
@@ -186,8 +184,7 @@ export default defineComponent({
}
let setClone = ()=>{
// canvasBtn.canvasState = 'move'
// canvasBtn.spreadState = false
let canvasBox = document.querySelector(".editFrontBack_center .exportCanvasBox_center");
let oldCanvasDom = canvasBox.querySelector('.canvas-container')
let oldCanvasDom1 = canvasBox.querySelector('canvas')
@@ -200,22 +197,24 @@ export default defineComponent({
document.removeEventListener("keyup", canvasKeyUp);
}
let rgba = ref('rgb(255,0,0)')
let mouseMove = (event)=>{
let e = getMousePosition(event,false)
setCanvasMove(e)
}
let touchmove = (event)=>{
let e = getMousePosition(event,true)
setCanvasMove(e)
}
let setCanvasMove = (event)=>{
var pointer = canvas.getPointer(event.e);
if(canvas.isDrawingMode){
canvas.setCursor('none');
// brushIndicator.set({ left: pointer.x, top: pointer.y, visible: true,radius:(canvasBtn.canvasPencilWidth[canvasBtn.canvasState])/2 });
}
let canvasBox = document.querySelector(".editFrontBack_center .canvas-container");
const rect = canvasBox.getBoundingClientRect();
const parentRect = canvasBox.parentElement.getBoundingClientRect();
let parentX = rect.left - parentRect.left
let parentY = rect.top - parentRect.top
// brushIndicator.set({ left: x, top: y, visible: true,radius:(canvasBtn.canvasPencilWidth[canvasBtn.canvasState])/2 });
pencilbtnStyle.value.left = parentX + pointer.x+'px'
pencilbtnStyle.value.top = parentY + pointer.y+'px'
canvas.requestRenderAll()
let canvasCenterBox = document.querySelector(".editFrontBack_center .exportCanvasBox_center_box");
if(!canvasCenterBox)return
let parentX = event.clientX - canvasCenterBox.getBoundingClientRect().left
let parentY = event.clientY - canvasCenterBox.getBoundingClientRect().top
pencilbtnStyle.value.left = parentX + "px"
pencilbtnStyle.value.top = parentY+'px'
}
let setOperation = (str)=>{
canvasBtn.canvasState = str
@@ -227,7 +226,7 @@ export default defineComponent({
pencilbtnStyle.value.display = `block`
}else if(str == 'eraser'){
setEraser()
rgba.value = 'rgb(255,255,255)'
// rgba.value = 'rgb(255,255,255)'
pencilbtnStyle.value.display = `block`
}
}
@@ -373,6 +372,7 @@ export default defineComponent({
})
}
let cancelDsign = ()=>{
document.removeEventListener('keydown',canvasKeyDown);
document.removeEventListener('keyup', canvasKeyUp);
}
@@ -410,6 +410,7 @@ export default defineComponent({
// width: calc(512px / 2);
// width: 256px;
height: 100%;
width: 100%;
display: flex;
flex-direction: column;
// height: calc(512px / 2);
@@ -499,13 +500,30 @@ export default defineComponent({
transform: translate(-50%,0);
}
}
.exportCanvasBox_center{
.exportCanvasBox_center_box{
padding: 3rem;
height: 100%;
flex: 1;
position: relative;
width: 100%;
background: #e6e6e6;
&:hover{
cursor: none;
}
.editFrontBack_pencilbtn{
position: absolute;
z-index: 1;
border-radius: 50%;
border: 1px solid #000;
pointer-events: none;
transform: translate(-50%,-50%);
}
}
.exportCanvasBox_center{
margin: 0 auto;
overflow: hidden;
background: #e6e6e6;
height: 100%;
position: relative;
// overflow: scroll;
:deep(.canvas-container){
@@ -531,14 +549,7 @@ export default defineComponent({
object-fit: contain;
}
}
.editFrontBack_pencilbtn{
position: absolute;
z-index: 1;
border-radius: 50%;
border: 1px solid #000;
pointer-events: none;
transform: translate(-50%,-50%);
}
}
.exportCanvasBox_center:hover{
.editFrontBack_center_btn{

View File

@@ -1,141 +0,0 @@
<template>
<a-modal class="oldHsitory_detail_modal_component"
v-model:visible="hsitoryDetailShow"
:footer="null"
:title="collectionName"
width="80%"
:maskClosable="false"
:keyboard="false"
:centered="true"
>
<template #closeIcon>
<div class="close_icon" @click.stop="changeDetailShow()"><span class="icon iconfont icon-guanbi"></span></div>
</template>
<!-- <div class="history_detail_content scroll_style">
<div class="history_img_block" v-for="img in groupDetails" :key="img">
<div class="history_img_item" >
<img class="element_img" :src="img.url">
</div>
</div>
</div> -->
<OldExportNewCoolection ref="OldExportNewCoolection"></OldExportNewCoolection>
</a-modal>
</template>
<script lang="ts">
import OldExportNewCoolection from "@/component/HomePage/OldExportNewCoolection.vue";
import { defineComponent, ref, nextTick } from 'vue'
export default defineComponent({
components: {
OldExportNewCoolection
},
props:{
groupDetails:{
default:{},
},
collectionName:{
default:''
}
},
setup() {
let hsitoryDetailShow = ref(false)
return{
hsitoryDetailShow
}
},
data(){
return{
}
},
methods:{
init(data:any){
this.hsitoryDetailShow = true
nextTick().then(()=>{
let OldExportNewCoolection:any = this.$refs.OldExportNewCoolection
OldExportNewCoolection.init(data)
})
},
changeDetailShow(){
this.hsitoryDetailShow = !this.hsitoryDetailShow
}
}
})
</script>
<style lang="less">
.oldHsitory_detail_modal_component{
.ant-modal-body{
overflow-y: initial !important;
overflow-x: auto;
}
.export_new_collection_review{
position: relative;
left: 50%;
transform: translateX(-50%) scale(2);
transform-origin: top center;
top: 0;
}
.ant-modal-close{
width: 3.6rem;
height: 3.6rem;
position: absolute;
top: -1.8rem;
right: -1.8rem;
}
.ant-modal-header{
background: #F7F7F7;
}
.ant-modal-body{
background: #F2F3FB;
height: 80vh;
min-height: 72rem;
overflow-y: hidden;
padding: 0;
}
.close_icon{
width: 3.6rem;
height: 3.6rem;
background: #000000;
border-radius: 50%;
line-height: 3.6rem;
text-align: center;
.icon-guanbi{
font-size: 2rem;
color: #ffffff;
}
}
.history_detail_content{
padding: 2.6rem 2.0rem 2.6rem 3.7rem;
height: 100%;
width: 100%;
overflow-y:auto;
background: #FFFFFF;
.history_img_block{
width: 16.5rem;
height: 16.5rem;
border: 0.1rem solid #343579;
margin: 0 1.7rem 1.7rem 0;
display: inline-block;
.history_img_item{
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
}
.element_img{
max-width: 100%;
max-height: 100%;
}
}
}
}
</style>

View File

@@ -8,7 +8,6 @@
</div>
</div>
</div>
<div class="designOpenrtion_imgMask" :style="frontBack?.body?.style">
<!-- <div
v-for="item,index in frontBack.back"
@@ -26,7 +25,7 @@
<div class="detail_modal_item_front" v-for="item,index in frontBack.front" @mousedown.stop="itemMoveMousedown(index,getMousePosition($event,false))" @touchstart.passive="itemMoveMousedown(index,getMousePosition($event,true))" @click="setpitch(item,index)" :style="item.style">
<img :src="item.imageUrl" alt="">
</div>
<div class="designOpenrtion_btn">
<div class="designOpenrtion_btn" v-if="!isBody">
<ul v-for="item,index in frontBack.front" :key="item" :class="{active:item.designOpenrtionBtn}" class="designOpenrtion_btn" :style="item.style" @mousedown.stop="itemMoveMousedown(index,getMousePosition($event,false))" @touchstart.passive="itemMoveMousedown(index,getMousePosition($event,true))">
<li class="designOpenrtion_btn_top" @mousedown.stop="itemSizeMousedown('top',getMousePosition($event,false))" @touchstart.passive="itemSizeMousedown('top',getMousePosition($event,true))"></li>
<li class="designOpenrtion_btn_bottom" @mousedown.stop="itemSizeMousedown('bottom',getMousePosition($event,false))" @touchstart.passive="itemSizeMousedown('bottom',getMousePosition($event,true))"></li>
@@ -56,7 +55,7 @@ import { Https } from "@/tool/https";
import editFrontBack from '@/component/Detail/editFrontBack.vue'
import { getMousePosition } from "@/tool/mdEvent";
export default defineComponent({
// props: ["frontBack"],
props: ["isBody"],
emits:['setParentLoadingShow','setDesignCoverage','setSubmit'],
components:{editFrontBack},
setup(prop) {
@@ -160,11 +159,18 @@ export default defineComponent({
let front = []
let back = []
let body = {}
designItemDetail.others.forEach((item) => {
if(item.type == 'Body'){
if(designItemDetail.others.length > 0){
designItemDetail.others.forEach((item) => {
if(item.type == 'Body'){
body = item
}
});
}else{
designItemDetail.clothes.forEach((item) => {
body = item
}
});
});
}
let ratio = await this.setPostition(body.layersObject[0]?.imageUrl)
let frontIndex = 6
let backIndex = 3
@@ -243,7 +249,6 @@ export default defineComponent({
},
clear(){
this.imgDomIndex = -1
console.log(this.editFrontBack);
this.clothesOpenActive(-1)
this.editFrontBack.setClone()
window.removeEventListener('resize', this.setImgSizeTime);

View File

@@ -168,7 +168,6 @@
<i class="icon iconfont icon-move" @click="setOperation('move')" :class="{active:operation == 'move'}"></i>
<i class="icon iconfont icon-xiangpi_huaban1" @click="setOperation('eraser')" :class="{active:operation == 'eraser'}"></i>
<!-- <i class="icon iconfont icon-xiala" :class="closeNav.tool?'icon-rotate':''" @click.stop="setCloseNav('tool')"></i> -->
<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> -->
@@ -180,6 +179,7 @@
<input type="file" @change="uploadImage">
</label>
<i class="icon iconfont" @click="setOperation('text')" :class="{active:operation == 'text'}">T</i>
<i @click="setLiquefaction()">液化</i>
</div>
<!-- <div class="exportCanvasBox_left_tool exportCanvasBox_left_item" :class="{'closeNav' :closeNav.tool}">
<div class="exportCanvasBox_left_tool_item">
@@ -287,6 +287,7 @@
</div>
</a-modal>
<publish ref="publish" @setPublish="setSubmit"></publish>
<liquefaction ref="liquefaction" @submitLiquefaction="submitLiquefaction"></liquefaction>
</a-modal>
</template>
<script>
@@ -307,12 +308,14 @@ import { exportSele,JSRectUpdata,JSchangeType,JScanvasMouseDown,JScanvasMouseMov
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";
export default defineComponent({
components: {
scaleImage,
ExportNewCoolection,
publish,
liquefaction,
},
props: ["msg", "sketchCatecoryList"],
setup(props,{emit}) {
@@ -465,8 +468,9 @@ export default defineComponent({
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){
if(localUserlikeGroupId == userlikeGroupId && (new Date().getTime() - currentTime < 21600000)){
Modal.confirm({
title: useI18.t('exportModel.jsContent8'),
okText: 'Yes',
@@ -622,6 +626,7 @@ export default defineComponent({
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()
@@ -1931,6 +1936,46 @@ export default defineComponent({
canvas.renderAll();
}
}
//液化
let liquefaction = ref(null)
let submitLiquefaction = (rv)=>{
}
let setLiquefaction = ()=>{
const selectedObject = canvas.getActiveObjects();
if (selectedObject.length > 0) {
// 创建一个新的画布用于生成图片
const tempCanvas = new fabric.Canvas();
tempCanvas.setDimensions({
width: selectedObject.width,
height: selectedObject.height,
});
let cloneCount = 0;
selectedObject.forEach((obj) => {
obj.clone((clonedObject) => {
tempCanvas.add(clonedObject);
clonedObject.set({ left: obj.left, top: obj.top }); // 设置位置
cloneCount++;
// 当所有对象都克隆完成后生成图片
if (cloneCount === selectedObject.length) {
const dataURL = tempCanvas.toDataURL();
console.log(dataURL);
console.log('Image URL:', dataURL);
// 可以根据需要使用 dataURL例如显示在 img 标签中
}
});
});
// 生成图片的地址
} else {
console.log('No object selected.');
return null;
}
// liquefaction.value.init()
}
onMounted(() => {
let arr = [
{ value: 'Arial', name: 'select font' },
@@ -2009,6 +2054,10 @@ export default defineComponent({
fontFamily,
textDataShow,
setFontFamily,
//液化
liquefaction,
submitLiquefaction,
setLiquefaction,
};
},
data(prop) {

View File

@@ -1,6 +1,6 @@
<template>
<div class="generate">
<div v-if="type_.type2 == 'Printboard' && scene.value == 'Pattern'" class="generate_checkbox" >
<div v-if="(type_.type2 == 'Printboard' && scene.value == 'Pattern')" class="generate_checkbox" >
<generalMenu :dataList="printModelList" @setprintModel="setprintModel" :item="printModel" :driver__="driver__.driver" :driverClass="{class1: 'Guide_1_2_4'}"></generalMenu>
<!-- <generalMenu :dataList="sceneList" @setprintModel="setSceneList" :item="scene"></generalMenu> -->
<!-- <div v-if="type_.type2 == 'Printboard'" class="printModel">
@@ -14,7 +14,7 @@
</div>
<div class="input_border" >
<div class="input_box Guide_1_5" :class="[inputShow?'active':'',type_.type2 =='Sketchboard'?'Guide_1_9_2':'']">
<div class="input_box_btnBox">
<div class="input_box_btnBox" v-if="scene?.value != 'extract'">
<div class="upload_item">
<div
class="upload_file_item Guide_1_2_7"
@@ -39,13 +39,6 @@
</div>
</div>
</div>
<!-- <a-popover>
<template #content>
<p>Seed</p>
</template>
<input class="search_seed" max="9999" v-show="scene?.value == 'Logo'" @input="ifSeedValue" v-model="searchPictureSeed" type="Number" placeholder='Seed' min="0">
</a-popover> -->
<input
class="search_input"
@input="ifMaximumLength"
@@ -77,6 +70,53 @@
<i v-show="!isTextarea" class="fi fi-br-expand" @click.stop="setTextareaShow"></i>
<i v-show="isTextarea" class="fi fi-bs-compress" @click.stop="setTextareaShow"></i>
</div>
<div class="input_box_btnBox" v-else>
<div class="upload_item">
<div
class="upload_file_item"
v-for="(file, index) in sketchboardList"
:key="file"
:class="[driver__.driver?'showEvents':'']"
>
<div
class="upload_file_item_content"
v-show="file?.status === 'uploading'"
>
<a-spin size="small" :indicator="indicator" tip="Uploading..." />
</div>
<div
class="upload_file_item_content"
v-show="file?.status === 'done' || file?.base64"
>
<img :src="file?.imgUrl" class="upload_img" />
<div class="delete_like_file_block" :class="[driver__.driver?'hideEvents':'']">
<span class="icon iconfont icon-shanchu operate_icon" @click.stop="deleteFile(index)"></span>
</div>
</div>
</div>
</div>
<i class="fi fi-br-upload" style="margin-left: 2rem;" v-show="sketchboardList.length == 0" :title="$t('Generate.uploadproduct')">
<a-upload
class="search_upImg"
:capture="null"
:action="uploadUrl + '/api/element/upload'"
list-type="picture-card"
:data="{
...upload,
}"
:maxCount='1'
:headers="{ Authorization: token }"
v-model:file-list="sketchboardList"
:before-upload="beforeUpload"
accept=".jpg,.png,.jpeg,.bmp"
@change="(file) => fileUploadChange(file)"
>
</a-upload>
</i>
<div :title="$t('Generate.style')">
<generalMenu :dataList="printModelList" @setprintModel="setprintModel" :item="printModel"></generalMenu>
</div>
</div>
<textarea
v-show="isTextarea"
class="search_textarea "
@@ -86,10 +126,8 @@
@click.stop=""
v-model="searchPictureName"
></textarea>
<!-- <div class="generage_btn started_btn" @click.stop="getgenerate">{{ $t('Generate.Generate') }}</div> -->
<div v-show="!isGenerate" class="generage_btn started_btn" :class="{Guide_1_2_8:type_.type2 == 'Printboard'}" @click.stop="getgenerate">
{{ $t('Generate.Generate') }}
<!-- <div v-show="isGenerate"><a-spin size="large" /></div> -->
</div>
<div v-show="isGenerate && !remGenerate" class="generage_btn started_btn" :class="{Guide_1_2_8:type_.type2 == 'Printboard'}" @click="getgenerate">
<i class="fi fi-br-loading"></i>
@@ -108,37 +146,6 @@
</div>
</div>
</div>
<!-- <div v-if="type_.type2 == 'Sketchboard' || type_.type2 == 'Printboard'" class="generage_img Guide_1_6">
<div class="upload_item">
<div
class="upload_file_item Guide_1_2_7"
v-for="(file, index) in sketchboardList"
:key="file"
@click.stop="setSketchboardItem(file)"
:class="[file?.checked?'active':'',checkboxImage? 'forbidden':'',driver__.driver?'showEvents':'']"
>
<div
class="upload_file_item_content"
v-show="file?.status === 'uploading'"
>
<a-spin :indicator="indicator" tip="Uploading..." />
</div>
<div
class="upload_file_item_content"
v-show="file?.status === 'done'"
>
<img :src="file?.imgUrl" class="upload_img" />
<div
class="delete_file_block"
:class="[driver__.driver?'hideEvents':'']"
@click.stop="deleteFile(index)"
>
<span class="icon iconfont icon-shanchu"></span>
</div>
</div>
</div>
</div>
</div> -->
<div class="generage_img Guide_1_6" :class="{Guide_1_13_2:type_.type2 == 'Sketchboard',Guide_1_2_9:type_.type2 == 'Printboard'}" :style="[isGenerate?'overflow:hidden':'']">
<div
class="generage_img_item"
@@ -163,8 +170,11 @@
<span class="icon iconfont icon-shanchu operate_icon"></span>
</div>
</div>
<div class="mark_loading" v-show="loadingShow">
<a-spin size="large" />
</div>
</div>
<scaleImage ref="scaleImage"></scaleImage>
<scaleImage ref="scaleImage" :isCanvas="true" :workspace="workspace"></scaleImage>
<createSlogan ref="createSlogan" @setSloganData="setSloganData"></createSlogan>
</div>
</template>
@@ -196,25 +206,9 @@ export default defineComponent({
setup(props) {
// console.log(prop.msg);
let printModelList = ref([
{
num:'',
optype:false,
value:'Painting Style',
label:useI18n().t('Generate.Model1')
},{
num:'',
optype:false,
value:'Illustration Style',
label:useI18n().t('Generate.Model2')
},{
num:'',
optype:false,
value:'Real Style',
label:useI18n().t('Generate.Model3')
},
])
let printModel = ref({
let printModelList:any = ref([])
let sketchStyleList:any = ref([])
let printModel:any = ref({
num:'',
optype:false,
value:'Painting Style',
@@ -240,12 +234,13 @@ export default defineComponent({
let isTest = ref()
let userInfo:any = {}
let generateTime:any = ref()
let generateProceedList = ref([])
let generateProceedList:any = ref([])
let remGenerate:any = ref(false)
let remGenerateTime:any = ref()
let styleRecommend:any = inject('styleRecommend')
let generateLevel2Type = ''
let isSloganHint:any = ref(' ')
let loadingShow =ref(false)
return {
searchPictureName,
searchPictureSeed,
@@ -255,6 +250,7 @@ export default defineComponent({
level2Type,
printModel,
printModelList,
sketchStyleList,
isGenerate,
// printBoards,
@@ -274,6 +270,7 @@ export default defineComponent({
styleRecommend,
generateLevel2Type,
isSloganHint,
loadingShow,
};
},
data(prop) {
@@ -319,6 +316,42 @@ export default defineComponent({
this.workspaceCom = computed(()=>{
return this.store?.state?.Workspace?.workspace
})
// if()
if(this.type_.type2 == 'Printboard'){
this.printModelList = [
{
num:'',
optype:false,
value:'Painting Style',
label:useI18n().t('Generate.Model1')
},{
num:'',
optype:false,
value:'Illustration Style',
label:useI18n().t('Generate.Model2')
},{
num:'',
optype:false,
value:'Real Style',
label:useI18n().t('Generate.Model3')
},
]
}else if(this.type_.type2 == 'Sketchboard'){
this.printModelList = JSON.parse(JSON.stringify(this.store.state.UserHabit.SketchStyle))
this.printModelList.forEach((item:any)=>{
item.img = 'https://www.aida.com.hk/img/aida_logo.5ab4163e.png'
})
this.printModelList.push({
num:'',
optype:false,
img:-1,
value:'',
label:useI18n().t('Generate.Model1')
})
}
this.printModel = this.printModelList[0]
},
watch:{
driver__:{
@@ -377,6 +410,7 @@ export default defineComponent({
methods: {
generageAdd(data: any) {
data.type_ = this.type_;
data.type_.type1 = data.designType?data.designType:this.type_.type1
data.resData = JSON.parse(JSON.stringify(data))
let maxImg = 8
if(this.type_.type2 == 'Sketchboard'){
@@ -410,7 +444,41 @@ export default defineComponent({
setprintModel(value:any){
this.printModel = value
},
imageToSketch(){
if((!this.printModel?.id && !this.printModel?.value) || !this.sketchboardList?.[0]?.id)return message.info(this.t('Generate.jsContent4'));
this.loadingShow = true
let data = {
"elementId": this.sketchboardList[0].id,
gender:this.workspace.sexEnum.value,
"style": this.printModel.value,
"styleImageId": this.printModel.id?this.printModel.id:''
}
Https.axiosPost(Https.httpUrls.imageToSketch, data).then((rv)=>{
if(rv){
this.sketchCatecoryList.forEach((itemCategory:any) => {
if(itemCategory.value == rv.category){
rv.categoryValue = itemCategory?.value
rv.category = itemCategory?.name
}
});
this.fileList.push({
imgUrl:rv.url,
categoryValue:rv.categoryValue,
category:rv.category,
id:rv.id,
status:'Success',
})
this.loadingShow = false
}
}).catch(()=>{
this.loadingShow = false
})
},
getgenerate(){
if(this.scene?.value == 'extract'){
this.imageToSketch()
return
}
this.isTextarea = false
this.isInputFocus = false
if(this.isGenerate)return
@@ -844,7 +912,6 @@ export default defineComponent({
border-radius: calc(1rem*1.2);
img {
transform: scale(0.9);
object-fit: contain;
}
.delete_like_file_block{
pointer-events:none;
@@ -856,6 +923,7 @@ export default defineComponent({
img {
width: calc(10rem*1.2);
height: calc(10rem*1.2);
object-fit: contain;
}
&:hover .delete_like_file_block{
// display: block;

View File

@@ -1,190 +0,0 @@
<template>
<!-- 生成collention缩略图用的 -->
<div class="export_new_collection_review">
<div class="img_block_item" v-if="allBoardData?.moodTemplateId">
<MoodTemplate :fileList="allBoardData?.moodboardFiles" :moodTemplateId="allBoardData?.moodTemplateId"></MoodTemplate>
</div>
<div class="img_block_item" v-else>
<div class="lager_img_item" v-for="(mood) in allBoardData.moodboardFiles" :key="mood">
<div class="all_img_item_block">
<img class="all_img_content cover_img" :src="mood.imgUrl" >
</div>
</div>
</div>
<div class="img_block_item">
<div class="small_img_item" v-for="(print) in allBoardData.printboardFiles" :key="print">
<div class="all_img_item_block">
<img class="all_img_content cover_img" :src="print.imgUrl">
</div>
</div>
<div class="small_img_item" v-for="(generate) in allBoardData.generatePrintFiles" :key="generate">
<div class="all_img_item_block">
<img class="all_img_content cover_img" :src="generate.imgUrl">
</div>
</div>
</div>
<div class="img_block_item">
<div class="color_item" v-for="(color) in allBoardData.colorBoards" :key="color">
<div class="color_content" :style="{background:`rgb(${color?.rgbValue?.r},${color?.rgbValue?.g},${color?.rgbValue?.b})`}"></div>
<div class="color_content_body">
<div class="color_des">{{color.tcx}}</div>
<div class="color_des">{{color.name}}</div>
</div>
</div>
</div>
<div class="img_block_item">
<div class="lager_img_item" v-for="(skecth) in allBoardData.skecthboardFiles" :key="skecth">
<div class="all_img_item_block">
<img class="all_img_content" :src="skecth.imgUrl">
</div>
</div>
</div>
<div class="img_block_item">
<div class="lager_img_item" v-for="(marketing) in allBoardData.marketingSketchFiles" :key="marketing">
<div class="all_img_item_block">
<img class="all_img_content" :src="marketing.imgUrl">
</div>
</div>
</div>
<div class="img_block_item">
<div class="lager_img_item" v-for="(design) in allBoardData.likeDesignCollectionList" :key="design.designItemUrl">
<div class="all_img_item_block">
<img class="all_img_content" :src="design.designItemUrl">
</div>
</div>
</div>
</div>
</template>
<script lang="ts">
import { computed, defineComponent, ref } from 'vue'
import MoodTemplate from '@/component/HomePage/MoodTemplate.vue'
import { useStore } from "vuex";
export default defineComponent({
// props: {
// allBoardData: {
// // default: false,
// },
// },
components:{MoodTemplate},
setup() {
const allBoardData = ref({});
// let allBoardData:any = computed(()=>{return store.state.UploadFilesModule.allBoardData})
// let likeDesignCollectionList : any = computed(()=>{return store.state.HomeStoreModule.likeDesignCollectionList})
return {
allBoardData,
// likeDesignCollectionList,
}
},
mounted () {
},
methods:{
init(data:any){
this.allBoardData = data
}
}
})
</script>
<style lang="less" scoped>
.export_new_collection_review{
width: 40.8rem;
background: #fff;
position: fixed;
left: -100rem;
top: 0;
.img_block_item{
margin-bottom: 2rem;
// &.color_block_item{
// padding: 0 0.5rem 0 0.3rem;
// }
.lager_img_item{
display: inline-block;
width: 20.4rem;
height: 20.4rem;
vertical-align: top;
}
.sketch_img_item{
display: inline-block;
width: 20.4rem;
height: 42.2rem;
vertical-align: top;
}
.small_img_item{
width: 6.8rem;
height: 6.8rem;
display: inline-block;
vertical-align: top;
}
.color_item{
display: inline-block;
vertical-align: top;
// padding: 0 0.5rem;
margin-right: 1.6rem;
margin-bottom: 0.5rem;
&:nth-child(4n){
margin-right: 0;
}
}
.color_content{
width: 9rem;
height:6.2rem
}
.color_content_body{
width: 9rem;
padding: 0.7rem 0.2rem;
background: #FEFEFE;
border: 1px solid #E6E6E6;
.color_des{
font-size: 1rem;
font-family: Roboto;
font-weight: 500;
color: #000000;
margin-bottom: 0.5rem;
line-height: 1.3rem;
width: 100%;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
&:last-child{
margin-bottom: 0;
}
}
}
.all_img_item_block{
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
.all_img_content{
max-height: 100%;
max-width: 100%;
&.cover_img{
width: 100%;
height: 100%;
}
}
}
}
}
</style>

View File

@@ -203,18 +203,6 @@ export default defineComponent({
designType:''
})
let workspace:any = ref({})
let sceneList = ref([
{
name:'Pattern',
value:'Pattern'
},{
name:'Slogan',
value:'Slogan'
},{
name:'Logo',
value:'Logo'
},
])
let scene = ref({
name:'Pattern',
value:'Pattern'
@@ -234,7 +222,6 @@ export default defineComponent({
userInfo,
useGenerate,
workspace,
sceneList,
scene,
openMenu,
printCatecoryList,
@@ -700,6 +687,8 @@ export default defineComponent({
.printMenu{
margin-right: 0;
margin-top: auto;
position: relative;
margin-left: 2rem;
>div{
width: 14rem;
font-size: var(--aida-fsize1-6);
@@ -707,6 +696,8 @@ export default defineComponent({
i{
transition: all .3s;
display: inline-block;
position: absolute;
right: 0;
}
.forbidden{
transform: rotate(180deg);

View File

@@ -23,6 +23,19 @@
>
<span>{{ $t('SketchboardUpload.Generate') }}</span>
</div>
<div v-show="openClick == 3" class="generalMenu_printModel printMenu">
<div @click.stop="openPrintModel">{{ scene.name }} <i class="icon iconfont icon-xiala" :class="{forbidden:openMenu}"></i></div>
<ul v-show="openMenu">
<li
v-for="item,index in sketchStyleList"
class="printModel_item"
@click.stop="setSceneList(item)"
:title="item.value == 'Pattern'?$t('PrintboardUpload.PatternTitle'):
item.value == 'Logo'?$t('PrintboardUpload.LogoTitle'):
item.value == 'Slogan'?$t('PrintboardUpload.SloganTitle'):''"
>{{ item.name }}</li>
</ul>
</div>
</div>
<div v-show="openClick == 1" class="sketchboard_body">
<div class="upload_img_body scroll_style">
@@ -113,6 +126,7 @@
v-show="openClick == 3"
ref="Generate"
msg="Sketchboard"
:scene="scene"
:sketchCatecoryList="sketchCatecoryList"
></Generate>
</div>
@@ -214,6 +228,14 @@ export default defineComponent({
level2Type:'',
designType:'',
})
let scene = ref({
name:'Generate Sketch',
value:'generate'
})
let openMenu = ref(false)
let sketchStyleList:any = computed(()=>{
return store.state.UserHabit.SketchGenerateType
})
return {
fileList,
openClick,
@@ -227,6 +249,9 @@ export default defineComponent({
isTest,
userInfo,
useGenerate,
scene,
openMenu,
sketchStyleList,
};
},
data() {
@@ -549,6 +574,23 @@ export default defineComponent({
}
this.store.commit("setSketchboardFile", this.fileList);
},
setSceneList(data:any){
if(this.scene.value === data.value) return
this.scene = data
let generate:any = this.$refs.Generate
generate.sketchboardList = []
generate.searchPictureName = ''
this.openMenu = false
},
openPrintModel(){
if(this.openMenu)return
document.addEventListener('click',this.removePrintModel)
this.openMenu = true
},
removePrintModel(){
this.openMenu = false
document.removeEventListener('click',this.removePrintModel)
}
},
});
</script>
@@ -610,6 +652,32 @@ export default defineComponent({
margin-right: calc(0.8rem*1.2);
}
}
.printMenu{
margin-right: 0;
margin-left: 2rem;
margin-top: auto;
position: relative;
>div{
width: 14rem;
font-size: var(--aida-fsize1-6);
border: 0;
i{
transition: all .3s;
display: inline-block;
position: absolute;
right: 0;
}
.forbidden{
transform: rotate(180deg);
}
}
ul{
width: 14rem;
}
}
.switch_type_item:nth-child(3){
margin: 0;
}
}
.sketchboard_body {
// height: calc(100% - 5rem*1.2));

View File

@@ -1,16 +1,56 @@
<template>
<div class="generalMenu_printModel">
<div @click.stop="openPrintModel" :class="driverClass.class1">{{ item.label }}</div>
<div @click.stop="openPrintModel" :class="driverClass.class1">
<a-popover>
<template #content>
<img style="width: 10rem;height: 10rem;object-fit: contain;" :src="item.img" alt="">
</template>
<span v-if="item.label">{{ item.label }}</span>
<span v-else>{{ item.name }}</span>
</a-popover>
</div>
<ul :class="driverClass.class2" v-show="openClick">
<li v-for="item,index in dataList" :class="{active:deleteItem == index}" class="printModel_item" @click="setprintModel(item,index)">{{ item.label }}</li>
<li v-for="item,index in dataList" :class="{active:deleteItem == index}" class="printModel_item" @click="setprintModel(item,index)">
<a-popover placement="right">
<template #content>
<img v-if="item.img != -1" style="width: 10rem;height: 10rem;object-fit: contain;" :src="item.img" alt="">
<div v-else-if="item.img == -1" class="generalMenu_printModel_upload ">
<i class="fi fi-br-upload input_border" style="width: 8rem; height: 8rem;padding: 0;" :title="$t('Generate.uploadTitle')">
<a-upload
style="height: 100%;"
class="search_upImg"
:capture="null"
:action="uploadUrl + '/api/element/upload'"
list-type="picture-card"
:data="{
...upload,
}"
:maxCount='1'
:headers="{ Authorization: token }"
accept=".jpg,.png,.jpeg,.bmp"
@change="(file) => fileUploadChange(file)"
>
</a-upload>
</i>
</div>
</template>
<span v-if="item.label">{{ item.label }}</span>
<span v-else>{{ item.name }}</span>
</a-popover>
</li>
</ul>
</div>
</template>
<script lang="ts">
import { defineComponent,ref ,nextTick} from "vue";
import { Https } from "@/tool/https";
import { useStore } from "vuex";
import { Https } from "@/tool/https";
import { openGuide,driverObj__ } from "@/tool/guide";
import { getUploadUrl } from "@/tool/util";
import { getCookie } from "@/tool/cookie";
import { message, Upload, Modal } from "ant-design-vue";
export default defineComponent({
name:'filterComponent',
props:{
@@ -37,7 +77,7 @@
setup(props:any,{emit}){
let selectIndex = ref(0)
let openClick = ref(false)
let store = useStore();
let openPrintModel = ()=>{
document.addEventListener('click',removePrintModel)
openClick.value = true
@@ -48,7 +88,10 @@
})
}
let setprintModel = (item:any,index:any)=>{
console.log(item.img);
if(props.deleteItem == index) return
if(item.img == -1) return
openClick.value = false
selectIndex = index
nextTick().then(()=>{
@@ -62,15 +105,69 @@
openClick.value = false
document.removeEventListener('click',removePrintModel)
}
let fileUploadChange = (data: any)=>{
let file = data.file;
let bor = true
if (file.status === "done") {
let res = JSON.parse(file.xhr.response);
if(res.errCode == 0){
file.type_ = "upload";
props.dataList.forEach((item:any)=>{
if(item.img == -1){
item.img = res.data.url
item.id = res.data.id
}
})
}else{
bor = false
}
} else if (file.status === "error") {
bor = false
}
if(!bor){
let res:any = JSON.parse(file.xhr.response);
// props.dataList.forEach((item:any)=>{
// if(item.img == -1){
// }
// })
message.warning(res.errMsg);
}
}
return {
selectIndex,
openClick,
store,
setprintModel,
openPrintModel,
fileUploadChange,
}
},
data(prop) {
return {
upload: {
isPin: 0,
gender:'',
level1Type: 'Sketchboard',
timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,
},
token: "",
uploadUrl: "",
type_: {
type1: "generate",
type2: 'Sketchboard',
},
workspaceCom:{},
isTextarea:false,
isInputFocus:false,
};
},
mounted() {
this.uploadUrl = getUploadUrl();
this.token = getCookie("token") || "";
this.upload.gender = this.store?.state?.Workspace?.workspace?.sexEnum?.value
}
});
</script>
<style lang="less">
@@ -122,4 +219,9 @@
}
}
}
.generalMenu_printModel_upload{
>i{
justify-content: center;
}
}
</style>

View File

@@ -30,7 +30,7 @@
</div>
<div class="layout_centent" :class="{active:flex_direction}" id="layoutCentent">
<div v-for="item,index in layoutList" :key="item" :class="moodbClassName[index]" class="modal_imgItem" v-layout="index" @mousedown="setpitch(item,index)" @touchstart="setpitch(item,index)" ref="content" >
<img crossOrigin="anonymous" :src="item.imgUrl" :style="{'transform':item.angle?`translate(-50%, -50%) scale(${item.zoom}) rotateZ(${item.angle}deg)`:`translate(-50%, -50%) scale(${item.zoom})`}" draggable="false" :class="moodbClassName[index]" v-modelImg>
<img crossOrigin="anonymous" :src="item.imgUrl" :style="{'transform':item.angle?`translate(-50%, -50%) scale(${item.zoom}) rotateZ(${item.angle}deg)`:`translate(-50%, -50%) scale(${item.zoom}) rotateZ(${item.angle}deg)`}" draggable="false" :class="moodbClassName[index]" v-modelImg>
<div>
</div>
@@ -39,7 +39,7 @@
<li class="layout_btn_bottom" v-compile.stop="'bottom'"></li>
<li class="layout_btn_left" v-compile.stop="'left'"></li>
<li class="layout_btn_right" v-compile.stop="'right'"></li>
<li class="layout_rotote" v-rotote.stop='item'></li>
<li class="layout_rotote" v-rotote.stop='item' :style="{'transform':`translate(-50%, -50%) rotateZ(${item.angle}deg)`}"></li>
<li class="layout_translate" v-translate.stop></li>
<!-- <li class="layout_translate" v-translate.stop></li> -->
<li class="layout_angle_tr" v-angle.stop = "'top'"></li>
@@ -372,7 +372,7 @@ export default defineComponent({
mounted(el,item){
let mouse = true;
let angle :any = 0
let num:any
let num:any = 1
let x = 0
let y = 0
let elParent = el.parentNode.parentNode
@@ -391,6 +391,8 @@ export default defineComponent({
var info = el.getBoundingClientRect();
let eX = info.x + info.width / 2;
let eY = info.y + info.height / 2;
num = item.value.zoom?item.value.zoom :1
angle = item.value.angle?item.value.angle:0
let mouseMove = function(event:MouseEvent){
let e:any = getMousePosition(event,false)
mouseMoveOperation(e)
@@ -406,8 +408,7 @@ export default defineComponent({
let x:any = e.clientX - X
let y:any = Y - e.clientY
angle = Math.atan2(x,y)*(180 / Math.PI)
elParent.firstElementChild.style.transform = "translate(-50%,-50%) scale("+ num + ") rotateZ("+ angle + "deg)"
el.style.transform = "translate(-50%,-50%) rotateZ("+ angle + "deg)"
item.value.angle = angle
}
};
@@ -432,25 +433,9 @@ export default defineComponent({
let timeSwitch = true
el.parentNode.addEventListener('mousemove', (e:MouseEvent) => {
el.parentNode.addEventListener('mousewheel',(e:MouseEvent) => {
if(document.defaultView){
let transform = document.defaultView.getComputedStyle(elParent.firstElementChild, null).transform.split('(')[1].split(',')
num = Number(transform[3])
}
num = item.value.zoom?item.value.zoom :1
angle = item.value.angle?item.value.angle:0
if(timeSwitch){
if(angle == 0){
function getRotationAngle(transformDom:any) {
if (!transformDom || transformDom === 'none') return null;
let transform = window.getComputedStyle(transformDom).transform;
const values = transform?.match(/matrix\(([^)]+)\)/);
if (values) {
const matrix = values[1].split(',').map(Number);
const angle = Math.atan2(matrix[1], matrix[0]) * (180 / Math.PI);
return angle >= 0 ? angle : angle + 360; // 确保角度为正值
}
return null;
}
angle = getRotationAngle(elParent.firstElementChild);
}
timeSwitch = false
if((e as WheelEvent).deltaY > 0){
if(num <= 1){
@@ -477,7 +462,6 @@ export default defineComponent({
let instance:any = item.instance
instance.moodItemScale = num * 100
item.value.zoom = num
elParent.firstElementChild.style.transform = "translate(-50%,-50%) scale("+ num + ") rotateZ("+ angle + "deg)"
}
});
});

View File

@@ -102,15 +102,14 @@
</div>
<div class="scaleImage_content_imgBox" :class="{active:isComparison}">
<img v-if="isComparison" :src="scaleImageList[scaleImageIndex]?.sourceUrl">
<img :src="scaleImageList[scaleImageIndex]?.imgUrl">
<generalMiniCanvas v-if="isCanvas" :imgUrl="scaleImageList[scaleImageIndex]?.imgUrl" @submitBase64Data="submitBase64Data"></generalMiniCanvas>
<img v-else :src="scaleImageList[scaleImageIndex]?.imgUrl">
<div class="img_operate_block" v-if="isLike">
<i v-if="!scaleImageList[scaleImageIndex]?.like" class="fi fi-rr-heart operate_icon" @click.stop="LikeFile(scaleImageList[scaleImageIndex],'like')"></i>
<i v-else class="fi fi-sr-heart operate_icon" :adminLike="!!scaleImageList[scaleImageIndex]?.like" @click.stop="LikeFile(scaleImageList[scaleImageIndex],'noLike')"></i>
</div>
</div>
</div>
<div class="scaleImage_nav" @keydown="handleKeyDown">
<div class="nav_left">
<i class="fi fi-rr-arrow-small-left" @click="lastStep()"></i>
@@ -124,18 +123,9 @@
<i class="fi fi-rr-arrow-small-right" @click.stop="nextStep()"></i>
</div>
</div>
<!-- <div>
<a-button type="primary" @click="() => setVisible(true)">show image preview</a-button>
<a-image
:width="200"
:style="{ display: 'none' }"
:preview="{
visible,
onVisibleChange: setVisible,
}"
src="https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png"
/>
</div> -->
<div class="mark_loading" v-show="loadingShow">
<a-spin size="large" />
</div>
</a-modal>
</template>
@@ -147,7 +137,9 @@ import { useStore } from "vuex";
import { downloadIamge } from "@/tool/util";
import { getCookie,setCookie } from "@/tool/cookie";
import generalMiniCanvas from "@/component/modules/generalMiniCanvas.vue";
export default defineComponent({
components:{generalMiniCanvas},
props:{
productData:{
type:Object,
@@ -156,7 +148,16 @@ export default defineComponent({
brightenValue:1,
upload:'',
},
}
},
isCanvas:{
type:Boolean,
default:false,
},
workspace:{
type:Object,
default:{
}
},
},
setup(props:any,{emit}) {
const store = useStore();
@@ -298,6 +299,27 @@ export default defineComponent({
});
}
}
let submitBase64Data = (rv:any)=>{
loadingShow.value = true
let data = {
"base64": rv,
"category": scaleImageList.value[scaleImageIndex.value]?.categoryValue,
"gender": props.workspace.sexEnum.value,
}
Https.axiosPost(Https.httpUrls.modifySketch, data).then(
(rv) => {
rv.imgUrl = rv.url
rv.status = 'Success'
rv.category = scaleImageList.value[scaleImageIndex.value]?.category
rv.categoryValue = scaleImageList.value[scaleImageIndex.value]?.categoryValue
delete rv.url
scaleImageList.value.unshift(rv)
loadingShow.value = false
}
).catch(res=>{
loadingShow.value = false
});
}
return {
...toRefs(productimg),
scaleImage,
@@ -313,6 +335,7 @@ export default defineComponent({
robotAssits,
getPrductimg,
removeProductimg,
submitBase64Data,
};
},
data() {
@@ -447,6 +470,7 @@ export default defineComponent({
display: flex;
align-items: center;
justify-content: center;
z-index: 2;
.operate_icon{
font-size: 1.8rem;
color: #fff;
@@ -464,7 +488,7 @@ export default defineComponent({
}
.scaleImage_content:hover{
.scaleImage_content_imgBox:hover{
.img_operate_block{
opacity: 1;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,511 @@
<template>
<div class="generalMiniCanvas">
<div class="addDetails_canvasCenter">
<div class="generalMiniCanvas_btn generalMiniCanvas_item" :class="{spread:spreadState}">
<!-- <div @click="setOperation('')" class="generalMiniCanvas_btn_item">
<div>新增</div>
</div> -->
<i class="icon iconfont icon-chehui" @click="historyState('')"></i>
<i class="icon iconfont icon-fanchehui" @click="historyState('reverse')"></i>
<i class="icon iconfont icon-move" @click="setOperation('move')" :class="{active:canvasState == 'move'}"></i>
<i class="icon iconfont icon-bianji" @click="setOperation('pencil')" :class="{active:canvasState == 'pencil'}"></i>
<i class="icon iconfont icon-xiangpi_huaban1" @click="setOperation('eraser')" :class="{active:canvasState == 'eraser'}"></i>
<input type="range" v-show="canvasState != 'move'" @input="setPencilWidth" min="1" max="50" v-model="canvasPencilWidth[canvasState]">
<!-- <div class="icon iconfont icon-xiala" :class="{btnRotate:spreadState}" @click="()=>spreadState = !spreadState"></div> -->
</div>
<div class="exportCanvasBox_center_box">
<div class="exportCanvasBox_center">
<!-- <div class="editFrontBack_bgImg" v-show="loadingShow">
<img :src="imgData?.undividedLayer" alt="">
</div> -->
</div>
<div class="editFrontBack_pencilbtn" v-show="loadingShow" :style="pencilbtnStyle"></div>
</div>
</div>
<div class="exportCanvasBox_submit" @click="setSubmit">
<div class="started_btn">
{{ $t('addDetails.submit') }}
</div>
</div>
</div>
</template>
<script>
import { defineComponent, ref, reactive, watch, onMounted, nextTick, toRefs } from "vue";
import { Https } from "@/tool/https";
import { formatTime } from "@/tool/util";
import { setCookie, getCookie } from "@/tool/cookie";
import { Modal, message } from "ant-design-vue";
import { ExclamationCircleOutlined } from "@ant-design/icons-vue";
import allOrder from "@/component/Pay/allOrder.vue";
import creditsDetail from "@/component/Pay/creditsDetail.vue";
import { exportSele,JSRectUpdata,JSchangeType,JScanvasMouseDown,JSSetRemoveImage,JScreateCheck,JSSetTexture } from "@/tool/canvasDrawing";
import { useI18n } from "vue-i18n";
import canvasGeneral from "@/tool/canvasGeneral";
import { getMousePosition } from "@/tool/mdEvent";
export default defineComponent({
components: {
creditsDetail,
allOrder,
},
emits: ['submitBase64Data'],
props: {
imgUrl: {
type: String,
default: ''
},
},
// watch: {
// // imgUrl: function(newVal, oldVal) {
// // console.log(newVal);
// // // 当propertyName数据发生变化时执行相应的操作
// // }
// imgUrl(newVal, oldVal) {
// console.log(`imgUrl changed from ${oldVal} to ${newVal}`);
// },
// },
setup(props,{emit}) {
let presentState = ref('paypal');
let showPayOrder = ref(false);
let loadingShow = ref(false);
let { t } = useI18n();
let canvas = reactive({});
let scale = 2;
let ratio = [1,1]
let exportWH = 512
let pencilbtnStyle = ref({
background:'',
width:0+'px',
height:0+'px',
display:'none',
left:0+'px',
top:0+'px',
})
let canvasBtn = reactive({
canvasState:'move',
canvasPencilWidth:{
pencil:4,
eraser:4,
},
spreadState:false,
})
let canvasWH = ref(0);
watch(
() => props.imgUrl,
(newValue, oldValue) => {
init()
})
onMounted(()=>{
init()
})
let reverseCanvasState = ref([])//存放canvas操作
let normalCanvasState = ref([])//存放canvas操作
let canvasState = ref()//存放canvas操作
let keyDown = []//监听键盘的 keydown 和 keyup 事件
let init = ()=>{
normalCanvasState.value = []
reverseCanvasState.value = []
showPayOrder.value = true;
ratio = [1,1]
nextTick(()=>{
let canvasBox = document.querySelector(".generalMiniCanvas .exportCanvasBox_center");
document.removeEventListener('mousemove', mouseMove);
document.removeEventListener('touchmove', touchmove);
let img = new Image();
img.onload = function(){
loadingShow.value = true
let height = canvasBox.offsetHeight;
canvasWH.value = height
// canvasBox.style.width = height+'px'
let wScale = 1
let hScale = 1
if(img.width>img.height){
hScale = img.height/img.width
exportWH = img.width
}else{
wScale = img.width/img.height
exportWH = img.height
}
ratio = [wScale,hScale]
canvas = canvasGeneral.canvasInit(canvasBox,{
width:canvasWH.value * wScale,
height:canvasWH.value * hScale,
})
scale = img.height/canvas.height
pencilbtnStyle.value.background = rgba
fabric.Object.prototype.cornerSize = 10
fabric.Object.prototype.transparentCorners = false
fabric.Image.fromURL(props.imgUrl, function(img) {
// 设置背景图对象的宽度和高度与 canvas 相同
img.scaleToWidth(canvas.width);
img.scaleToHeight(canvas.height);
img.set({
scaleX: canvas.width / img.width,
scaleY: canvas.height / img.height
});
// 将背景图添加到 canvas 的底层
canvas.setBackgroundImage(img, canvas.renderAll.bind(canvas));
if(!fabric.Object.prototype.controls.deleteControl){
JSSetRemoveImage(deleteObj)
}else{
fabric.Object.prototype.controls.deleteControl.mouseUpHandler = deleteObj
}
setPencilWidth()
updateCanvasState()
},{ crossOrigin: "Anonymous" });
// 鼠标抬起事件
canvas.on('mouse:up', function(event) {
if(canvasBtn.canvasState != 'move'){
updateCanvasState('mouseUp')
}
});
//画布上移动
document.addEventListener('mousemove', mouseMove);
document.addEventListener('touchmove', touchmove);
setOperation('pencil')
img.remove()
}
img.src = props.imgUrl
})
}
let canvasKeyDown = (event) => {
if(keyDown.indexOf(event.key)>-1){
}else{
keyDown.push(event.code)
if(keyDown.indexOf('ControlLeft') > -1 && keyDown.indexOf('KeyZ') > -1 && keyDown.indexOf('ShiftLeft') > -1){
historyState('reverse')
}else if(keyDown.indexOf('ControlLeft') > -1 && keyDown.indexOf('KeyZ') > -1){
historyState('')
}
}
}
let canvasKeyUp = (event) =>{
keyDown = keyDown.filter(function(item) {
return event.code !== item;
})
}
let clearCanvas = ()=>{
canvasBtn.canvasState = 'move'
canvasBtn.spreadState = false
document.removeEventListener("keydown", canvasKeyDown);
document.removeEventListener("keyup", canvasKeyUp);
}
let rgba = 'rgba(0, 0, 0, 1)'
let mouseMove = (event)=>{
let e = getMousePosition(event,false)
setCanvasMove(e)
}
let touchmove = (event)=>{
let e = getMousePosition(event,true)
setCanvasMove(e)
}
let setCanvasMove = (event)=>{
if(canvas.isDrawingMode){
canvas.setCursor('none');
}
let canvasCenterBox = document.querySelector(".generalMiniCanvas .exportCanvasBox_center_box");
if(!canvasCenterBox)return
let parentX = event.clientX - canvasCenterBox.getBoundingClientRect().left
let parentY = event.clientY - canvasCenterBox.getBoundingClientRect().top
pencilbtnStyle.value.left = parentX + "px"
pencilbtnStyle.value.top = parentY+'px'
}
let setOperation = (str)=>{
canvasBtn.canvasState = str
if(str == 'move'){
setMove()
pencilbtnStyle.value.display = `none`
}else if(str == 'pencil'){
setPencil()
pencilbtnStyle.value.display = `block`
}else if(str == 'eraser'){
setEraser()
pencilbtnStyle.value.display = `block`
}
}
let setMove = ()=>{
canvas.isDrawingMode = false
canvas.forEachObject((obj) =>obj.selectable = true);
}
let setPencil = ()=>{
canvas.isDrawingMode = true//开启绘画模式
canvas.freeDrawingBrush = new fabric.PencilBrush(canvas,{});
canvas.freeDrawingBrush.width = Number(canvasBtn.canvasPencilWidth[canvasBtn.canvasState]);
canvas.freeDrawingBrush.color = rgba
pencilbtnStyle.value.background = rgba
canvas.freeDrawingBrush.isEraser = false
setPencilWidth()
}
let setEraser = ()=>{
canvas.isDrawingMode = true
let eraser = new fabric.EraserBrush(canvas)
canvas.freeDrawingBrush = eraser
canvas.requestRenderAll();
canvas.freeDrawingBrush.isEraser = true
pencilbtnStyle.value.background = `rgb(255,255,255)`
canvas.freeDrawingBrush.width = Number(canvasBtn.canvasPencilWidth[canvasBtn.canvasState]);
setPencilWidth()
}
let deleteObj = ()=> {
// if(!canvas.getActiveObjects()){
// return
// }
let target = canvas.getActiveObjects()
target.forEach((item)=>{
canvas.fxRemove(item, {
onComplete(){
canvas.discardActiveObject(); // 丢弃当前选中的对象
canvas.renderAll(); // 重新渲染 Canvas
}
})
canvas.FX_DURATION = 300
})
}
let setTimeOutWidth
let setPencilWidth = ()=>{//切换颜色给铅笔设置颜色
clearTimeout(setTimeOutWidth)
setTimeOutWidth = setTimeout(()=>{
canvas.freeDrawingBrush.width = Number(canvasBtn.canvasPencilWidth[canvasBtn.canvasState])
pencilbtnStyle.value.height = canvasBtn.canvasPencilWidth[canvasBtn.canvasState]+'px'
pencilbtnStyle.value.width = canvasBtn.canvasPencilWidth[canvasBtn.canvasState]+'px'
},300)
}
let updateCanvasState = (str) =>{
if(str != 'mouseUp'){
}
const canvasAsJson = JSON.stringify(canvas.toJSON());
normalCanvasState.value.push(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);
}else{
return
}
canvas.loadFromJSON(canvasState.value, () => {});
}
let setSubmit = ()=>{
var allObjects = canvas.getObjects('path');
// if(allObjects.length == 0){
// return message.info(t('addDetails.jsContent1'))
// }
var canvasDom = document.createElement("canvas");
let exportCanvas = new fabric.Canvas(canvasDom, {
backgroundColor: "rgba(255, 255, 255,1)",
width: exportWH * ratio[0],
height: exportWH * ratio[1],
isDrawingMode: false, // 开启绘图模式
});
canvas.backgroundImage.clone((back)=>{
back.set({
scaleX:1,
scaleY:1,
left:back.left*scale,
top:back.top*scale ,
})
exportCanvas.backgroundImage = back
allObjects.forEach((item,index)=>{
// let obj = fabric.util.object.clone(item);
if(item.type == 'circle')return
let obj
item.clone((cloned)=>{
obj = cloned
})
obj.set(
{
scaleX:(item.scaleX?item.scaleX:1)*scale,
scaleY:(item.scaleY?item.scaleY:1)*scale,
left:item.left*scale,
top:item.top*scale,
}
)
exportCanvas.add(obj)
})
let data = exportCanvas.toDataURL('jpg')
cancelDsign()
clearCanvas()
emit('submitBase64Data',data)
})
}
let cancelDsign = ()=>{
document.removeEventListener('keydown',canvasKeyDown);
document.removeEventListener('keyup', canvasKeyUp);
showPayOrder.value = false
}
return {
presentState,
showPayOrder,
loadingShow,
t,
pencilbtnStyle,
...toRefs(canvasBtn),
init,
setOperation,
setPencilWidth,
historyState,
setSubmit,
cancelDsign,
};
},
data() {
return {
};
},
mounted() {},
methods: {
},
});
</script>
<style lang="less">
.generalMiniCanvas{
position: relative;
// width: calc(512px / 2);
// width: 256px;
height: 100%;
display: flex;
flex-direction: column;
// height: calc(512px / 2);
margin: 0 auto;
.generalMiniCanvas_item{
// position: relative;
background: #fff;
position: absolute;
display: flex;
border: 0.2rem solid #c4c4c4;
width: 25rem;
border-radius: 4px; /* 设置圆角半径 */
flex-wrap: wrap;
.generalMiniCanvas_btn_item{
display: flex;
align-items: center;
padding: 1rem 0;
}
}
.generalMiniCanvas_btn{
z-index: 2;
// left: 50%;
min-width: 45rem;
// transform: translate(-50%,-135%);
// transition: all .3s;
padding: 1rem 1.5rem;
// transform: translate(-50%,0);
position: relative;
width: 100%;
flex-direction: row;
input{
// width: 100%;
// margin-top: 1rem;
flex: 1;
}
.icon-xiala{
position: absolute;
width: 2rem;
bottom: 0;
transform: translate(-50%, 90%);
left: 50%;
width: 6rem;
background: #fff;
text-align: center;
cursor: pointer;
&.icon-xiala::before{
transition: all .3s;
}
&.btnRotate::before{
transform: rotate(180deg);
display: block;
}
}
i{
font-size: 2.5rem;
cursor: pointer;
width: 4rem;
height: 4rem;
display: flex;
align-items: center;
justify-content: center;
&.active{
border: 1px solid;
border-radius: .4rem;
}
}
&.spread{
transform: translate(-50%,0);
}
}
.addDetails_canvasCenter{
flex: 1;
overflow: hidden;
display: flex;
flex-direction: column;
position: relative;
margin: 0 auto;
}
.exportCanvasBox_center_box{
padding: 3rem;
height: 100%;
flex: 1;
position: relative;
width: 100%;
background: #e6e6e6;
&:hover{
cursor: none;
}
.editFrontBack_pencilbtn{
position: absolute;
z-index: 1;
border-radius: 50%;
border: 1px solid #000;
pointer-events: none;
transform: translate(-50%,-50%);
}
}
.exportCanvasBox_center{
height: 100%;
flex: 1;
position: relative;
overflow: hidden;
background: #e6e6e6;
// overflow: scroll;
.canvas-container{
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
}
.editFrontBack_pencilbtn{
position: absolute;
z-index: 1;
border-radius: 50%;
border: 1px solid #000;
pointer-events: none;
transform: translate(-50%,-50%);
}
}
.exportCanvasBox_center:hover{
.generalMiniCanvas_btn{
// transform: translate(-50%,-101%);
// &.spread{
// transform: translate(-50%,0);
// }
}
}
}
.exportCanvasBox_submit{
margin-top: 1rem;
text-align: center;
}
</style>

View File

@@ -0,0 +1,284 @@
<template>
<a-modal
class="liquefaction generalModel"
v-model:visible="liqufeaction"
:footer="null"
width="50%"
:maskClosable="false"
:centered="true"
:closable="false"
wrapClassName="#app"
:keyboard="false"
>
<div class="generalModel_btn">
<div class="generalModel_closeIcon" @click.stop="cancelDsign()">
<i class="fi fi-rr-cross-small"></i>
</div>
</div>
<div class="liquefaction_center">
</div>
</a-modal>
<!-- <div class="mark_loading" v-show="loadingShow">
<a-spin size="large" />
</div> -->
</template>
<script>
import { defineComponent, ref, reactive, watch, onMounted, nextTick, toRefs } from "vue";
import { Https } from "@/tool/https";
import { formatTime } from "@/tool/util";
import { setCookie, getCookie } from "@/tool/cookie";
import { Modal, message } from "ant-design-vue";
import { ExclamationCircleOutlined } from "@ant-design/icons-vue";
import allOrder from "@/component/Pay/allOrder.vue";
import creditsDetail from "@/component/Pay/creditsDetail.vue";
import { exportSele,JSRectUpdata,JSchangeType,JScanvasMouseDown,JSSetRemoveImage,JScreateCheck,JSSetTexture } from "@/tool/canvasDrawing";
import { useI18n } from "vue-i18n";
import { getMousePosition } from "@/tool/mdEvent";
export default defineComponent({
components: {
creditsDetail,
allOrder,
},
emits: ['setSloganData'],
setup(props,{emit}) {
let presentState = ref('paypal');
let liqufeaction = ref(false);
let loadingShow = ref(false);
let { t } = useI18n();
let canvas = reactive({});
let scale = 2;
let ratio = [1,1]
let exportWH = 512
let pencilbtnStyle = ref({
background:'',
width:0+'px',
height:0+'px',
display:'none',
left:0+'px',
top:0+'px',
})
let canvasBtn = reactive({
canvasState:'move',
canvasPencilWidth:{
pencil:4,
eraser:4,
},
spreadState:false,
})
let canvasWH = ref(0);
onMounted(()=>{
})
let exportUrl = ''
let reverseCanvasState = ref([])//存放canvas操作
let normalCanvasState = ref([])//存放canvas操作
let canvasState = ref()//存放canvas操作
let keyDown = []//监听键盘的 keydown 和 keyup 事件
let init = (data)=>{
console.log(data);
console.log(123);
}
let canvasKeyDown = (event) => {
if(keyDown.indexOf(event.key)>-1){
}else{
keyDown.push(event.code)
if(keyDown.indexOf('ControlLeft') > -1 && keyDown.indexOf('KeyZ') > -1 && keyDown.indexOf('ShiftLeft') > -1){
historyState('reverse')
}else if(keyDown.indexOf('ControlLeft') > -1 && keyDown.indexOf('KeyZ') > -1){
historyState('')
}
}
}
let canvasKeyUp = (event) =>{
keyDown = keyDown.filter(function(item) {
return event.code !== item;
})
}
let clearCanvas = ()=>{
canvasBtn.canvasState = 'move'
canvasBtn.spreadState = false
document.removeEventListener("keydown", canvasKeyDown);
document.removeEventListener("keyup", canvasKeyUp);
}
let rgba = 'rgba(0, 0, 0, 1)'
let mouseMove = (event)=>{
let e = getMousePosition(event,false)
setCanvasMove(e)
}
let touchmove = (event)=>{
let e = getMousePosition(event,true)
setCanvasMove(e)
}
let setCanvasMove = (event)=>{
if(canvas.isDrawingMode){
canvas.setCursor('none');
}
let canvasCenterBox = document.querySelector(".liquefaction .exportCanvasBox_center_box");
if(!canvasCenterBox)return
let parentX = event.clientX - canvasCenterBox.getBoundingClientRect().left
let parentY = event.clientY - canvasCenterBox.getBoundingClientRect().top
pencilbtnStyle.value.left = parentX + "px"
pencilbtnStyle.value.top = parentY+'px'
}
let setOperation = (str)=>{
canvasBtn.canvasState = str
if(str == 'move'){
setMove()
pencilbtnStyle.value.display = `none`
}else if(str == 'pencil'){
setPencil()
pencilbtnStyle.value.display = `block`
}else if(str == 'eraser'){
setEraser()
pencilbtnStyle.value.display = `block`
}
}
let setMove = ()=>{
canvas.isDrawingMode = false
canvas.forEachObject((obj) =>obj.selectable = true);
}
let setPencil = ()=>{
canvas.isDrawingMode = true//开启绘画模式
canvas.freeDrawingBrush = new fabric.PencilBrush(canvas,{});
canvas.freeDrawingBrush.width = Number(canvasBtn.canvasPencilWidth[canvasBtn.canvasState]);
canvas.freeDrawingBrush.color = rgba
pencilbtnStyle.value.background = rgba
canvas.freeDrawingBrush.isEraser = false
setPencilWidth()
}
let setEraser = ()=>{
canvas.isDrawingMode = true
let eraser = new fabric.EraserBrush(canvas)
canvas.freeDrawingBrush = eraser
canvas.requestRenderAll();
canvas.freeDrawingBrush.isEraser = true
pencilbtnStyle.value.background = `rgb(255,255,255)`
canvas.freeDrawingBrush.width = Number(canvasBtn.canvasPencilWidth[canvasBtn.canvasState]);
setPencilWidth()
}
let deleteObj = ()=> {
// if(!canvas.getActiveObjects()){
// return
// }
let target = canvas.getActiveObjects()
target.forEach((item)=>{
canvas.fxRemove(item, {
onComplete(){
canvas.discardActiveObject(); // 丢弃当前选中的对象
canvas.renderAll(); // 重新渲染 Canvas
}
})
canvas.FX_DURATION = 300
})
}
let setTimeOutWidth
let setPencilWidth = ()=>{//切换颜色给铅笔设置颜色
clearTimeout(setTimeOutWidth)
setTimeOutWidth = setTimeout(()=>{
canvas.freeDrawingBrush.width = Number(canvasBtn.canvasPencilWidth[canvasBtn.canvasState])
pencilbtnStyle.value.height = canvasBtn.canvasPencilWidth[canvasBtn.canvasState]+'px'
pencilbtnStyle.value.width = canvasBtn.canvasPencilWidth[canvasBtn.canvasState]+'px'
},300)
}
let updateCanvasState = (str) =>{
if(str != 'mouseUp'){
}
const canvasAsJson = JSON.stringify(canvas.toJSON());
normalCanvasState.value.push(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);
}else{
return
}
canvas.loadFromJSON(canvasState.value, () => {});
}
let setSubmit = ()=>{
var allObjects = canvas.getObjects('path');
// if(allObjects.length == 0){
// return message.info(t('addDetails.jsContent1'))
// }
var canvasDom = document.createElement("canvas");
let exportCanvas = new fabric.Canvas(canvasDom, {
backgroundColor: "rgba(255, 255, 255,1)",
width: exportWH * ratio[0],
height: exportWH * ratio[1],
isDrawingMode: false, // 开启绘图模式
});
canvas.backgroundImage.clone((back)=>{
back.set({
scaleX:1,
scaleY:1,
left:back.left*scale,
top:back.top*scale ,
})
exportCanvas.backgroundImage = back
allObjects.forEach((item,index)=>{
// let obj = fabric.util.object.clone(item);
if(item.type == 'circle')return
let obj
item.clone((cloned)=>{
obj = cloned
})
obj.set(
{
scaleX:(item.scaleX?item.scaleX:1)*scale,
scaleY:(item.scaleY?item.scaleY:1)*scale,
left:item.left*scale,
top:item.top*scale,
}
)
exportCanvas.add(obj)
})
let data = exportCanvas.toDataURL('jpg')
cancelDsign()
clearCanvas()
emit('setSloganData',data)
})
}
let cancelDsign = ()=>{
document.removeEventListener('keydown',canvasKeyDown);
document.removeEventListener('keyup', canvasKeyUp);
liqufeaction.value = false
}
return {
presentState,
liqufeaction,
loadingShow,
t,
pencilbtnStyle,
...toRefs(canvasBtn),
init,
setOperation,
setPencilWidth,
historyState,
setSubmit,
cancelDsign,
};
},
data() {
return {
};
},
mounted() {},
methods: {
},
});
</script>
<style lang="less" scoped>
.liquefaction {
}
</style>