Files
aida_front/src/component/Detail/model/modelPosition.vue
X1627315083 56916c8d10 fix
2026-02-02 10:31:37 +08:00

850 lines
41 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="molepositon" :class="{active:!imgDesignImg}">
<div class="designOpenrtion_imgMask" v-if="frontBack?.body?.path" :style="frontBack?.body?.style">
<div class="designOpenrtion_print" v-for="item,index in frontBack.back" :style="frontBack.front[index].style">
<img :style="item.imageUrl?'':'display:none;'" :src="item.imageUrl" alt="">
</div>
<img class="perview_img" @load="setPrintSize()" ref="detailBody" :key="designDetail.designItemId" :src="frontBack?.body?.path" :style="'width:'+ frontBack?.body?.layersObject?.[0].imageSize?.[0] +';height:' + frontBack?.body?.layersObject?.[0].imageSize?.[0] +';'">
<!-- <div class="detail_modal_item_front" ref="target" 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="detail_modal_item_front" :ref="el => { setElementRef(el, index) }" v-for="item,index in frontBack.front" :class="{'active':item.id == selectDetail?.id}" :style="{...item.style,transform:`rotate(${getTransformValues(item.style.transform)?.rotate}deg) scaleX(1) scaleY(1)`}">
<img :src="item.imageUrl" alt="" :style="{transform:`scaleX(${getTransformValues(item.style.transform).scaleX}) scaleY(${getTransformValues(item.style.transform).scaleY})`}">
</div>
<div ref="moveableContainer" class="moveableContainer"></div>
</div>
<div class="designOpenrtion_imgMask" v-if="!frontBack?.body?.path">
<div class="designOpenrtion_print">
<img v-if="frontBack.back?.[0].imageUrl" :src="frontBack.back?.[0].imageUrl" style="object-fit: cover;" alt="">
</div>
<div class="detail_modal_item_front" style="position: relative;">
<img :src="frontBack.front?.[0].imageUrl || selectDetail?.path" style="object-fit: cover;" alt="">
</div>
<!-- <img @load="setSelectSketch()" :src="designDetail?.currentFullBodyView || selectDetail?.undividedLayer" style="object-fit: cover;" alt=""> -->
</div>
</div>
<div class="molepositon imgDesignImg" :class="{active:imgDesignImg}">
<div class="designOpenrtion_imgMask" style="width: 100%;height: 100%;">
<div class="detail_modal_item_front">
<img
style="object-fit: cover;"
:style="observerWH.width > 0?{width:observerWH.width+'px',height:observerWH.height+'px'}:{width:'100%',height:'auto','object-fit': 'contain'}"
:src="designDetail.designItemUrl" alt="">
</div>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent,computed,inject,watch,nextTick,createVNode,toRefs, reactive, onUnmounted} from 'vue'
// import setDesignItem from '@/component/Detail/setDesignItem2.vue'
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { Https } from "@/tool/https";
import { useStore } from "vuex";
import { useI18n } from 'vue-i18n'
import { getMousePosition } from "@/tool/mdEvent";
import { KeyValueDB } from "@/tool/indexedDB";
import Vue3Moveable from 'vue3-moveable';
import Moveable from 'moveable';
import { parse } from 'vue/compiler-sfc';
import { scale } from 'echarts/types/src/scale/helper.js';
export default defineComponent({
components:{
},
props:{
imgDesignImg:{
default:false,
type:Boolean,
}
},
emits:['addSketch'],
setup(props,{emit}) {
const {t} = useI18n()
const store = useStore();
const detailData = reactive({
frontBack:computed(()=>store.state.DesignDetail.frontBack),
designDetail:computed(()=>store.state.DesignDetail.designDetail),
selectDetail:computed(()=>store.state.DesignDetail.selectDetail),
isEditPattern:inject('isEditPattern') as any,
singleOveral:inject('singleOveral') as any,
detailBody:null as any,
observer:null as any,
observerWH:{
width:0,
height:0,
},
})
const selectItem = reactive({
selectDetail:computed(()=>store.state.DesignDetail.selectDetail),
imgDomIndex:-1,
printZIndex:store.state.DesignDetail.printZIndex,
imgDom:null as any,
direction:'',
})
watch(()=>detailData.frontBack?.body?.path,(newVal)=>{
setPrintSize()
})
const setPrintSize = ()=>{
nextTick(()=>{
let sacle = 0
const img = new Image();
let dom = document.querySelector('.molepositon .perview_img') as any
if(!detailData.frontBack?.body?.path || !dom)return
img.onload = () => {
//监听模特图片宽度设置整体图片宽度
if (detailData.observer) {
detailData.observer.disconnect()
}
detailData.observerWH.width = dom.width
detailData.observerWH.height = dom.height
detailData.observer = new ResizeObserver((entries) => {
if(entries[0].contentRect.width == 0)return
detailData.observerWH.width = Math.floor(entries[0].contentRect.width)
detailData.observerWH.height = Math.floor(entries[0].contentRect.height)
})
detailData.observer.observe(dom)
if(detailData.designDetail.clothes.length == 0){
store.commit('DesignDetail/addDesignColthes')
emit('addSketch')
return
}
if(!detailData.selectDetail?.id){
let item = detailData.designDetail.clothes.reduce((max, current) => {
return current.priority > max.priority ? current : max;
});
store.commit('DesignDetail/setDesignColthes',item.id)
}
// resolve(img)
sacle = dom.parentNode.offsetWidth / img.width
detailData.frontBack.front.forEach((item:any,index:number) => {
for (const key in item.style) {
if(key == 'zIndex')return
let value = item.style[key]
if(typeof value !== 'number'){
value = value.replace('px','')
item.style[key] = value
}else{
item.style[key] = value*sacle+'px'
}
// item.style[key] = value*sacle+'px'
}
for (const key in detailData.frontBack.back[index].style) {
if(key == 'zIndex')return
if(key == 'transform')return
let value = detailData.frontBack.back[index].style[key]
if(typeof value !== 'number'){
value = value.replace('px','')
detailData.frontBack.back[index].style[key] = value
}else{
detailData.frontBack.back[index].style[key] = value*sacle+'px'
}
// detailData.frontBack.back[index].style[key] = value*sacle+'px'
}
});
setTimeout(() => {
initMoveableForSelected()
},500);
};
img.src = detailData.frontBack?.body?.path;
})
}
const getDetailListDom = reactive({
libraryList:null as any,
moveableContainer:null as any,//控件层
})
const elementRefs = ref([]) as any;
const moveableInstance = ref(null) as any;
const setElementRef = (el, index) => {
elementRefs.value[index] = el;
};
const updateRect = ()=>{
setTimeout(() => {
if(moveableInstance.value)moveableInstance.value.updateRect()
}, 200);
}
function getTransformValues(transformStr) {
let scaleX = 1;
let scaleY = 1;
let rotate = 0;
if (!transformStr || transformStr === 'none') {
return { scaleX, scaleY, rotate };
}
const scaleXMatch = transformStr.match(/scaleX\(([-\d.]+)\)/);
if (scaleXMatch) {
scaleX = parseFloat(scaleXMatch[1]);
}
const scaleYMatch = transformStr.match(/scaleY\(([-\d.]+)\)/);
if (scaleYMatch) {
scaleY = parseFloat(scaleYMatch[1]);
}
const rotateMatch = transformStr.match(/rotate\(([-\d.]+)(deg|rad)?\)/);
if (rotateMatch) {
rotate = parseFloat(rotateMatch[1]);
if (rotateMatch[2] === 'rad') {
rotate = rotate * (180 / Math.PI);
}
}
return { scaleX, scaleY, rotate };
}
const initMoveableForSelected = () => {
// 销毁旧的实例
if(selectItem.imgDomIndex == -1)return
if (moveableInstance.value) {
moveableInstance.value.destroy();
}
const selectedEl = elementRefs.value[selectItem.imgDomIndex];
if (!selectedEl) return;
if(!selectedEl.style.left)return
moveableInstance.value = new Moveable(getDetailListDom.moveableContainer, {
target: selectedEl,
draggable: true,
scalable: true,
rotatable: true,
keepRatio: false, // 等比缩放
snappable: true,
snapThreshold: 5,
edge: false,
});
const createCustomButtons = () => {
const flipX = document.createElement('div');
const flipY = document.createElement('div');
flipX.className = 'custom-btn';
flipX.innerHTML = `
<svg class="btn flip-x" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<mask id="mask0_2641_12523" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="-1" width="24" height="25">
<rect y="-0.00044632" width="23.3511" height="23.3511" fill="url(#pattern0_2641_12523)"/>
</mask>
<g mask="url(#mask0_2641_12523)">
<rect x="2.92188" y="2.91752" width="17.5133" height="17.5133" fill="#0090FF"/>
</g>
<defs>
<pattern id="pattern0_2641_12523" patternContentUnits="objectBoundingBox" width="1" height="1">
<use xlink:href="#image0_2641_12523" transform="scale(0.005)"/>
</pattern>
<image id="image0_2641_12523" width="200" height="200" preserveAspectRatio="none" xlink:href="data:image/png;base64,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"/>
</defs>
</svg>
`;
flipY.className = 'custom-btn';
flipY.innerHTML = `
<svg class="btn flip-y" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<mask id="mask0_2641_12520" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="-1" y="-1" width="25" height="25">
<rect width="23.3511" height="23.3511" transform="matrix(0 -1 -1 0 23.3511 23.3511)" fill="url(#pattern0_2641_12520)"/>
</mask>
<g mask="url(#mask0_2641_12520)">
<rect width="17.5133" height="17.5133" transform="matrix(0 -1 -1 0 20.4292 20.4331)" fill="#0090FF"/>
</g>
<defs>
<pattern id="pattern0_2641_12520" patternContentUnits="objectBoundingBox" width="1" height="1">
<use xlink:href="#image0_2641_12520" transform="scale(0.005)"/>
</pattern>
<image id="image0_2641_12520" width="200" height="200" preserveAspectRatio="none" xlink:href="data:image/png;base64,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"/>
</defs>
</svg>
`;
let moveableControlBox = getDetailListDom.moveableContainer.querySelector('.moveable-control-box')
// 添加到 Moveable 容器或目标元素
moveableControlBox.appendChild(flipX);
moveableControlBox.appendChild(flipY);
// 绑定事件
moveableControlBox.addEventListener('click', (e:any) => {
e.stopPropagation();
const btn = e.target.closest('.btn');
if (!btn) return;
handleCustomButtonClick(btn.className?.animVal);
});
};
const handleCustomButtonClick = (btnClass:any) => {
const frontStyle = detailData.frontBack.front[selectItem.imgDomIndex];
let transform = getTransformValues(frontStyle.style.transform)
switch (btnClass) {
case 'btn flip-x':
transform.scaleX = transform.scaleX == -1?1:-1
frontStyle.style.transform = `rotate(${transform.rotate}deg) scaleX(${transform.scaleX}) scaleY(${transform.scaleY})`;
break;
case 'btn flip-y':
transform.scaleY = transform.scaleY == -1?1:-1
frontStyle.style.transform = `rotate(${transform.rotate}deg) scaleX(${transform.scaleX}) scaleY(${transform.scaleY})`;
break;
}
};
const updateTransform = () => {
let leftClass = '.moveable-control-box .moveable-w'
let bottomClass = '.moveable-control-box .moveable-s'
const frontStyle = detailData.frontBack.front[selectItem.imgDomIndex];
let transform = getTransformValues(frontStyle.style.transform)
// leftClass = transform.scaleX == -1?'.moveable-control-box .moveable-e':leftClass
// bottomClass = transform.scaleY == -1?'.moveable-control-box .moveable-n':bottomClass
let customFlipX = getDetailListDom.moveableContainer.querySelector('.moveable-control-box .flip-x')
let customFlipY = getDetailListDom.moveableContainer.querySelector('.moveable-control-box .flip-y')
let leftBorder = getDetailListDom.moveableContainer.querySelector(leftClass)
let bottomBorder = getDetailListDom.moveableContainer.querySelector(bottomClass)
customFlipX.parentNode.style.transform = leftBorder.style.transform
customFlipY.parentNode.style.transform = bottomBorder.style.transform
}
createCustomButtons()
updateTransform()
let startPosition = {//记录初始位置
left: 0,
top: 0,
}
let startSize = {//记录初始缩放比例
width: 0,
height: 0,
}
moveableInstance.value.on('scaleStart', ({ target, direction }) => {
const frontStyle = detailData.frontBack.front[selectItem.imgDomIndex];
// let scaleX = frontStyle.style.transform.match(/scaleX\(([-\d.]+)\)/);
// let scaleY = frontStyle.style.transform.match(/scaleY\(([-\d.]+)\)/);
let scaleX = ['1','1']
let scaleY = ['1','1']
frontStyle.mirror = { x: scaleX[1] == '-1' ? true : false, y: scaleY[1] == '-1' ? true : false };
startSize.width = Number(parseInt(target.style.width))
startSize.height = Number(parseInt(target.style.height))
startPosition.left = Number(parseInt(target.style.left))
startPosition.top = Number(parseInt(target.style.top))
});
moveableInstance.value.on('rotateStart', ({ target, direction }) => {
const frontStyle = detailData.frontBack.front[selectItem.imgDomIndex];
// let scaleX = frontStyle.style.transform.match(/scaleX\(([-\d.]+)\)/);
// let scaleY = frontStyle.style.transform.match(/scaleY\(([-\d.]+)\)/);
let scaleX = ['1','1']
let scaleY = ['1','1']
frontStyle.mirror = { x: scaleX[1] == '-1' ? true : false, y: scaleY[1] == '-1' ? true : false };
});
moveableInstance.value.on('dragStart', ({ target, clientX, clientY }) => {
startPosition = {
left:parseFloat(selectedEl.style.left.replace('px','')) || 0,
top:parseFloat(selectedEl.style.top.replace('px','')) || 0,
}
});
// 拖拽
moveableInstance.value.on('drag', ({ target, beforeTranslate }) => {
let x = startPosition.left + beforeTranslate[0]
let y = startPosition.top + beforeTranslate[1]
detailData.frontBack.front[selectItem.imgDomIndex].style.left = x + 'px'
detailData.frontBack.front[selectItem.imgDomIndex].style.top = y + 'px'
});
const updateElementTransform = (element, rotateDeg = null) => {
const currentTransform = element.style?.transform || '';
const currentRotates = (currentTransform.match(/rotate[XYZ]?\([^)]+\)/g) || []);
const scaleXMatch = currentTransform.match(/scaleX\(([^)]+)\)/);
const scaleYMatch = currentTransform.match(/scaleY\(([^)]+)\)/);
// 移除所有需要单独处理的变换
let otherTransforms = currentTransform
.replace(/rotate[XYZ]?\([^)]+\)/g, '')
.replace(/scaleX\([^)]+\)/g, '')
.replace(/scaleY\([^)]+\)/g, '')
.replace(/\s+/g, ' ')
.trim();
const transforms = [];
// 处理旋转
if (rotateDeg !== null) {
transforms.push(`rotate(${rotateDeg}deg)`);
} else if (currentRotates.length > 0) {
transforms.push(...currentRotates);
}
// 处理scaleX
if (element.mirror && element.mirror.x) {
transforms.push('scaleX(-1)');
} else if (scaleXMatch) {
// 保留原有的scaleX
transforms.push(`scaleX(${scaleXMatch[1]})`);
}
// 处理scaleY
if (element.mirror && element.mirror.y) {
transforms.push('scaleY(-1)');
} else if (scaleYMatch) {
// 保留原有的scaleY
transforms.push(`scaleY(${scaleYMatch[1]})`);
}
// 添加其他变换
if (otherTransforms) {
transforms.push(otherTransforms);
}
element.style.transform = transforms.join(' ').trim();
};
moveableInstance.value.on('scale', (e) => {
var { target, delta, direction, dist} = e
// console.log('scaleStart', e);
const frontStyle = detailData.frontBack.front[selectItem.imgDomIndex];
// 清除可能存在的重复镜像变换
// updateElementTransform(frontStyle);
let width = startSize.width
let height = startSize.height
let left = startPosition.left;
let top = startPosition.top;
let rotation = 0;
const originalRatio = width / height;
if (frontStyle.style.transform) {
const match = frontStyle.style.transform.match(/rotate\(([-\d.]+)deg\)/);
if (match) rotation = parseFloat(match[1]);
}
const isDiagonal = Math.abs(direction[0]) === 1 && Math.abs(direction[1]) === 1;
const processAxis = (axis, val, distVal, dir, pos, keepRatio = false, otherAxisResult = null) => {
const mirrorKey = axis === 'width' ? 'x' : 'y';
const isWidth = axis === 'width';
let newVal = val * distVal;
if(newVal < 10) newVal = 10;
// 位置调整
const shouldMove = (!frontStyle.mirror[mirrorKey] && dir === -1) || (frontStyle.mirror[mirrorKey] && dir === 1);
// 保持宽高比
const adjustPos = shouldMove ? pos - (newVal - val) : pos;
return { newVal, adjustPos };
};
// 处理缩放
if (isDiagonal) {
const scale = (dist[0] < 0 && dist[1] < 0) ? -Math.sqrt(dist[0] * dist[1]) : Math.sqrt(dist[0] * dist[1]);
const widthResult = processAxis('width', width, scale, direction[0], left);
const heightResult = processAxis('height', height, scale, direction[1], top);
frontStyle.style.width = widthResult.newVal + 'px';
frontStyle.style.height = heightResult.newVal + 'px';
frontStyle.style.left = widthResult.adjustPos + 'px';
frontStyle.style.top = heightResult.adjustPos + 'px';
} else {
const widthResult = processAxis('width', width, dist[0], direction[0], left);
const heightResult = processAxis('height', height, dist[1], direction[1], top);
frontStyle.style.left = widthResult.adjustPos + 'px';
frontStyle.style.top = heightResult.adjustPos + 'px';
frontStyle.style.width = widthResult.newVal + 'px';
frontStyle.style.height = heightResult.newVal + 'px';
}
// 更新变换,确保正确的顺序
updateElementTransform(frontStyle);
//更新自定义按钮
updateTransform()
});
moveableInstance.value.on('rotate', ({ target, beforeRotate }) => {
let frontStyle = detailData.frontBack.front[selectItem.imgDomIndex];
// 获取当前旋转角度
const currentTransform = frontStyle.style?.transform || '';
const rotateMatch = currentTransform.match(/rotate\(([-\d.]+)deg\)/);
let currentAngle = 0;
if (rotateMatch && rotateMatch[1]) {
const parsed = parseFloat(rotateMatch[1]);
if (!isNaN(parsed)) {
currentAngle = parsed;
}
}
// 计算新角度
const newBeforeRotate = parseFloat(beforeRotate) || 0;
if (!window._lastRotateData) {
window._lastRotateData = {
beforeRotate: newBeforeRotate,
angle: currentAngle
};
}
const delta = newBeforeRotate - window._lastRotateData.beforeRotate;
let newAngle = window._lastRotateData.angle + delta;
// 规范化角度到 0-360 范围
newAngle = ((newAngle % 360) + 360) % 360;
window._lastRotateData.beforeRotate = newBeforeRotate;
window._lastRotateData.angle = newAngle;
// 更新元素变换
updateElementTransform(frontStyle, newAngle);
// 更新自定义按钮
updateTransform();
});
// 可选在rotateStart时重置
moveableInstance.value.on('rotateStart', () => {
window._lastRotateData = null;
});
// 调整大小
moveableInstance.value.on('resize', ({ target, width, height }) => {
// console.log(width, height)
// detailData.frontBack.front[selectItem.imgDomIndex].style.width = width
// detailData.frontBack.front[selectItem.imgDomIndex].style.height = height
});
moveableInstance.value.on('dragEnd', ({ target, clientX, clientY }) => {
startPosition = {
left:0,
top:0,
}
upDataDetail()
});
moveableInstance.value.on('scaleEnd', () => {
upDataDetail()
});
moveableInstance.value.on('rotateEnd', () => {
upDataDetail()
});
};
// watch(()=>selectItem.selectDetail,(newValue,oldValue)=>{
// if(!newValue && newValue?.id == oldValue?.id)return
// },{immediate: true,})
watch(()=>selectItem.selectDetail?.id,(newValue,oldValue)=>{
if(newValue){
selectItem.imgDomIndex = detailData.frontBack.front.findIndex((item:any)=>item.id == newValue)
setTimeout(()=>{
initMoveableForSelected()
},100)
}
},{immediate: true,})
watch(()=>detailData.frontBack.front.length,(newValue,oldValue)=>{
if(selectItem.selectDetail?.id)selectItem.imgDomIndex = detailData.frontBack.front.findIndex((item:any)=>item.id == selectItem.selectDetail?.id)
setTimeout(()=>{
initMoveableForSelected()
},100)
})
const setRevocation = async ()=>{
let frontBack = JSON.parse(JSON.stringify(detailData.frontBack))
let revocation:any = JSON.parse((await KeyValueDB.get("revocation") as any) || '[]')
revocation.push({designData:null,position:frontBack})
KeyValueDB.set('revocation', JSON.stringify(revocation));
}
const upDataDetail = async ()=>{
//同步到selectDetail数据中
// getDetailListData.designDetail
let {scale,offset,priority,transpose,rotate,position,imageSize} = await getSubmitData(selectItem.selectDetail)
selectItem.selectDetail.layersObject[0].scale = scale
selectItem.selectDetail.layersObject[1].scale = scale
selectItem.selectDetail.layersObject[0].offset = offset
selectItem.selectDetail.layersObject[1].offset = offset
selectItem.selectDetail.layersObject[0].priority = priority
selectItem.selectDetail.layersObject[1].priority = priority
selectItem.selectDetail.layersObject[0].rotate = rotate
selectItem.selectDetail.layersObject[1].rotate = rotate
selectItem.selectDetail.layersObject[0].transpose = transpose
selectItem.selectDetail.layersObject[1].transpose = transpose
selectItem.selectDetail.layersObject[0].position = position
selectItem.selectDetail.layersObject[1].position = position
selectItem.selectDetail.layersObject[0].imageSize = imageSize
selectItem.selectDetail.layersObject[1].imageSize = imageSize
setRevocation()
}
const sort = (arr:any)=>{
arr.sort((a:any, b:any) => {
var a_num = a.style.zIndex;
var b_num = b.style.zIndex;
return a_num - b_num;
});
return arr
}
const getSubmitData = async (value:any)=>{
let parentNode = document.getElementsByClassName('molepositon')[0].getElementsByClassName("designOpenrtion_imgMask")[0].getBoundingClientRect()
if(!detailData.frontBack?.body?.layersObject?.[0]?.imageSize){
return{
scale:value.layersObject[0].scale,
offset:value.layersObject[0].offset,
priority:value.layersObject[0].priority,
}
}
let ratio = detailData.frontBack.body.layersObject[0].imageSize[0]/parentNode.width
let scale = 0
let dom:any = document.querySelector('.molepositon .perview_img')
const img = new Image();
img.src = detailData.frontBack?.body?.path;
await new Promise<void>((resolve, reject) => {
img.onload = () => {
scale = dom.parentNode.offsetWidth / img.width
resolve()
};
})
// let arr:any = sort(detailData.frontBack.front)
let arr:any = sort(JSON.parse(JSON.stringify(detailData.frontBack.front)))
let num = 10
arr.forEach((item:any)=>{
item.priority = num++
})
let data:any = {
scale:null,
offset:null,
priority:'',
maskUrl:'',
maskMinioUrl:'',
position:null,
imageSize:null,
}
let state = false
for (let index = 0; index < arr.length; index++) {
if(value.id == arr[index].id){
state = true
let y = ((arr[index]?.style?.top.replace(/px/g,'')*ratio).toFixed(0) as any - arr[index]?.position[0])
let x = ((arr[index]?.style?.left.replace(/px/g,'')*ratio).toFixed(0) as any - arr[index]?.position[1])
let positionX = Number((arr[index]?.style?.left.replace(/px/g,'')/scale)).toFixed(2)
let positionY = Number((arr[index]?.style?.top.replace(/px/g,'')/scale)).toFixed(2)
let imageSizeW = Number((arr[index]?.style?.width.replace(/px/g,'')/scale)).toFixed(2)
let imageSizeH = Number((arr[index]?.style?.height.replace(/px/g,'')/scale)).toFixed(2)
let scaleWidth = arr[index]?.imageSize?Number(((arr[index]?.style?.width.replace(/px/g,'')*ratio)/(arr[index]?.imageSize[0]/arr[index].scale[0])).toFixed(2)):1
let scaleHeight = arr[index]?.imageSize?Number(((arr[index]?.style?.height.replace(/px/g,'')*ratio)/(arr[index]?.imageSize[1]/arr[index].scale[1])).toFixed(2)):1
// let widthScale = (arr[index].style.width.replace(/px/g,'')/arr[index].style.height.replace(/px/g,'')).toFixed(2)
let transformStr = arr[index]?.style?.transform
let scaleX = transformStr.match(/scaleX\(([-\d.]+)\)/)
let scaleY = transformStr.match(/scaleY\(([-\d.]+)\)/)
let rotate = transformStr.match(/rotate\(([-\d.]+)deg\)/);
data.transpose = [parseFloat(scaleX?.[1] || 1),parseFloat(scaleY?.[1] || 1)]
data.rotate = parseFloat(rotate?.[1] || 0)
data.scale = [scaleWidth,scaleHeight]
let top = y == 0 ? value.layersObject[0].offset[1]:y+value.layersObject[0].offset[1]
let left = x == 0 ? value.layersObject[0].offset[0]:x+value.layersObject[0].offset[0]
data.offset = [left?left:0,top?top:0]
data.position = [positionY,positionX]
data.imageSize = [imageSizeW,imageSizeH]
// data.offset = [left?left:0,top?top:0]
data.maskUrl = arr[index].maskUrl
data.maskMinioUrl = arr[index].maskMinioUrl
// data.priority = arr[index].style.zIndex
data.priority = arr[index].priority
arr[index].similarity = true
// item.offset = [(arr[index]?.style?.left.replace(/px/g,'')*ratio).toFixed(0),(i?.style?.top.replace(/px/g,'')*ratio).toFixed(0)]
break
}
}
if(!state){
data.scale = [1,1]
data.offset = [0,0]
data.priority = 10+arr.length
}
return data
}
const deleteNav = ()=>{
}
const updataPosition = ()=>{
let url = detailData.frontBack?.body?.path
let sacle = 0
const img = new Image();
img.onload = () => {
let dom:any = document.querySelector('.molepositon .perview_img')
// resolve(img)
sacle = dom.parentNode.offsetWidth / img.width
detailData.frontBack.front.forEach((item:any,index:number) => {
for (const key in item.style) {
if(key == 'zIndex')return
if(key == 'transform')return
item.style[key] = item.style[key]*sacle+'px'
}
for (const key in detailData.frontBack.back[index].style) {
if(key == 'zIndex')return
if(key == 'transform')return
detailData.frontBack.back[index].style[key] = detailData.frontBack.back[index].style[key]*sacle+'px'
}
});
};
img.src = url;
}
onUnmounted(()=>{
if (detailData.observer) {
detailData.observer.disconnect()
}
if (moveableInstance.value) {
moveableInstance.value.destroy();
}
})
return{
...toRefs(detailData),
...toRefs(selectItem),
...toRefs(getDetailListDom),
setElementRef,
setPrintSize,
deleteNav,
getSubmitData,
getMousePosition,
updataPosition,
updateRect,
initMoveableForSelected,
getTransformValues,
}
},
directives:{
detailBody:{
mounted (el,data:any) {
let sacle = 0
const img = new Image();
img.onload = () => {
// resolve(img)
sacle = el.parentNode.offsetWidth / img.width
data.instance.frontBack.front.forEach((item:any,index:number) => {
for (const key in item.style) {
if(key == 'zIndex')return
item.style[key] = item.style[key]*sacle+'px'
}
for (const key in data.instance.frontBack.back[index].style) {
if(key == 'zIndex')return
data.instance.frontBack.back[index].style[key] = data.instance.frontBack.back[index].style[key]*sacle+'px'
}
});
};
img.src = data.value;
},
updated (el,data:any) {
let sacle = 0
const img = new Image();
img.onload = () => {
// resolve(img)
sacle = el.parentNode.offsetWidth / img.width
data.instance.frontBack.front.forEach((item:any,index:number) => {
for (const key in item.style) {
if(key == 'zIndex')return
item.style[key] = item.style[key].replace(/px/g,'')*sacle+'px'
}
for (const key in data.instance.frontBack.back[index].style) {
if(key == 'zIndex')return
data.instance.frontBack.back[index].style[key] = data.instance.frontBack.back[index].style[key].replace(/px/g,'')*sacle+'px'
}
});
};
img.src = data.value;
}
}
},
provide() {
return {
}
},
})
</script>
<style lang="less" scoped>
.molepositon{
// width: 30rem;
// width: calc(66 * .470rem);
width: calc(66 * .457rem);
height: 66rem;
display: flex;
flex-direction: column;
// margin: auto 0;
// padding-top: 3rem;
position: relative;
display: none;
&.active{
display: flex;
z-index: 2;
align-items: center;
justify-content: center;
}
&.imgDesignImg{
> .designOpenrtion_imgMask{
.detail_modal_item_front{
display: flex;
align-items: center;
justify-content: center;
img{
// height: auto;
}
}
}
}
.moveableContainer{
:deep(.moveable-origin){
opacity: 0;
}
:deep(.moveable-control){
width: 1.4rem;
height: 1.4rem;
margin-top: -.7rem;
margin-left: -.7rem;
border-radius: 0;
background-color: #44aaff;
border: 2px solid #44aaff;
&.moveable-ne,&.moveable-se,&.moveable-sw,&.moveable-nw{
border: 2px solid #44aaff;
background-color: #ffff;
}
}
:deep(.custom-btn){
width: 2.8rem;
height: 2.8rem;
margin: .5rem;
border-radius: 50%;
position: absolute;
left: 0;
top: 0;
will-change: transform;
margin-left: -1.4rem;
margin-top: -1.4rem;
> svg{
cursor: pointer;
}
.flip-y{
transform: translateY(100%);
}
.flip-x{
transform: translateX(-100%);
}
}
:deep(.moveable-rotation-control){
border-radius: 50%;
}
}
> .designOpenrtion_imgMask{
width: auto;
height: auto;
position: relative;
// height: 100%;
display: flex;
align-items: center;
justify-content: center;
>img{
z-index: 2;
position: relative;
width: 100%;
height: auto;
// height: 100%;
// object-fit: contain;
}
>div{
position: absolute;
top: 0;
}
.detail_modal_item_front,.designOpenrtion_print{
z-index: 2;
height: 100%;
width: 100%;
pointer-events: none;
&.active{
pointer-events: auto;
}
img{
width: 100%;
// height: ;
height: 100%;
float: left;
user-select:none;
-webkit-user-drag: none;
}
.modal_imgItem{
position: absolute;
overflow: hidden;
top: 0;
}
}
.designOpenrtion_print{
z-index: 1 !important;
}
}
}
</style>