103 lines
3.4 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="../../index.css">
<script src="https://unpkg.com/canvaskit-wasm@latest/bin/canvaskit.js"></script>
<script src="../dist/iife/spine-canvaskit.js"></script>
<style>
* {
margin: 0;
padding: 0;
}
</style>
</head>
<body class="p-4 flex flex-col items-center">
<h1>IK Following</h1>
<p class="mb-4">Drag anywhere</p>
<canvas id=foo style="margin: 0 auto; width: 600px; height: 400px;"></canvas>
</body>
<script type="module">
async function readFile(path) {
const response = await fetch(path);
if (!response.ok) throw new Error("Could not load file " + path);
return await response.arrayBuffer();
}
const canvasElement = document.querySelector("#foo");
const dpr = window.devicePixelRatio || 1;
canvasElement.width = canvasElement.clientWidth * dpr;
canvasElement.height = canvasElement.clientHeight * dpr;
const ck = await CanvasKitInit();
const surface = ck.MakeCanvasSurface('foo');
surface.getCanvas().scale(dpr, dpr);
const atlas = await spine.loadTextureAtlas(ck, "assets/celestial-circus.atlas", readFile);
const skeletonData = await spine.loadSkeletonData("assets/celestial-circus-pro.json", atlas, readFile);
const drawable = new spine.SkeletonDrawable(skeletonData);
drawable.skeleton.scaleX = drawable.skeleton.scaleY = 0.15;
drawable.skeleton.x = 300;
drawable.skeleton.y = 300;
// Set the blink animation on track 0
drawable.animationState.setAnimation(0, "eyeblink-long", true);
// Set up touch and mouse listeners on the canvas element
// and set the touch/mouse coordinate on the aim bone
let mouseDown = false;
let lastX = -1, lastY = -1;
canvasElement.addEventListener("touchmove", (ev) => drag(ev.changedTouches[0].clientX, ev.changedTouches[0].clientY));
canvasElement.addEventListener("mousedown", (ev) => {
mouseDown = true;
drag(ev.clientX, ev.clientY);
});
canvasElement.addEventListener("mouseup", () => {
mouseDown = false;
lastX = -1; lastY = -1;
})
canvasElement.addEventListener("mousemove", (ev) => {
if (mouseDown) drag(ev.clientX, ev.clientY);
})
// Move the skeleton around based on the distance between
// the last touch/mouse location and the current touch/mouse location.
const drag = (touchX, touchY) => {
const clientRect = canvasElement.getBoundingClientRect();
let x = touchX - clientRect.left;
let y = touchY - clientRect.top;
if (lastX == -1 && lastY == -1) {
lastX = x;
lastY = y;
return;
}
drawable.skeleton.x += (x - lastX);
drawable.skeleton.y += (y - lastY);
lastX = x;
lastY = y;
}
const renderer = new spine.SkeletonRenderer(ck);
let lastTime = performance.now();
function drawFrame(canvas) {
canvas.clear(ck.Color(52, 52, 54, 1));
const now = performance.now();
const deltaTime = (now - lastTime) / 1000;
lastTime = now;
drawable.update(deltaTime);
renderer.render(canvas, drawable);
surface.requestAnimationFrame(drawFrame);
}
surface.requestAnimationFrame(drawFrame);
</script>
</html>