Skip to content

Commit 8c6e825

Browse files
committed
[canvaskit] Add IK following example.
1 parent 32f43fb commit 8c6e825

File tree

3 files changed

+102
-1
lines changed

3 files changed

+102
-1
lines changed

spine-ts/index.html

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ <h1>spine-ts Examples</h1>
2525
<li><a href="/spine-canvaskit/example">Example</a></li>
2626
<li><a href="/spine-canvaskit/example/animation-state-events.html">Animation State Events</a></li>
2727
<li><a href="/spine-canvaskit/example/mix-and-match.html">Skins Mix &amp; Match</a></li>
28+
<li><a href="/spine-canvaskit/example/ik-following.html">IK Following</a></li>
2829
</ul>
2930
<li>Pixi</li>
3031
<ul>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
<!DOCTYPE html>
2+
<html>
3+
4+
<head>
5+
<meta charset="UTF-8">
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
7+
<link rel="stylesheet" href="../../index.css">
8+
<script src="https://unpkg.com/canvaskit-wasm@latest/bin/canvaskit.js"></script>
9+
<script src="../dist/iife/spine-canvaskit.js"></script>
10+
<style>
11+
* {
12+
margin: 0;
13+
padding: 0;
14+
}
15+
</style>
16+
</head>
17+
18+
<body class="p-4 flex flex-col items-center">
19+
<h1>IK Following</h1>
20+
<p class="mb-4">Click/touch to set the aim</p>
21+
<canvas id=foo width=600 height=400 style="margin: 0 auto;"></canvas>
22+
</body>
23+
24+
<script type="module">
25+
async function readFile(path) {
26+
const response = await fetch(path);
27+
if (!response.ok) throw new Error("Could not load file " + path);
28+
return await response.arrayBuffer();
29+
}
30+
31+
const ck = await CanvasKitInit();
32+
const surface = ck.MakeCanvasSurface('foo');
33+
34+
const atlas = await spine.loadTextureAtlas(ck, "assets/spineboy.atlas", readFile);
35+
const skeletonData = await spine.loadSkeletonData("assets/spineboy-pro.skel", atlas, readFile);
36+
const drawable = new spine.SkeletonDrawable(skeletonData);
37+
drawable.skeleton.scaleX = drawable.skeleton.scaleY = 0.5;
38+
drawable.skeleton.x = 100;
39+
drawable.skeleton.y = 380;
40+
41+
// Set the walk animation on track 0 and the aim animation on track 1
42+
drawable.animationState.setAnimation(0, "walk", true);
43+
drawable.animationState.setAnimation(1, "aim", true);
44+
45+
// Set up touch and mouse listeners on the canvas element
46+
// and set the touch/mouse coordinate on the aim bone
47+
const canvasElement = document.querySelector("#foo");
48+
let mouseDown = false;
49+
canvasElement.addEventListener("touchmove", (ev) => setCrosshairPosition(ev.changedTouches[0].clientX, ev.changedTouches[0].clientY));
50+
canvasElement.addEventListener("mousedown", (ev) => {
51+
mouseDown = true;
52+
setCrosshairPosition(ev.clientX, ev.clientY);
53+
});
54+
canvasElement.addEventListener("mouseup", () => mouseDown = false)
55+
canvasElement.addEventListener("mousemove", (ev) => {
56+
if (mouseDown) setCrosshairPosition(ev.clientX, ev.clientY);
57+
})
58+
59+
// Get the crosshair bone. We will adjust its position based on the
60+
// touch/mouse coordinates
61+
const crosshair = drawable.skeleton.findBone("crosshair");
62+
63+
// Sets the crosshair bone position based on the touch/mouse position
64+
const setCrosshairPosition = (touchX, touchY) => {
65+
const clientRect = canvasElement.getBoundingClientRect();
66+
let x = touchX - clientRect.left;
67+
let y = touchY - clientRect.top;
68+
console.log(`${x}, ${y}`);
69+
70+
// Transform the touch/mouse position to the crosshair
71+
// bone's parent bone coordinate system
72+
const parent = crosshair.parent;
73+
const parentPosition = new spine.Vector2(x, y);
74+
parent.worldToLocal(parentPosition)
75+
76+
// Set the position on the bone (relative to its parent bone)
77+
crosshair.x = parentPosition.x;
78+
crosshair.y = parentPosition.y;
79+
}
80+
81+
82+
const renderer = new spine.SkeletonRenderer(ck);
83+
let lastTime = performance.now();
84+
85+
function drawFrame(canvas) {
86+
canvas.clear(ck.Color(52, 52, 54, 1));
87+
88+
const now = performance.now();
89+
const deltaTime = (now - lastTime) / 1000;
90+
lastTime = now;
91+
92+
drawable.update(deltaTime);
93+
renderer.render(canvas, drawable);
94+
95+
surface.requestAnimationFrame(drawFrame);
96+
}
97+
surface.requestAnimationFrame(drawFrame);
98+
</script>
99+
100+
</html>

spine-ts/spine-canvaskit/example/mix-and-match.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ <h1>Skins Mix &amp; Match Example</h1>
5656

5757
// Set the skin and the skeleton to the setup pose
5858
drawable.skeleton.setSkin(skin);
59-
drawable.skeleton.setToSetupPose();
59+
drawable.skeleton.setSlotsToSetupPose();
6060

6161
const renderer = new spine.SkeletonRenderer(ck);
6262
let lastTime = performance.now();

0 commit comments

Comments
 (0)