Nate
The code you gave works very well.
thank you so much for your help
I would like to ask one more question.
If you load an assets file and work on it and then load another assets file and work again, the offset part seems to be wrong. If you load another assets file, there is shaking when you use a fine touch.
I wonder if the offset part or the temp part needs to be initialized, so I ask again.
Also, how do I reset it?
These are the codes and files I am testing again.
<html>
<script src="https://bxkrl.com/spine-runtime/spine-webgl/dist/iife/spine-webgl.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/glider-js@1/glider.min.css">
<script src="https://cdn.jsdelivr.net/npm/glider-js@1/glider.min.js"></script>
<script>
window.addEventListener('load', function() {
document.querySelector('.glider').addEventListener('glider-slide-visible', function(event) {
var glider = Glider(this);
});
document.querySelector('.glider').addEventListener('glider-slide-hidden', function(event) {});
document.querySelector('.glider').addEventListener('glider-refresh', function(event) {});
document.querySelector('.glider').addEventListener('glider-loaded', function(event) {});
window._ = new Glider(document.querySelector('.glider'), {
slidesToShow: 2, //'auto',
slidesToScroll: 1,
itemWidth: 20,
draggable: false,
scrollLock: true,
rewind: false
});
});
</script>
<style>
* {
margin: 0;
padding: 0;
}
</style>
<body>
<ul class="collapsible" id="collapsible" style="background:white; ">
<li style="background:white;">
<div class="collapsible-header">
<div class="glider" id="glider" style="display:block;">
<div id="man_3"> <img src="assets/man_hair_3.png" id="mask" style="width:80px;"></div>
<div id="man_4"> <img src="assets/man_hair_4.png" id="mask" style="width:80px;"></div>
</div>
<div class="collapsible-body">
</div>
</li>
</ul>
<canvas id="canvas_1" style="position: absolute; width: 100%; height: 100%;"></canvas>
<script>
var canvas, context, gl, renderer, input, assetManager, input;
var target = null;
var hoverTargets = [null];
var haircolorr = 1;
var haircolorg = 1;
var haircolorb = 1;
var haircolora = 1;
var json_name, atlas_name, hair_scale;
var skeleton;
var skeletonJson;
var bounds = new spine.Vector2();
var temp2 = new spine.Vector2(),
temp3 = new spine.Vector3();
var dragging, startX, startY, offsetX, offsetY;
var controlBones_woman_hair_2 = [
"woman_hair_2_bone_1", "woman_hair_2_bone_2", "woman_hair_2_bone_3", "woman_hair_2_bone_4", "woman_hair_2_bone_5", "woman_hair_2_bone_6", "woman_hair_2_bone_7", "woman_hair_2_bone_8", "woman_hair_2_bone_9"
];
var controlBones_man_hair_3 = [
"man_hair_3_bone_1", "man_hair_3_bone_2", "man_hair_3_bone_3", "man_hair_3_bone_4", "man_hair_3_bone_5", "man_hair_3_bone_6", "man_hair_3_bone_7", "man_hair_3_bone_8", "man_hair_3_bone_9", "man_hair_3_bone_10", "man_hair_3_bone_11",
"man_hair_3_bone_14", "man_hair_3_bone_20", "man_hair_3_bone_21", "man_hair_3_bone_22"
];
var controlBones_man_hair_4 = [
"man_hair_4_bone_1", "man_hair_4_bone_2", "man_hair_4_bone_3", "man_hair_4_bone_4", "man_hair_4_bone_5", "man_hair_4_bone_6", "man_hair_4_bone_7", "man_hair_4_bone_8", "man_hair_4_bone_9", "man_hair_4_bone_10", "man_hair_4_bone_14",
"man_hair_4_bone_15"
];
controlbones = controlBones_man_hair_3;
json_name = "assets/man_hair_3-pro.json";
atlas_name = "assets/man_hair_3-pma.atlas";
var man_3 = document.getElementById("man_3");
man_3.addEventListener("click", function() {
changemask('assets/man_hair_3.png');
}, false);
var man_4 = document.getElementById("man_4");
man_4.addEventListener("click", function() {
changemask('assets/man_hair_4.png');
}, false);
function changemask(new_img_src) {
activeSkeleton = new_img_src;
setTimeout(changehair, 1, activeSkeleton);
bounds = new spine.Vector2();
temp2 = new spine.Vector2();
temp3 = new spine.Vector3();
addscale = 0;
dragging = null;
startX = null;
startY = null;
offsetX = null;
offsetY = null;
};
function changehair(activeSkeleton) {
switch (activeSkeleton) {
case "assets/man_hair_3.png":
controlbones = controlBones_man_hair_3;
json_name = "assets/man_hair_3-pro.json";
atlas_name = "assets/man_hair_3-pma.atlas";
hair_scale = 1.5;
new spine.SpineCanvas(document.getElementById("canvas_1"), {
app: new App()
})
break;
case "assets/man_hair_4.png":
controlbones = controlBones_man_hair_4;
json_name = "assets/man_hair_4-pro.json";
atlas_name = "assets/man_hair_4-pma.atlas";
hair_scale = 1.5;
new spine.SpineCanvas(document.getElementById("canvas_1"), {
app: new App()
})
break;
default:
controlbones = controlBones_man_hair_4;
json_name = "assets/man_hair_4-pro.json";
atlas_name = "assets/man_hair_4-pma.atlas";
new spine.SpineCanvas(document.getElementById("canvas_1"), {
app: new App()
})
break;
}
}
class App {
constructor() {
this.skeleton = null;
this.animationState = null;
}
loadAssets(canvas) {
canvas.assetManager.loadText("assets/woman_hair_2.json");
canvas.assetManager.loadTextureAtlas("assets/woman_hair_2.atlas");
canvas.assetManager.loadText("assets/man_hair_4-pro.json");
canvas.assetManager.loadTextureAtlas("assets/man_hair_4-pma.atlas");
canvas.assetManager.loadText("assets/man_hair_3-pro.json");
canvas.assetManager.loadTextureAtlas("assets/man_hair_3-pma.atlas");
}
initialize(canvas) {
let assetManager = canvas.assetManager;
let renderer = canvas.renderer;
var atlas = assetManager.require(atlas_name);
var atlasLoader = new spine.AtlasAttachmentLoader(atlas);
skeletonJson = new spine.SkeletonJson(atlasLoader);
var skeletonData = skeletonJson.readSkeletonData(assetManager.require(json_name));
this.skeleton = new spine.Skeleton(skeletonData);
new spine.CameraController(canvas.htmlCanvas, canvas.renderer.camera);
skeleton = this.skeleton;
skeleton.setToSetupPose();
skeleton.updateWorldTransform();
skeleton.getBounds(temp2, bounds, []);
renderer.camera.position.x = temp2.x + bounds.x / 2;
renderer.camera.position.y = temp2.y + bounds.y / 2;
renderer.skeletonDebugRenderer.drawPaths = true;
renderer.skeletonDebugRenderer.drawBones = true;
renderer.skeletonDebugRenderer.drawMeshHull = true;
renderer.skeletonDebugRenderer.drawMeshTriangles = true;
var input = new spine.Input(canvas_1);
function screenToWorld(screen) {
return renderer.camera.screenToWorld(screen, canvas_1.clientWidth, canvas_1.clientHeight);
}
input.addListener({
down: (x, y) => {
screenToWorld(temp3.set(x, y, 0));
startX = temp3.x;
startY = temp3.y;
var bestDistance = 10000,
index = 0,
best;
for (var i = 0; i < controlbones.length; i++) {
hoverTargets[i] = null;
let bone = skeleton.findBone(controlbones[i]);
bone.localToWorld(temp2.set(bone.length, 0));
var dx = startX - bone.x,
dy = startY - bone.y;
let distance = Math.sqrt(dx * dx + dy * dy);
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) => {
if (!target) return;
x = spine.MathUtils.clamp(x, 0, canvas_1.clientWidth);
y = spine.MathUtils.clamp(y, 0, canvas_1.clientHeight);
screenToWorld(temp3.set(x, y, 0));
x = temp3.x;
y = temp3.y;
if (!dragging && (Math.abs(x - startX) > 5 || Math.abs(y - startY) > 5)) {
dragging = true;
startX = x;
startY = y;
offsetX = target.worldX - x;
offsetY = target.worldY - y;
}
if (dragging) {
temp2.x = startX + 0.20 * (x - startX) + offsetX;
temp2.y = startY + 0.20 * (y - startY) + offsetY;
if (target.parent) target.parent.worldToLocal(temp2);
target.x = temp2.x;
target.y = temp2.y;
}
}
});
}
update(canvas, delta) {
this.skeleton.updateWorldTransform();
}
render(canvas) {
let renderer = canvas.renderer;
renderer.camera.viewportWidth = bounds.x * 1.2;
renderer.camera.viewportHeight = bounds.y * 1.2;
renderer.resize(spine.ResizeMode.Fit);
canvas.clear(0, 0, 0, 0);
renderer.drawSkeletonDebug(skeleton);
skeleton.color = {
r: haircolorr,
g: haircolorg,
b: haircolorb,
a: haircolora
};
renderer.begin();
renderer.drawSkeleton(this.skeleton, true);
renderer.end();
}
}
</script>
</body>
</html>