This commit is contained in:
wzp 2024-05-01 22:53:52 +08:00
parent 01a35a2727
commit 15e87deba6
6 changed files with 74 additions and 40 deletions

View File

@ -22,7 +22,7 @@
}, },
"devDependencies": { "devDependencies": {
"@vitejs/plugin-vue": "^5.0.4", "@vitejs/plugin-vue": "^5.0.4",
"typescript": "^5.2.2", "typescript": "^5.4.5",
"unplugin-auto-import": "^0.17.5", "unplugin-auto-import": "^0.17.5",
"unplugin-vue-components": "^0.27.0", "unplugin-vue-components": "^0.27.0",
"vite": "^5.2.0", "vite": "^5.2.0",

Binary file not shown.

View File

@ -29,12 +29,14 @@
:value="item.value" :value="item.value"
/> />
</el-select> </el-select>
<el-button>1</el-button><el-button>2</el-button> <el-button style="margin: 0;">1</el-button>
<el-button style="margin: 0;">2</el-button>
</div> </div>
</div> </div>
<AtlasRenderCanvasRegion class="viewer" :debug="true" :premultiplied-alpha="false" :atlas="data" v-if="show"></AtlasRenderCanvasRegion> <AtlasRenderCanvasRegion class="viewer" :debug="true" :premultiplied-alpha="false" :atlas="data"
v-if="show" @edit="onEdit"></AtlasRenderCanvasRegion>
<div class="layer-right"> <div class="layer-right">
123
</div> </div>
</div> </div>
</div> </div>
@ -44,8 +46,11 @@
import AtlasRenderCanvasRegion from "./components/AtlasRenderCanvasRegion.vue"; import AtlasRenderCanvasRegion from "./components/AtlasRenderCanvasRegion.vue";
import AtlasRenderArgument from "./entities/AtlasRenderArgument.ts"; import AtlasRenderArgument from "./entities/AtlasRenderArgument.ts";
import {onMounted, ref} from "vue"; import {onMounted, ref} from "vue";
import {Skeleton} from "@esotericsoftware/spine-webgl";
import {RenderArgument} from "./entities/RenderArgument.ts";
const show = ref<boolean>(false); const show = ref<boolean>(false);
const data: AtlasRenderArgument[] = []; const data = ref<AtlasRenderArgument[]>([]);
const spineName = ref('ceshi'); const spineName = ref('ceshi');
const spineNameList = ref([ const spineNameList = ref([
{ {
@ -55,16 +60,16 @@ const spineNameList = ref([
{ {
value: 'ceshi1', value: 'ceshi1',
label: '测试1', label: '测试1',
},{ }, {
value: 'ceshi2', value: 'ceshi2',
label: '测试2', label: '测试2',
},{ }, {
value: 'ceshi3', value: 'ceshi3',
label: '测试3', label: '测试3',
},{ }, {
value: 'ceshi4', value: 'ceshi4',
label: '测试4', label: '测试4',
},{ }, {
value: 'ceshi5', value: 'ceshi5',
label: '测试5', label: '测试5',
}, },
@ -74,9 +79,21 @@ onMounted(async () => {
const jsonBlob = URL.createObjectURL(await json.blob()); const jsonBlob = URL.createObjectURL(await json.blob());
const atlas = await fetch("/nan/nan.atlas"); const atlas = await fetch("/nan/nan.atlas");
const atlasBlob = URL.createObjectURL(await atlas.blob()); const atlasBlob = URL.createObjectURL(await atlas.blob());
data.push({skel: jsonBlob, texture: atlasBlob, scale: 1, x: 0, y: 0, animation: "animation", edit: true, textureImage: {"nan.png": "/nan/nan.png"}}); data.value.push({
skel: jsonBlob,
texture: atlasBlob,
scale: 2.5,
x: 12,
y: 92,
animation: "animation",
edit: true,
textureImage: {"nan.png": "/nan/nan.png"}
});
show.value = true; show.value = true;
}) })
const onEdit = (skel: {skel: Skeleton, obj: RenderArgument}) => {
console.log(skel.skel.scaleX, skel.skel.x, skel.skel.y);
}
</script> </script>
<style scoped> <style scoped>
@ -84,23 +101,28 @@ onMounted(async () => {
display: grid; display: grid;
grid-template-rows: 2fr 48fr; grid-template-rows: 2fr 48fr;
} }
.menu { .menu {
background-color: darkgray; background-color: darkgray;
} }
.editor { .editor {
width: 100vw; width: 100vw;
height: 100vh; height: 100vh;
display: grid; display: grid;
grid-template-columns: 1.5fr 7fr 1.5fr; grid-template-columns: 1.5fr 7fr 1.5fr;
background: gray; background: gray;
justify-items: center;
} }
.viewer { .viewer {
width: 99%; width: 99%;
height: 99%; height: 99%;
} }
.layer-left { .layer-left {
width: 100%; width: 100%;
height:100%; height: 100%;
border-right: 2px dotted black; border-right: 2px dotted black;
} }
@ -109,12 +131,14 @@ onMounted(async () => {
height: 100%; height: 100%;
border-left: 2px dotted black; border-left: 2px dotted black;
} }
.menu { .menu {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
padding: 10px; padding: 10px;
} }
.select { .select {
display: flex; display: flex;
align-items: center; align-items: center;

View File

@ -9,25 +9,17 @@ import {
Shader, ShapeRenderer, Skeleton, SkeletonDebugRenderer, SkeletonJson, Shader, ShapeRenderer, Skeleton, SkeletonDebugRenderer, SkeletonJson,
SkeletonRenderer, Vector2 SkeletonRenderer, Vector2
} from "@esotericsoftware/spine-webgl"; } from "@esotericsoftware/spine-webgl";
import {RenderArgument} from "../entities/RenderArgument.ts";
type Props = { type Props = {
atlas: AtlasRenderArgument[], atlas: AtlasRenderArgument[],
premultipliedAlpha: boolean, premultipliedAlpha: boolean,
debug: boolean debug: boolean
} }
type Bound = {
width: number,
height: number, const props = defineProps<Props>();
x: number, const emit = defineEmits(['edit']);
y: number
}
type RenderArgument = {
skel: Skeleton,
state: AnimationState,
setupBound: Bound,
edit: boolean
}
const props = defineProps<Props>()
const mainCanvas = ref<HTMLCanvasElement>(); const mainCanvas = ref<HTMLCanvasElement>();
let mounted = false; let mounted = false;
@ -56,7 +48,7 @@ const rendererArguments = computed<RenderArgument[]>(() => {
const animationStateData = new AnimationStateData(skeletonData); const animationStateData = new AnimationStateData(skeletonData);
const animationState = new AnimationState(animationStateData); const animationState = new AnimationState(animationStateData);
animationState.setAnimation(0, argument.animation, true); animationState.setAnimation(0, argument.animation, true);
return {skel: skeleton, setupBound, state: animationState, edit: !!argument.edit}; return {skel: skeleton, setupBound, state: animationState, edit: !!argument.edit, originalRender: argument};
}) })
}) })
let timer = Date.now() / 1000; let timer = Date.now() / 1000;
@ -99,7 +91,7 @@ const initializationRender = () => {
mainCanvas.value.getContext("webgl"); mainCanvas.value.getContext("webgl");
} }
let viewport: {width: number, height: number} = {width: 0, height: 0}; let viewport: {width: number, height: number} = {width: 0, height: 0};
let selectSkel: Skeleton | null = null; let selectSkel: {skel: Skeleton, obj: RenderArgument} | null = null;
let isDragging: boolean = false; let isDragging: boolean = false;
const resize = () => { const resize = () => {
if (!mainCanvas.value){ if (!mainCanvas.value){
@ -241,7 +233,7 @@ const render = () => {
const yMax = Math.max(renderObj.setupBound.y + renderObj.setupBound.height, renderObj.setupBound.y); const yMax = Math.max(renderObj.setupBound.y + renderObj.setupBound.height, renderObj.setupBound.y);
if (mousePosition.x > xMin && mousePosition.x < xMax && mousePosition.y > yMin && mousePosition.y < yMax) { if (mousePosition.x > xMin && mousePosition.x < xMax && mousePosition.y > yMin && mousePosition.y < yMax) {
if (!hasTouched){ if (!hasTouched){
selectSkel = renderObj.skel; selectSkel = {skel: renderObj.skel, obj: renderObj};
webGlCtx.value.bindBuffer(webGlCtx.value.ARRAY_BUFFER, initBuffers(renderObj.setupBound.x,renderObj.setupBound.y,renderObj.setupBound.width,renderObj.setupBound.height, 0, 0, 0)); webGlCtx.value.bindBuffer(webGlCtx.value.ARRAY_BUFFER, initBuffers(renderObj.setupBound.x,renderObj.setupBound.y,renderObj.setupBound.width,renderObj.setupBound.height, 0, 0, 0));
webGlCtx.value.drawArrays(webGlCtx.value.LINE_LOOP, 0, 4); webGlCtx.value.drawArrays(webGlCtx.value.LINE_LOOP, 0, 4);
} }
@ -279,8 +271,9 @@ const mouseMove = (evt: MouseEvent) => {
const mX = evt.movementX; const mX = evt.movementX;
const mY = evt.movementY; const mY = evt.movementY;
if (selectSkel){ if (selectSkel){
selectSkel.x += mX * 2; selectSkel.skel.x += mX * 2;
selectSkel.y -= mY * 2; selectSkel.skel.y -= mY * 2;
emit("edit", selectSkel);
} }
} }
} }
@ -296,27 +289,28 @@ const wheel = (evt: WheelEvent) => {
evt.stopPropagation(); evt.stopPropagation();
if (selectSkel){ if (selectSkel){
const deltaScale = -evt.deltaY / 1000; const deltaScale = -evt.deltaY / 1000;
selectSkel.scaleX += deltaScale; selectSkel.skel.scaleX += deltaScale;
if (selectSkel.scaleX < 0.1){ if (selectSkel.skel.scaleX < 0.1){
selectSkel.scaleX = 0.1; selectSkel.skel.scaleX = 0.1;
} }
if (selectSkel.scaleX > 10){ if (selectSkel.skel.scaleX > 10){
selectSkel.scaleX = 10; selectSkel.skel.scaleX = 10;
} }
selectSkel.scaleY += deltaScale; selectSkel.skel.scaleY += deltaScale;
if (selectSkel.scaleY < 0.1){ if (selectSkel.skel.scaleY < 0.1){
selectSkel.scaleY = 0.1; selectSkel.skel.scaleY = 0.1;
} }
if (selectSkel.scaleY > 10){ if (selectSkel.skel.scaleY > 10){
selectSkel.scaleY = 10; selectSkel.skel.scaleY = 10;
} }
emit("edit", selectSkel);
} }
} }
} }
</script> </script>
<template> <template>
<canvas id="mainCanvas" ref="mainCanvas"></canvas> <canvas id="mainCanvas" ref="mainCanvas" v-once></canvas>
</template> </template>
<style scoped> <style scoped>

6
src/entities/Bound.ts Normal file
View File

@ -0,0 +1,6 @@
interface Bound {
width: number,
height: number,
x: number,
y: number
}

View File

@ -0,0 +1,10 @@
import {AnimationState, Skeleton} from "@esotericsoftware/spine-webgl";
import AtlasRenderArgument from "./AtlasRenderArgument.ts";
export interface RenderArgument {
skel: Skeleton,
state: AnimationState,
setupBound: Bound,
edit: boolean,
originalRender: AtlasRenderArgument,
}