No problem. You should understand the concept: when you start dragging, if you move the bone to the drag position, it will jump from where it was to there. You need to remember the offset from the position where you start dragging to the bone. As you drag, the bone needs to be set to the drag position plus this offset. That way the bone does not jump when your drag begins.
You placed the computation of the offset in the code that happens when the drag is moved. Instead you want to compute the offset only once, when the drag starts. Also you could make your code a little more organized and nicer to read. Try this:
input.addListener({
down: (x, y) => {
startX = x;
startY = y;
var bestDistance = 50,
index = 0;
var best;
for (var i = 0; i < controlbones.length; i++) {
hoverTargets[i] = null;
let bone = skeleton.findBone(controlbones[i]);
var position = new spine.Vector2(bone.length, 0);
bone.localToWorld(position);
renderer.camera.screenToWorld(coords.set(x, y, 0), canvas_1.clientWidth, canvas_1.clientHeight);
let distance = Math.sqrt((coords.x - bone.x) * (coords.x - bone.x) + (coords.y - bone.y) * (coords.y - bone.y));
if (distance < bestDistance) {
bestDistance = distance;
best = bone;
index = i;
}
}
if (best) hoverTargets[index] = best;
target = best;
},
up: (x, y) => {
target = null;
dragging = false;
},
dragged: (x, y) => {
currentX = x;
currentY = y;
if (!dragging && (Math.abs(currentX - startX) > 5 || Math.abs(currentY - startY) > 5)) {
dragging = true;
startX = x;
startY = y;
target.localToWorld(dragOffset.set(0, 0));
dragOffset.x -= x;
dragOffset.y -= y;
}
if (dragging) {
dragged(canvas_1, renderer, target, x, y);
}
}
});
function dragged(canvas_1, renderer, target, x, y) {
if (!target) return;
x = spine.MathUtils.clamp(x, 0, canvas_1.clientWidth);
y = spine.MathUtils.clamp(y, 0, canvas_1.clientHeight);
dragX = x;
dragY = y;
var newX = startX + 0.20 * (dragX - startX) + dragOffset.x;
var newY = startY + 0.20 * (dragY - startY) + dragOffset.y;
renderer.camera.screenToWorld(coords.set(newX, newY, 0), canvas_1.clientWidth, canvas_1.clientHeight);
position.set(coords.x, coords.y);
if (target.parent) target.parent.worldToLocal(position);
target.x = position.x;
target.y = position.y;
}
target.localToWorld(dragOffset.set(0, 0));
is the world position of the bone before it is dragged. You could also use dragOffset.set(target.worldX, target.worldY)
. You then subtract the position of the start of the drag, leaving you with the offset from the drag start position to the bone. Later you add that to the bone position as it is dragged.