当前位置:网站首页>Parse PSD files and map them into components
Parse PSD files and map them into components
2022-04-23 06:50:00 【Time202051】
const comsData = ref([]);
const closed = () => {
comsData.value = [];
};
const menu = useMenuStore();
const frame = useFrameStore();
const psdFileRef = ref(null);
const psdFileHandler = e => {
loadingInstance.value = ElLoading.service({
// target: '#main'
// customClass: 'el-loading--custom',
background: 'rgba(0, 0, 0, 0.8)',
text: '',
});
const reader = new FileReader();
reader.onloadend = () => {
onDrop({
dataTransfer: {
files: [psdFileRef.value.files[0]] },
target: {
result: null,
},
})
};
reader.readAsText(psdFileRef.value.files[0], 'utf8');
loadingInstance.value.close();
};
var PSD = require('psd');
const onDragOver = e => {
e.stopPropagation();
e.preventDefault();
e.dataTransfer.dropEffect = 'copy';
};
const onDrop = e => {
repeatNumber++;
loadingInstance.value = ElLoading.service({
// target: '#main'
// customClass: 'el-loading--custom',
background: 'rgba(0, 0, 0, 0.8)',
text: '',
});
PSD.fromEvent(e).then(function (psd) {
const config = psd.tree().export();
const {
children } = config;
const {
width, height } = config.document; // Page width and height
// frame.center.height = height
// frame.center.width = width
dgc(children, psd.tree().children());
});
loadingInstance.value.close();
};
const dataURLtoBlob = dataurl => {
let arr = dataurl.split(','),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], {
type: mime });
};
let repeatNumber = 0; // The number of failed uploads of the same file
const loadingInstance = ref(null);
const dgc = (c, tree) => {
for (let i = 0; i < c.length; i++) {
const item = c[i];
const t = tree[i];
const {
visible, children, type } = item;
//children Exist or type==='group' Prove that there are children , Otherwise, it is available
if (visible && children) {
dgc(children, t.children());
} else if (visible) {
const {
name, text, width, height, bottom, left, top } = item;
if (text && width > 0 && height > 0) {
setCom(item, 'text');
} else if (width > 0 && height > 0) {
let file = new File([dataURLtoBlob(t.toPng().src)], `${
name || 'file'}.png`);
let formData = new FormData();
formData.append('file', file);
setCom(item, 'rect', formData);
// Mount the picture component
// t.toBase64();
// document.getElementById('image').appendChild(t.toPng());
}
}
}
console.log(' Current component 22', comsData.value);
};
// Map generation component
const setCom = async (item, comType, formData) => {
const {
name, text, width, height, bottom, left, top, type } = item;
const options = {
type: comType == 'text' ? 'text' : 'rect',
model: 'base',
style: {
left,
top,
'z-index': 100, // Give it casually , Click the OK button later to reset
},
};
if (comType == 'text') {
const {
value } = text;
const com = getInitialAttrs(options);
if (com) {
const {
model, type } = com;
com.vueData[`${
model}_${
type}`].gWidth = null;
com.vueData[`${
model}_${
type}`].gHeight = null;
com.vueData[`${
model}_${
type}`].text = value;
com.vueData[`${
model}_${
type}`].fontSize = text.font.sizes[0];
com.vueData[`${
model}_${
type}`].color = `rgba(${
text.font.colors[0]})`;
}
comsData.value.unshift(com);
} else if (comType == 'rect') {
const rectCom = getInitialAttrs(options);
// To upload pictures , And return the address
const url = await sendImage(formData)
.then(res => {
if (res.data.StatusCode == 200) {
return res.data.Data;
}
repeatNumber = 0;
})
.catch(err => {
if (repeatNumber < 5) {
setCom(item, comType, formData, index);
}
});
if (rectCom) {
const {
model, type } = rectCom;
rectCom.vueData[`${
model}_${
type}`].backgroundImage = url;
rectCom.vueData[`${
model}_${
type}`].gWidth = width;
rectCom.vueData[`${
model}_${
type}`].gHeight = height;
rectCom.vueData[`${
model}_${
type}`].urlPre = 'http://192.168.0.150:8008';
}
comsData.value.unshift(rectCom);
}
};
const sendImage = formData => {
const url = `${
domain.uploadUrl}${
uploadFile}`;
return axios({
method: 'post',
url,
data: formData,
headers: {
accesstoken: 'adcf40f89d4acd38bddb9',
app: 'cloudconfigure',
ext: '.png',
},
});
};
The original document
<template>
<el-dialog
v-model="state.dialogVisible"
:title="props.dialogType == 'new' ? ' New page ' : ' Edit page '"
width="400px"
custom-class="pageDialog_container"
:destroy-on-close="true"
:before-close="close"
@closed="closed"
>
<!-- custom-class="pageList_dialog" -->
<!-- :rules="rules" -->
<el-form ref="pageFromRef" :model="state.pageFrom" :rules="rules" label-width="100px">
<el-form-item label=" Page name " prop="name">
<el-input
v-model="state.pageFrom.name"
autocomplete="off"
placeholder=" Please enter the page name "
style="width: 250px"
/>
</el-form-item>
<el-form-item v-if="props.dialogType == 'new'" label=" Page type " prop="type">
<el-select v-model="state.pageFrom.type" placeholder=" Please select the page type " style="width: 250px">
<el-option
v-for="(item, index) in localPageList"
:value="item.value"
:label="item.label"
:key="item.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label=" Page permissions " prop="authority">
<el-select
v-model="state.pageFrom.authority"
placeholder=" Please select Page permission "
style="width: 250px"
>
<el-option
v-for="(item, i) in authorityList"
:key="i"
:value="item.value"
:label="item.label"
></el-option>
</el-select>
</el-form-item>
<el-form-item label=" The menu is hidden " v-show="!state.pageFrom.isShowMenuPage" prop="isHide">
<el-select
v-model="state.pageFrom.isHide"
placeholder=" Please choose whether to hide the menu bar "
style="width: 250px"
>
<el-option
v-for="item in menuStatus"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label=" Pop up theme " v-show="state.pageFrom.isShowMenuPage">
<el-select v-model="state.pageFrom.themeProDialog" style="width: 250px">
<el-option
v-for="(item, i) in themeList"
:key="i"
:value="item.value"
:label="item.label"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item v-if="props.dialogType == 'new'" label=" Window page ">
<el-switch
:disabled="dialogType == 'edit'"
v-model="state.pageFrom.isShowMenuPage"
></el-switch>
</el-form-item>
<el-form-item label=" analysis psd">
<div class="psdFile_container">
<el-icon class="hand_icon"><Plus /></el-icon>
<input
class="fileInput"
type="file"
ref="psdFileRef"
accept=".psd"
@change="psdFileHandler"
/>
</div>
</el-form-item>
</el-form>
<div class="dialog_footer flex_c">
<el-button type="primary" class="OKbtn" @click="confirmHandler"> determine </el-button>
<el-button class="cancelbtn" @click="cancelHandler"> Cancel </el-button>
</div>
</el-dialog>
</template>
<script setup>
import {
ref, onMounted, reactive, toRefs, nextTick } from 'vue';
import {
Plus } from '@element-plus/icons-vue';
import {
useMenuStore, useFrameStore } from '@/store';
import {
newPageList } from '@/hooks/useMouseMenu.js';
import {
getInitialAttrs } from '@/components/CenterEdit/hooks/useCompt/add.js';
import {
state as centerStore, setBodyVueMap, addPageCompt } from '@/hooks/useCenterHook.js';
import domain from '@/utils/http/domain.http.js';
import {
uploadFile } from '@/utils/http/api.http';
import axios from 'axios';
import {
ElMessage, ElLoading } from 'element-plus';
import {
maxZindex } from '@/components/CenterEdit/hooks/useCompt/index.js';
const comsData = ref([]);
const closed = () => {
comsData.value = [];
};
const menu = useMenuStore();
const frame = useFrameStore();
const psdFileRef = ref(null);
const psdFileHandler = e => {
loadingInstance.value = ElLoading.service({
// target: '#main'
// customClass: 'el-loading--custom',
background: 'rgba(0, 0, 0, 0.8)',
text: '',
});
const reader = new FileReader();
reader.onloadend = () => {
onDrop({
dataTransfer: {
files: [psdFileRef.value.files[0]] },
target: {
result: null,
},
})
};
reader.readAsText(psdFileRef.value.files[0], 'utf8');
loadingInstance.value.close();
};
var PSD = require('psd');
const onDragOver = e => {
e.stopPropagation();
e.preventDefault();
e.dataTransfer.dropEffect = 'copy';
};
const onDrop = e => {
repeatNumber++;
loadingInstance.value = ElLoading.service({
// target: '#main'
// customClass: 'el-loading--custom',
background: 'rgba(0, 0, 0, 0.8)',
text: '',
});
PSD.fromEvent(e).then(function (psd) {
const config = psd.tree().export();
const {
children } = config;
const {
width, height } = config.document; // Page width and height
// frame.center.height = height
// frame.center.width = width
dgc(children, psd.tree().children());
});
loadingInstance.value.close();
};
const dataURLtoBlob = dataurl => {
let arr = dataurl.split(','),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], {
type: mime });
};
let repeatNumber = 0; // The number of failed uploads of the same file
const loadingInstance = ref(null);
const dgc = (c, tree) => {
for (let i = 0; i < c.length; i++) {
const item = c[i];
const t = tree[i];
const {
visible, children, type } = item;
//children Exist or type==='group' Prove that there are children , Otherwise, it is available
if (visible && children) {
dgc(children, t.children());
} else if (visible) {
const {
name, text, width, height, bottom, left, top } = item;
if (text && width > 0 && height > 0) {
setCom(item, 'text');
} else if (width > 0 && height > 0) {
let file = new File([dataURLtoBlob(t.toPng().src)], `${
name || 'file'}.png`);
let formData = new FormData();
formData.append('file', file);
setCom(item, 'rect', formData);
// Mount the picture component
// t.toBase64();
// document.getElementById('image').appendChild(t.toPng());
}
}
}
console.log(' Current component 22', comsData.value);
};
// Map generation component
const setCom = async (item, comType, formData) => {
const {
name, text, width, height, bottom, left, top, type } = item;
const options = {
type: comType == 'text' ? 'text' : 'rect',
model: 'base',
style: {
left,
top,
'z-index': 100, // Give it casually , Click the OK button later to reset
},
};
if (comType == 'text') {
const {
value } = text;
const com = getInitialAttrs(options);
if (com) {
const {
model, type } = com;
com.vueData[`${
model}_${
type}`].gWidth = null;
com.vueData[`${
model}_${
type}`].gHeight = null;
com.vueData[`${
model}_${
type}`].text = value;
com.vueData[`${
model}_${
type}`].fontSize = text.font.sizes[0];
com.vueData[`${
model}_${
type}`].color = `rgba(${
text.font.colors[0]})`;
}
comsData.value.unshift(com);
} else if (comType == 'rect') {
const rectCom = getInitialAttrs(options);
// To upload pictures , And return the address
const url = await sendImage(formData)
.then(res => {
if (res.data.StatusCode == 200) {
return res.data.Data;
}
repeatNumber = 0;
})
.catch(err => {
if (repeatNumber < 5) {
setCom(item, comType, formData, index);
}
});
if (rectCom) {
const {
model, type } = rectCom;
rectCom.vueData[`${
model}_${
type}`].backgroundImage = url;
rectCom.vueData[`${
model}_${
type}`].gWidth = width;
rectCom.vueData[`${
model}_${
type}`].gHeight = height;
rectCom.vueData[`${
model}_${
type}`].urlPre = 'http://192.168.0.150:8008';
}
comsData.value.unshift(rectCom);
}
};
const sendImage = formData => {
const url = `${
domain.uploadUrl}${
uploadFile}`;
return axios({
method: 'post',
url,
data: formData,
headers: {
accesstoken: 'adcf40f89d4acd38bddb9',
app: 'cloudconfigure',
ext: '.png',
},
});
};
// const isActivePsd = e => {
// document.getElementById('dropzone').addEventListener('dragover', onDragOver, true);
// document.getElementById('dropzone').addEventListener('drop', onDrop, true);
// };
const localPageList = Object.freeze([
{
label: ' Single page ', value: 'opage' },
{
label: ' Multi page ', value: 'mpage' },
]);
const authorityList = Object.freeze([
{
label: ' Zero level authority ', value: 0 },
{
label: ' First level authority ', value: 1 },
{
label: ' Secondary authority ', value: 2 },
{
label: ' Three level authority ', value: 3 },
{
label: ' Four levels of authority ', value: 4 },
{
label: ' Five levels of authority ', value: 5 },
]);
const menuStatus = Object.freeze([
{
label: ' Show menu ',
value: '0',
},
{
label: ' The hidden menu ',
value: '1',
},
{
label: ' Full screen display ',
value: '2',
},
]);
const themeList = Object.freeze([
{
label: ' Theme 1 ', value: 'black' },
{
label: ' Topic 2 ', value: 'white' },
]);
const props = defineProps({
// Pop up type
dialogType: {
type: String,
default: 'new', //edit
},
// Edit menu data
pageItem: {
type: Object,
default: () => {
return {
name: '',
type: 'opage',
isHide: '0', // The menu is hidden
authority: 0, // Page permissions
isShowMenuPage: false, // Whether to show or hide the menu
themeProDialog: 'black', // The theme
size: 0,
};
},
},
});
const pageFromRef = ref(null);
const state = reactive({
dialogVisible: false,
pageFrom: {
name: '',
type: 'opage',
isHide: '0', // The menu is hidden
authority: 0, // Page permissions
isShowMenuPage: false, // Whether to show or hide the menu
themeProDialog: 'black', // The theme
size: 0,
},
});
// check
const validatePageName = (rule, value, callback) => {
const tempI = menu.pageList.findIndex(item => item.name == value);
if (value === '') {
callback(new Error(' Please enter the page name '));
} else if (tempI != -1) {
callback(new Error(' The page name cannot be repeated !'));
} else {
callback();
}
};
const rules = reactive({
name: [{
required: true, validator: validatePageName, trigger: 'blur' }],
type: [{
required: true, message: ' mandatory ', trigger: 'blur' }],
authority: [{
required: true, message: ' mandatory ', trigger: 'blur' }],
});
const createdPageList = data => {
const type = props.dialogType;
if (type == 'new') {
// New page
newPageList(state.pageFrom);
// Add the component
addPsdCom(state.pageFrom.id, comsData.value);
} else {
// Edit page
editPageList();
}
};
const addPsdCom = (id, datas) => {
const page = centerStore.pageData.find(item => item.id == id);
datas.forEach((item, index) => {
const {
model, type } = item;
item.vueData[`${
model}_${
type}`].gZindex = index + maxZindex.value;
setBodyVueMap(item);
});
page.pageCompts.push(...datas);
console.log(' The final centerStore', centerStore);
};
// Edit page
const editPageList = () => {
// Take out the change value and insert it into pageList term
menu.replacePageList(JSON.parse(JSON.stringify(state.pageFrom)));
};
// OK and Cancel buttons
const confirmHandler = () => {
if (!pageFromRef.value) return;
pageFromRef.value.validate(valid => {
if (valid) {
createdPageList(); // Data manipulation
cancelHandler(); // Pop up frame closing operation
} else {
return false;
}
});
};
const cancelHandler = () => {
close();
};
const resetPageForm = () => {
state.pageFrom = {
name: '',
type: 'opage',
isHide: '0', // The menu is hidden
authority: 0, // Page permissions
isShowMenuPage: false, // Whether to show or hide the menu
themeProDialog: 'black', // The theme
};
};
//open/close Expose it for
const open = () => {
state.dialogVisible = true;
};
const close = () => {
if (!pageFromRef.value) return;
pageFromRef.value.resetFields();
resetPageForm();
state.dialogVisible = false;
};
// Initialize pop-up data , Don't go props, The parent component also passes data
const initEditData = params => {
Object.assign(state.pageFrom, params);
};
defineExpose({
...toRefs(state),
open,
close,
initEditData,
});
</script>
<style lang="less">
.pageDialog_container {
.el-dialog__body {
padding: 15px;
}
.el-dialog__footer {
padding: 0 !important;
}
}
#dropzone {
margin-left: 20px;
height: 32px;
width: 190px;
border: 1px #ababab dashed;
box-sizing: border-box;
}
#dropzone p {
text-align: center;
line-height: 32px;
margin: 0;
padding: 0;
}
.psdFile_container {
border: 1px #ababab dashed;
width: 40px;
height: 20px;
position: relative;
.hand_icon {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
.fileInput {
width: 40px;
height: 20px;
opacity: 0;
}
}
</style>
版权声明
本文为[Time202051]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204230551593919.html
边栏推荐
猜你喜欢
随机推荐
查漏补缺(八)
查漏补缺(七)
欢迎使用Markdown编辑器
手动实现call,apply,bind函数
Detailed explanation and application principle of token
Detailed explanation and application of PN junction and diode principle
Krypton binary
导入文件时候 new FormData()
往String原型上封装一个时间戳转日期的方法
金额输入框,用于充值提现
千呼万唤始出来
1-4 NodeJS的安装之配置可执行脚本
【无标题】js中的类型判断
.Net Core 下使用 Quartz —— 【2】作业和触发器之初步了解作业
C# Task.Delay和Thread.Sleep的区别
Krypton zeal
写一个正则
出入库与库存系统的模型问题
2020 Jiangsu Collegiate Programming Contest-A.Array
Node的文件系统及Buffer概述