mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2025-12-21 17:56:04 +08:00
139 lines
5.1 KiB
HTML
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> |