mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-06 07:14:55 +08:00
[ts][webgl] Added example demonstrating how to drag bones. Closes #2151.
This commit is contained in:
parent
a64b79b498
commit
e01ba364df
@ -30,6 +30,7 @@
|
||||
<li><a href="/spine-webgl/example/mix-and-match.html">Mix & match</a></li>
|
||||
<li><a href="/spine-webgl/example/drag-and-drop.html">Drag & drop</a></li>
|
||||
<li><a href="/spine-webgl/example/dress-up.html">Dress-up</a></li>
|
||||
<li><a href="/spine-webgl/example/bone-dragging.html">Bone dragging</a></li>
|
||||
<li><a href="/spine-webgl/demos/additiveblending.html">Additive blending</a></li>
|
||||
<li><a href="/spine-webgl/demos/clipping.html">Clipping</a></li>
|
||||
<li><a href="/spine-webgl/demos/hoverboard.html">Hoverboard</a></li>
|
||||
|
||||
126
spine-ts/spine-webgl/example/bone-dragging.html
Normal file
126
spine-ts/spine-webgl/example/bone-dragging.html
Normal file
@ -0,0 +1,126 @@
|
||||
<html>
|
||||
<script src="../dist/iife/spine-webgl.js"></script>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
<body>
|
||||
<canvas id="canvas" style="position: absolute; width: 100%; height: 100%;"></canvas>
|
||||
<script>
|
||||
class App {
|
||||
constructor() {
|
||||
this.skeleton = null;
|
||||
this.animationState = null;
|
||||
this.draggableBones = [];
|
||||
this.draggedBone = null;
|
||||
}
|
||||
|
||||
loadAssets(canvas) {
|
||||
canvas.assetManager.loadBinary("assets/stretchyman-pro.skel");
|
||||
canvas.assetManager.loadTextureAtlas("assets/stretchyman-pma.atlas");
|
||||
}
|
||||
|
||||
initialize(canvas) {
|
||||
let assetManager = canvas.assetManager;
|
||||
var atlas = assetManager.require("assets/stretchyman-pma.atlas");
|
||||
var atlasLoader = new spine.AtlasAttachmentLoader(atlas);
|
||||
var skeletonBinary = new spine.SkeletonBinary(atlasLoader);
|
||||
skeletonBinary.scale = 1;
|
||||
var skeletonData = skeletonBinary.readSkeletonData(assetManager.require("assets/stretchyman-pro.skel"));
|
||||
this.skeleton = new spine.Skeleton(skeletonData);
|
||||
var animationStateData = new spine.AnimationStateData(skeletonData);
|
||||
this.animationState = new spine.AnimationState(animationStateData);
|
||||
|
||||
// Find the bones that should be draggable
|
||||
let draggableBoneNames = [
|
||||
"back-leg-ik-target",
|
||||
"front-leg-ik-target",
|
||||
"back-arm-ik-target",
|
||||
"front-arm-ik-target",
|
||||
"hip",
|
||||
"neck2"
|
||||
];
|
||||
for (let boneName of draggableBoneNames) {
|
||||
let bone = this.skeleton.findBone(boneName);
|
||||
if (bone == null) throw Error("Couldn't find bone " + boneName);
|
||||
this.draggableBones.push(bone)
|
||||
}
|
||||
|
||||
// Setup an input listener on the canvas to process touch/mouse events.
|
||||
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);
|
||||
|
||||
// Find the first bone within a radius of 20 pixels to the mouse position
|
||||
this.selectedBone = null;
|
||||
for (let bone of this.draggableBones) {
|
||||
if (mousePosition.distance(new spine.Vector3(bone.worldX, bone.worldY, 0)) < 20) {
|
||||
this.selectedBone = bone;
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
dragged: (x, y) => {
|
||||
// If no bone was selected, bail.
|
||||
if (this.selectedBone == null) return;
|
||||
|
||||
// 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);
|
||||
|
||||
if (this.selectedBone.parent != null) {
|
||||
// If the bone to be dragged has a parent, transform the mouse world position to
|
||||
// the parent bone's coordinate system, and set the bone's position accordingly.
|
||||
let position = new spine.Vector2(mousePosition.x, mousePosition.y);
|
||||
this.selectedBone.parent.worldToLocal(position);
|
||||
this.selectedBone.x = position.x;
|
||||
this.selectedBone.y = position.y;
|
||||
} else {
|
||||
// If the dragged bone has no parent, it's the root bone and we can simply set its
|
||||
// position to the mouse world position.
|
||||
this.selectedBone.x = mousePosition.x;
|
||||
this.selectedBone.y = mousePosition.y;
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
update(canvas, delta) {
|
||||
this.animationState.update(delta);
|
||||
this.animationState.apply(this.skeleton);
|
||||
this.skeleton.updateWorldTransform();
|
||||
}
|
||||
|
||||
render(canvas) {
|
||||
let renderer = canvas.renderer;
|
||||
renderer.resize(spine.ResizeMode.Expand);
|
||||
canvas.clear(0.2, 0.2, 0.2, 1);
|
||||
|
||||
renderer.begin();
|
||||
renderer.drawSkeleton(this.skeleton, true);
|
||||
|
||||
// Draw a circle with a radius of 20 pixels around each draggable bone
|
||||
let boneColor = new spine.Color(1, 0, 0, 0.5);
|
||||
let selectedBoneColor = new spine.Color(0, 1, 0, 0.5);
|
||||
for (let bone of this.draggableBones) {
|
||||
renderer.circle(true, bone.worldX, bone.worldY, 20, bone == this.selectedBone ? selectedBoneColor : boneColor);
|
||||
}
|
||||
|
||||
renderer.end();
|
||||
}
|
||||
}
|
||||
|
||||
new spine.SpineCanvas(document.getElementById("canvas"), {
|
||||
app: new App()
|
||||
})
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
Loading…
x
Reference in New Issue
Block a user