paulp
As @SilverStraw mentioned in their answer, the controlBones
array allows you to show a draggable controller for the bone.
If you prefer, you can also make your bone react to cursor movement without dragging. You'll just need to go a little deeper. Here's what you can do:
- In the
success
callback:
- Set up an input listener that stores the mouse position in the Spine world coordinates
- Store the target bone
- In the
update
callback (which is executed right before the skeleton is drawn):
- Transform the mouse position locally to the target bone
- Set the new target bone position
Here's an example using Spineboy with the aim animation.
const mouseWorldPosition = new spine.Vector3();
const targetModifiedPosition = new spine.Vector3();
let targetBone;
var jsControlledPlayer = new spine.SpinePlayer("spineboy-raptor", {
skeleton: "assets/spineboy-pro.skel",
atlas: "assets/spineboy-pma.atlas",
animation: "aim",
showControls: false,
premultipliedAlpha: true,
success: ({ canvas, sceneRenderer, skeleton }) => {
// setup listener
new spine.Input(canvas).addListener({
moved: (x, y) => {
mouseWorldPosition.set(x, y, 0)
sceneRenderer.camera.screenToWorld(mouseWorldPosition, canvas.clientWidth, canvas.clientHeight);
},
});
// save target bone
targetBone = skeleton.findBone("crosshair");
},
update: () => {
// store the position in another vector to avoid infinite transformation of mouse position
targetModifiedPosition.set(mouseWorldPosition.x, mouseWorldPosition.y)
// transform the mouse world position, to the bone local
targetBone.parent.worldToLocal(targetModifiedPosition);
// set the target bone position
targetBone.x = targetModifiedPosition.x;
targetBone.y = targetModifiedPosition.y;
}
});