213 lines
5.1 KiB
Vue
213 lines
5.1 KiB
Vue
<template>
|
||
<div class="generalCanvas">
|
||
<div class="canvasBox" ref="canvasBox">
|
||
<editCanvas v-if="canvasLoad" :config="canvasConfig"
|
||
@canvasInit="canvasInit"
|
||
@changeCanvas="changeCanvas"
|
||
is-general
|
||
ref="editCanvas"></editCanvas>
|
||
</div>
|
||
<div class="btn">
|
||
<div class="gallery_btn" @click="canvasSave" style="width: min-content;margin-top: auto;">{{ $t('exportModel.Save') }}</div>
|
||
<div class="gallery_btn" @click="exportElement">{{ $t('exportModel.Export') }}</div>
|
||
</div>
|
||
|
||
<div class="mark_loading" v-show="isShowMark">
|
||
<a-spin size="large" />
|
||
</div>
|
||
</div>
|
||
</template>
|
||
<script>
|
||
import {defineComponent, toRefs, provide, h, ref, nextTick, onBeforeUnmount, reactive, onMounted,
|
||
} from "vue";
|
||
import {message} from 'ant-design-vue'
|
||
import { Https } from "@/tool/https";
|
||
import { useStore } from "vuex";
|
||
import { useI18n } from "vue-i18n";
|
||
import editCanvas from "@/component/Canvas/CanvasEditor/index.vue";
|
||
|
||
|
||
export default defineComponent({
|
||
components: {
|
||
editCanvas,
|
||
},
|
||
props:{
|
||
imgUrl:{
|
||
type:String,
|
||
default:''
|
||
},
|
||
source:{
|
||
type:String,
|
||
default:''
|
||
},
|
||
isSubmitCanvasJSON:{
|
||
type:Boolean,
|
||
default:false
|
||
}
|
||
},
|
||
emits:['submitBase64Data','canvasChangeGetJSON'],
|
||
setup(props,{emit}) {
|
||
const { t } = useI18n();
|
||
const store = useStore();
|
||
const isShowMark = ref(false)
|
||
const component = reactive({
|
||
})
|
||
const data = reactive({
|
||
canvasLoad:false,
|
||
canvasJSON:computed(()=>store.state.HomeStoreModule.canvasData.canvas),
|
||
canvasConfig:{
|
||
|
||
},
|
||
})
|
||
watch(()=>data.canvasJSON,(newVal)=>{
|
||
dataDom.editCanvas.loadJSON(newVal)
|
||
})
|
||
const dataDom = reactive({
|
||
editCanvas:null,
|
||
canvasBox:null,
|
||
})
|
||
const openSetData = ()=>{
|
||
data.canvasLoad = true
|
||
|
||
}
|
||
const canvasLoadAddImg = (url,id)=>{
|
||
dataDom.editCanvas.addImageToLayer(url,{layerId:dataDom.editCanvas.layers[0].id,imageMode:'contains',undoable:false})
|
||
}
|
||
const canvasInit = (value)=>{
|
||
if(!props.imgUrl)return
|
||
canvasLoadAddImg(props.imgUrl,value.layers.value[0].id)
|
||
}
|
||
const getCanvasData = ()=>{
|
||
|
||
return canvasExport
|
||
}
|
||
const canvasSave = ()=>{
|
||
if(props.isSubmitCanvasJSON){
|
||
emit('canvasChangeGetJSON',{canvasJSON:dataDom.editCanvas.getJSON(),submitDate:0})
|
||
}else{
|
||
// dataDom.editCanvas.exportImage({isContainBg:props.source == 'detail',isContainFixed:true}).then((rv)=>{
|
||
// emit('submitBase64Data',rv)
|
||
// })
|
||
dataDom.editCanvas.exportImage({isContainBg:true,isContainFixed:true,isCropByBg:true}).then((rv)=>{
|
||
emit('submitBase64Data',rv)
|
||
})
|
||
}
|
||
|
||
}
|
||
const exportElement = ()=>{
|
||
dataDom.editCanvas.exportImage({isContainBg:true,isContainFixed:false,isCropByBg:true}).then((rv)=>{
|
||
downloadBase64Image(rv,'canvas')
|
||
})
|
||
}
|
||
function downloadBase64Image(base64Data, filename) {
|
||
// 1. 提取MIME类型(自动处理各种Base64前缀)
|
||
const mimeMatch = base64Data.match(/^data:(.+?);base64,/);
|
||
if (!mimeMatch) {
|
||
console.error('Invalid Base64 data');
|
||
return;
|
||
}
|
||
// 2. 获取扩展名
|
||
const mimeType = mimeMatch[1];
|
||
const extension = mimeType.split('/')[1] || 'png';
|
||
|
||
// 3. 转换Base64为Blob
|
||
const byteString = atob(base64Data.split(',')[1]);
|
||
const ab = new ArrayBuffer(byteString.length);
|
||
const ia = new Uint8Array(ab);
|
||
for (let i = 0; i < byteString.length; i++) {
|
||
ia[i] = byteString.charCodeAt(i);
|
||
}
|
||
const blob = new Blob([ab], { type: mimeType });
|
||
const url = URL.createObjectURL(blob);
|
||
const a = document.createElement('a');
|
||
a.href = url;
|
||
a.download = `${filename}.${extension}`;
|
||
document.body.appendChild(a);
|
||
a.click();
|
||
setTimeout(() => {
|
||
document.body.removeChild(a);
|
||
URL.revokeObjectURL(url);
|
||
}, 100);
|
||
}
|
||
const changeCanvas = ()=>{
|
||
emit('canvasChangeGetJSON',{canvasJSON:dataDom.editCanvas.getJSON(),submitDate:5000})
|
||
}
|
||
onMounted(() => {
|
||
if(props.imgUrl){
|
||
let img = new Image()
|
||
img.onload = ()=>{
|
||
// let wH = [1,1]
|
||
// let domHeight = dataDom.canvasBox.offsetHeight - 200
|
||
// let imgHeight = img.height
|
||
// wH = [1,domHeight/imgHeight]
|
||
// data.canvasConfig.height = domHeight
|
||
// data.canvasConfig.width = wH[1] * img.width
|
||
data.canvasConfig.height = img.height
|
||
data.canvasConfig.width = img.width
|
||
data.canvasConfig.initZoom = true
|
||
|
||
data.canvasLoad = true
|
||
// setTimeout(()=>{
|
||
// canvasLoadAddImg()
|
||
// },3000)
|
||
}
|
||
img.src = props.imgUrl
|
||
}else{
|
||
data.canvasLoad = true
|
||
}
|
||
});
|
||
onBeforeUnmount(()=>{
|
||
data.canvasLoad = false
|
||
})
|
||
return {
|
||
...toRefs(data),
|
||
...toRefs(dataDom),
|
||
isShowMark,
|
||
canvasLoadAddImg,
|
||
getCanvasData,
|
||
canvasSave,
|
||
canvasInit,
|
||
exportElement,
|
||
changeCanvas,
|
||
};
|
||
},
|
||
data(prop) {
|
||
return {
|
||
};
|
||
},
|
||
computed: {
|
||
},
|
||
watch: {
|
||
|
||
},
|
||
mounted() {},
|
||
|
||
methods: {
|
||
|
||
},
|
||
});
|
||
</script>
|
||
<style lang="less" scoped>
|
||
.generalCanvas{
|
||
width: 100%;
|
||
height: 100%;
|
||
position: relative;
|
||
display: flex;
|
||
flex-direction: row;
|
||
overflow: hidden;
|
||
padding-top: 4rem;
|
||
> .canvasBox{
|
||
flex: 1;
|
||
position: relative;
|
||
}
|
||
> .btn{
|
||
margin-top: auto;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: flex-end;
|
||
> div{
|
||
margin-top: 1rem;
|
||
}
|
||
}
|
||
}
|
||
</style> |