feat: 添加上传功能

This commit is contained in:
wzp 2024-05-19 00:07:44 +08:00
parent 6c6339c5b8
commit 30289d8ace
3 changed files with 86 additions and 18 deletions

View File

@ -54,14 +54,14 @@
</div>
</div>
<el-dialog v-model="showResourceManager" title="材质管理">
<ResourceManager />
<ResourceManager :resources="atlasResources" @add-atlas="addAtlasResource" />
</el-dialog>
</template>
<script setup lang="ts">
import AtlasRenderCanvasRegion from "./components/AtlasRenderCanvasRegion.vue";
import AtlasRenderArgument from "./entities/AtlasRenderArgument.ts";
import {onMounted, ref} from "vue";
import {computed, onMounted, ref} from "vue";
import {Skeleton} from "@esotericsoftware/spine-webgl";
import {RenderArgument} from "./entities/RenderArgument.ts";
import {ProjectData} from "./entities/ProjectData.ts";
@ -70,11 +70,14 @@ import 'element-plus/es/components/message-box/style/css'
import 'element-plus/es/components/message/style/css'
import {ElMessage, ElMessageBox} from "element-plus";
import ResourceManager from "./components/resources/ResourceManager.vue";
import {ResourceType} from "./entities/BaseResource.ts";
import {AtlasResource} from "./entities/resource/AtlasResource.ts";
const show = ref<boolean>(true);
const data = ref<AtlasRenderArgument[]>([]);
const showResourceManager = ref<boolean>(false);
const projectData = ref<ProjectData>({name: "未命名", resourceRequired: [], lastSave: new Date(), lastChange: new Date()});
const atlasResources = computed<AtlasResource>(() => projectData.value.resourceRequired.filter((e) => e.type === ResourceType.ATLAS));
onMounted(async () => {
})
const onEdit = (skel: {skel: Skeleton, obj: RenderArgument}) => {
@ -112,6 +115,9 @@ const renameProject = () => {
projectData.value.lastChange = new Date();
})
}
const addAtlasResource = (data: AtlasResource) => {
projectData.value.resourceRequired.push(data);
}
</script>
<style scoped>

View File

@ -1,28 +1,83 @@
<script setup lang="ts">
import {computed} from "vue";
import {computed, defineEmits, onMounted, onUnmounted, ref} from "vue";
import {AtlasResource} from "../../entities/resource/AtlasResource.ts";
import {TextureAtlas} from "@esotericsoftware/spine-core";
import {ResourceType} from "../../entities/BaseResource.ts";
const tableData = computed<unknown[]>(() => []);
const emit = defineEmits<{(e: 'addResource', resources: AtlasResource[])}>();
type UploadingImageData = {name: string, data?: File};
type UploadingAtlasData = {name: string, data: File, images: UploadingImageData[]};
const resourceData = ref<UploadingAtlasData[]>([]);
type TableShowData = {atlas: string, name: string, load?: boolean};
const tableData = computed<TableShowData[]>(() => {
const data: TableShowData[] = [];
resourceData.value.forEach((atlas) => {
atlas.images.forEach((image) => {
data.push({atlas: atlas.name, name: image.name, load: !!image.data});
});
});
return data;
});
const onImportAtlasFile = (evt: Event) => {
const target = evt.target;
if (target instanceof HTMLInputElement){
const files = target.files;
if (files){
for (let file of files) {
file.text().then((atlasText) => {
const textureAtlas = new TextureAtlas(atlasText);
const newImages: UploadingImageData[] = [];
for (let page of textureAtlas.pages) {
newImages.push({name: page.name});
}
resourceData.value.push({name: file.name, data: file, images: newImages});
});
}
target.value = "";
}
}
}
const onImportImage = (evt: Event, imageName: string, atlasName: string) => {
const target = evt.target;
if (target instanceof HTMLInputElement) {
const files = target.files;
if (files){
const file = files[0];
const imageAtlas = resourceData.value.find((e) => e.name === atlasName);
if (imageAtlas){
const image = imageAtlas.images.find((e) => e.name === imageName);
if (image){
image.data = file;
}
}
}
}
}
const importAtlas = () => {
const data = resourceData.value.map((e) => {
return {
name: e.name,
extend: ".atlas",
type: ResourceType.ATLAS,
data: e.data,
images: e.images.map((img) => {return {name: img.name, extend: ".png", type: ResourceType.IMAGE, data: img.data}})}
});
emit("addResource", data);
resourceData.value = [];
}
const onImportImage = (evt: Event, imageName: string, atlasName: string) => {
}
const canImportAtlas = computed<boolean>(() => true);
const canImportAtlas = computed<boolean>(() => tableData.value.filter((e) => !e.load).length === 0);
</script>
<template>
ATLAS文件<input type="file" multiple accept=".atlas" @change="onImportAtlasFile" />
<el-table :data="tableData" style="width: 100%">
<el-table-column prop="atlasName" label="ATLAS文件名称"></el-table-column>
<el-table-column prop="atlas" label="ATLAS文件名称"></el-table-column>
<el-table-column prop="name" label="名称"></el-table-column>
<el-table-column fixed="right" label="导入状态">
<template #default="data">
<el-text type="success" v-if="data.row.load">已导入</el-text>
<span v-else><el-text type="danger">未导入</el-text><input type="file" accept=".png" @change="(evt) => onImportImage(evt, data.row.name, data.row.atlasName)" /></span>
<span v-else><el-text type="danger">未导入</el-text><input type="file" accept=".png" @change="(evt) => onImportImage(evt, data.row.name, data.row.atlas)" /></span>
</template>
</el-table-column>
</el-table>

View File

@ -1,20 +1,27 @@
<script setup lang="ts">
import ImportResource from "./ImportResource.vue";
import {computed, ref} from "vue";
const emit = defineEmits<{addAtlas: [data: unknown]}>();
import {computed, defineEmits, defineProps, ref} from "vue";
import {AtlasResource} from "../../entities/resource/AtlasResource.ts";
const emit = defineEmits<{(e: 'addAtlas', data: AtlasResource): void}>();
const props = defineProps<{resources: AtlasResource[]}>();
const showImportResource = ref<boolean>(false);
const tableData = computed<unknown[]>(() => []);
type TableShowData = {name: string, imageNum: number};
const tableData = computed<TableShowData[]>(() => props.resources.map((e) => {return {name: e.name, imageNum: e.images.length}}));
const onAddResource = (res: AtlasResource[]) => {
res.forEach((e) => emit('addAtlas', e));
showImportResource.value = false;
}
</script>
<template>
<el-button @click="showImportResource = true">导入</el-button>
<el-table :data="tableData" style="width: 100%">
<el-table-column prop="name" label="名称" width="180" />
<el-table-column prop="data" :formatter="(row:unknown,col:unknown,cellValue: Blob) => cellValue.size" label="大小" width="180" />
<el-table-column prop="name" label="名称" />
<el-table-column prop="imageNum" label="页数量" />
</el-table>
<el-dialog v-model="showImportResource" title="导入材质">
<ImportResource />
<ImportResource @add-resource="onAddResource" />
</el-dialog>
</template>