2023-12-06 03:18:31 +01:00

139 lines
5.1 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<script src="../dist/iife/spine-webgl.js"></script>
<link rel="stylesheet" href="../../index.css">
<body>
<div class="overlay" style="user-select: none;">
<span>Drag anywhere</span>
<span id="fps"></span>
<button id="fullscreen" class="btn">Fullscreen</div>
</div>
<canvas id="canvas" style="position: absolute; width: 100%; height: 100vh;"></canvas>
<script>
class App {
constructor() {
this.skeleton = null;
this.animationState = null;
this.fps = document.body.querySelector("#fps");
const fsButton = document.body.querySelector("#fullscreen");
let fsEnabled = false;
fsButton.addEventListener("click", () => {
if (fsEnabled) {
document.exitFullscreen();
fsButton.innerText = "Fullscreen"
} else {
document.body.requestFullscreen()
fsButton.innerText = "Windowed";
}
fsEnabled = !fsEnabled;
})
}
loadAssets(canvas) {
// Load the skeleton file.
canvas.assetManager.loadBinary("assets/celestial-circus-pro.skel");
// Load the atlas and its pages.
canvas.assetManager.loadTextureAtlas("assets/celestial-circus-pma.atlas");
}
initialize(canvas) {
let assetManager = canvas.assetManager;
// Create the texture atlas.
var atlas = assetManager.require("assets/celestial-circus-pma.atlas");
// Create a AtlasAttachmentLoader that resolves region, mesh, boundingbox and path attachments
var atlasLoader = new spine.AtlasAttachmentLoader(atlas);
// Create a SkeletonBinary instance for parsing the .skel file.
var skeletonBinary = new spine.SkeletonBinary(atlasLoader);
// Set the scale to apply during parsing, parse the file, and create a new skeleton.
skeletonBinary.scale = 0.5;
var skeletonData = skeletonBinary.readSkeletonData(assetManager.require("assets/celestial-circus-pro.skel"));
this.skeleton = new spine.Skeleton(skeletonData);
// Create an AnimationState, and set the "run" animation in looping mode.
var animationStateData = new spine.AnimationStateData(skeletonData);
this.animationState = new spine.AnimationState(animationStateData);
this.animationState.setAnimation(0, "eyeblink-long", true);
// Center the camera on the skeleton
const offset = new spine.Vector2();
const size = new spine.Vector2();
this.skeleton.setToSetupPose();
this.skeleton.update(0);
this.skeleton.updateWorldTransform(spine.Physics.update);
this.skeleton.getBounds(offset, size);
canvas.renderer.camera.position.x = offset.x + size.x / 2;
canvas.renderer.camera.position.y = offset.y + size.y / 2;
// Setup an input listener on the canvas to process touch/mouse events. Allow drawing the skeleton around
// by clicking and dragging anywhere on the canvas.
let lastX = -1, lastY = -1;
canvas.input.addListener({
down: (x, y) => {
// Calculate the mouse position in the coordinate space of the camera, aka world space.
// The skeleton and its bones live in the same coordinate space.
let mousePosition = new spine.Vector3(x, y);
canvas.renderer.camera.screenToWorld(mousePosition, canvas.htmlCanvas.clientWidth, canvas.htmlCanvas.clientHeight);
lastX = mousePosition.x;
lastY = mousePosition.y;
},
dragged: (x, y) => {
// Calculate the mouse position in the coordinate space of the camera, aka world space.
// The skeleton and its bones live in this coordinate space.
let mousePosition = new spine.Vector3(x, y);
canvas.renderer.camera.screenToWorld(mousePosition, canvas.htmlCanvas.clientWidth, canvas.htmlCanvas.clientHeight);
this.skeleton.x += mousePosition.x - lastX;
this.skeleton.y += mousePosition.y - lastY;
lastX = mousePosition.x;
lastY = mousePosition.y;
}
})
}
update(canvas, delta) {
// Update the animation state using the delta time.
this.animationState.update(delta);
// Apply the animation state to the skeleton.
this.animationState.apply(this.skeleton);
// Let the skeleton update the transforms of its bones and apply physics
this.skeleton.update(delta);
this.skeleton.updateWorldTransform(spine.Physics.update);
this.fps.innerText = canvas.time.framesPerSecond.toFixed(2) + " fps";
}
render(canvas) {
let renderer = canvas.renderer;
// Resize the viewport to the full canvas.
renderer.resize(spine.ResizeMode.Expand);
// Clear the canvas with a light gray color.
canvas.clear(0.2, 0.2, 0.2, 1);
// Begin rendering.
renderer.begin();
// Draw the skeleton
renderer.drawSkeleton(this.skeleton, true);
// Complete rendering.
renderer.end();
}
}
new spine.SpineCanvas(document.getElementById("canvas"), {
app: new App()
})
</script>
</body>
</html>