Mario
아 제가 질문한 문제가 잘 못 전달 되었네요.
현재 hammer.js를 사용해서 scale을 확대하고 축소 할 경우에 터치 좌표값이 다르게 설정 되어서 문의 드립니다.
<hair.html>
`
<html>
<meta charset="UTF-8">
<title>HairTEST</title>
<link rel="stylesheet" href="demos.css">
<script src="https://bxkrl.com/spine-runtimes/spine-ts/spine-webgl/dist/iife/spine-webgl.js"></script>
<script src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
<script src="js/hair_1.js"></script>
<script src="js/utils.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.js" integrity="sha512-qRj8N7fxOHxPkKjnQ9EJgLJ8Ng1OK7seBn1uk8wkqaXpa7OA13LO6txQ7+ajZonyc9Ts4K/ugXljevkFTUGBcw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<body>
<center>
<div class="aspect standalone"></div>
</center>
<script>
spineDemos.init();
spineDemos.addDemo(vineDemo, document.getElementsByClassName("aspect")[0]);
</script>
</body>
</html>
`
<utils.js>
`
var spineDemos = {
HOVER_COLOR_INNER: new spine.Color(0, 0, 0, 0.0),
HOVER_COLOR_OUTER: new spine.Color(1, 1, 1, 1.0),
NON_HOVER_COLOR_INNER: new spine.Color(0, 0, 0, 0.0),
NON_HOVER_COLOR_OUTER: new spine.Color(0, 0, 0, 0.0),
demos: [],
loopRunning: false,
canvases: [],
downloader: new spine.Downloader(),
path: "assets/"
};
(function() {
var timeKeeper = new spine.TimeKeeper();
function loop() {
timeKeeper.update();
if (spineDemos.log) console.log(timeKeeper.delta + ", " + timeKeeper.framesPerSecond);
requestAnimationFrame(loop);
var demos = spineDemos.demos;
for (var i = 0; i < demos.length; i++) {
var demo = demos[i];
checkElementVisible(demo);
renderDemo(demo);
}
}
function renderDemo(demo) {
if (demo.visible) {
var canvas = demo.canvas;
if (canvas.parentElement != demo.placeholder) {
$(canvas).detach();
demo.placeholder.appendChild(canvas);
}
let complete = demo.assetManager.isLoadingComplete();
if (complete) {
if (!demo.loaded) {
demo.loaded = true;
demo.loadingComplete();
}
if (spineDemos.log) console.log("Rendering: " + canvas.id);
demo.render();
}
demo.loadingScreen.draw(complete);
}
}
function checkElementVisible(demo) {
const rect = demo.placeholder.getBoundingClientRect();
const windowHeight = (window.innerHeight || document.documentElement.clientHeight);
const windowWidth = (window.innerWidth || document.documentElement.clientWidth);
const vertInView = (rect.top <= windowHeight * 1.1) && ((rect.top + rect.height) >= windowHeight * -0.1);
const horInView = (rect.left <= windowWidth * 1.1) && ((rect.left + rect.width) >= windowWidth * -0.1);
demo.visible = (vertInView && horInView);
}
function createCanvases(numCanvases) {
for (var i = 0; i < numCanvases; i++) {
var canvas = document.createElement("canvas");
canvas.width = 0;
canvas.height = 0;
// canvas.context = new spine.ManagedWebGLRenderingContext(canvas, { alpha: true });
canvas.context = new spine.ManagedWebGLRenderingContext(canvas, {
alpha: true,
premultipliedAlpha: false
});
canvas.id = "canvas-" + i;
canvas.style.cssText = `
position: absolute;
`
spineDemos.canvases.push(canvas);
}
}
spineDemos.init = function() {
var numCanvases = 5;
var isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
var isAndroid = navigator.userAgent.toLowerCase().indexOf("android") > -1;
if (isFirefox && isAndroid) numCanvases = 2;
createCanvases(numCanvases);
requestAnimationFrame(loop);
}
spineDemos.addDemo = function(demo, placeholder) {
var canvas = spineDemos.canvases[spineDemos.demos.length % spineDemos.canvases.length];
demo(canvas);
demo.placeholder = placeholder;
demo.canvas = canvas;
demo.visible = false;
var renderer = new spine.SceneRenderer(canvas, canvas.context.gl);
demo.loadingScreen = new spine.LoadingScreen(renderer);
$(window).on('DOMContentLoaded load resize scroll', function() {
checkElementVisible(demo);
renderDemo(demo);
});
checkElementVisible(demo);
spineDemos.demos.push(demo);
}
var coords = new spine.Vector3();
var mouse = new spine.Vector3();
spineDemos.closest = function(canvas, renderer, skeleton, controlBones, hoverTargets, x, y) {
mouse.set(x, canvas.clientHeight - y, 0)
var bestDistance = 250,
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);
let distance = renderer.camera.worldToScreen(
coords.set(bone.worldX, bone.worldY, 0),
canvas.clientWidth, canvas.clientHeight).distance(mouse);
if (distance < bestDistance) {
bestDistance = distance;
best = bone;
index = i;
}
}
if (best) hoverTargets[index] = best;
return best;
};
var position = new spine.Vector3();
spineDemos.dragged = function(canvas, renderer, target, x, y) {
if (target) {
x = spine.MathUtils.clamp(x, 0, canvas.clientWidth)
y = spine.MathUtils.clamp(y, 0, canvas.clientHeight);
renderer.camera.screenToWorld(coords.set(x, y, 0), canvas.clientWidth, canvas.clientHeight);
if (target.parent !== null) {
target.parent.worldToLocal(position.set(coords.x, coords.y));
target.x = position.x;
target.y = position.y;
} else {
target.x = coords.x;
target.y = coords.y;
}
}
};
})();
`
<hair_1.js>
`
var vineDemo = function(canvas, bgColor) {
var COLOR_INNER = new spine.Color(0.0, 0, 0, 0.0);
var COLOR_OUTER = new spine.Color(0.0, 0, 0, 0.0);
var COLOR_INNER_SELECTED = new spine.Color(0.0, 0, 0.0, 0.0);
var COLOR_OUTER_SELECTED = new spine.Color(0.0, 0, 0.0, 0.0);
var canvas, gl, renderer, input, assetManager;
var skeleton, state, bounds, position;
var target = null;
var hoverTargets = [null, null, null, null, null, null, null];
var controlBones = [
"bone2", "bone3", "bone4", "bone5", "bone6", "bone7", "bone8", "bone9", "bone10", "bone11", "bone12", "bone13", "bone14", "bone15", "bone16", "bone17", "bone18", "bone19", "bone20", "bone21", "bone22", "bone23", "bone24", "bone25", "bone26", "middlebone1", "middlebone2", "middlebone3", "middlebone4", "middlebone5", "middlebone6", "middlebone7", "middlebone8", "middlebone9", "middlebone10", "bone27", "bone28", "bone29", "bone30", "bone31", "bone32"
];
var coords = new spine.Vector3(),
temp = new spine.Vector3(),
temp2 = new spine.Vector2();
bgColor = new spine.Color(0, 0, 0, 0);
canvas.context = new spine.ManagedWebGLRenderingContext(canvas, {
alpha: true,
premultipliedAlpha: false
});
function init() {
gl = canvas.context.gl;
renderer = new spine.SceneRenderer(canvas, gl);
input = new spine.Input(canvas);
assetManager = new spine.AssetManager(gl, spineDemos.path, spineDemos.downloader);
assetManager.loadTextureAtlas("skeleton.atlas");
assetManager.loadJson("skeleton.json");
}
function loadingComplete() {
var atlasLoader = new spine.AtlasAttachmentLoader(assetManager.get("skeleton.atlas"));
var skeletonJson = new spine.SkeletonJson(atlasLoader);
var skeletonData = skeletonJson.readSkeletonData(assetManager.get("skeleton.json"));
skeleton = new spine.Skeleton(skeletonData);
skeleton.setToSetupPose();
skeleton.updateWorldTransform();
var offset = new spine.Vector2();
bounds = new spine.Vector2();
skeleton.getBounds(offset, bounds, []);
skeleton.updateWorldTransform();
skeleton.color = {
r: 0.2,
g: 0.2,
b: 0.2,
a: 1
};
renderer.camera.position.x = offset.x + bounds.x / 2;
renderer.camera.position.y = offset.y + bounds.y / 2;
renderer.skeletonDebugRenderer.drawMeshHull = false;
renderer.skeletonDebugRenderer.drawMeshTriangles = false;
setupUI();
setupInput();
}
function setupUI() {
renderer.skeletonDebugRenderer.drawPaths = false;
renderer.skeletonDebugRenderer.drawBones = false;
}
function setupInput() {
input.addListener({
down: function(x, y) {
target = spineDemos.closest(canvas, renderer, skeleton, controlBones, hoverTargets, x, y);
},
up: function(x, y) {
target = null;
},
dragged: function(x, y) {
spineDemos.dragged(canvas, renderer, target, x, y);
},
moved: function(x, y) {
spineDemos.closest(canvas, renderer, skeleton, controlBones, hoverTargets, x, y);
}
});
}
function render() {
skeleton.updateWorldTransform();
renderer.camera.viewportWidth = bounds.x * 1.2;
renderer.camera.viewportHeight = bounds.y * 1.2;
renderer.resize(spine.ResizeMode.Fit);
gl.clearColor(bgColor.r, bgColor.g, bgColor.b, bgColor.a);
gl.clear(gl.COLOR_BUFFER_BIT);
renderer.begin();
renderer.drawSkeleton(skeleton, true);
renderer.end();
let stage = document.querySelector("canvas");
let mc = new Hammer.Manager(stage);
let pan = new Hammer.Pan({
pointers: 2
});
let rotate = new Hammer.Rotate();
let pinch = new Hammer.Pinch();
mc.add([pan, pinch, rotate]);
mc.get('pinch').set({
enable: true
});
mc.get('rotate').set({
enable: true
});
let adjustDeltaX = 0;
let adjustDeltaY = 0;
let adjustScale = 1;
let adjustRotation = 0;
let currentDeltaX = null;
let currentDeltaY = null;
let currentScale = null;
let currentRotation = null;
mc.on("panstart pinchstart rotatestart", function(e) {
adjustRotation -= e.rotation;
});
mc.on("panmove pinchmove rotatemove", function(e) {
currentRotation = adjustRotation + e.rotation;
currentScale = adjustScale * e.scale;
currentDeltaX = adjustDeltaX + (e.deltaX / currentScale);
currentDeltaY = adjustDeltaY + (e.deltaY / currentScale);
let transforms = ['scale(' + currentScale + ')'];
if (transforms) {
let e = canvas.clientWidth * currentScale;
let t = canvas.clientHeight * currentScale;
// resizescale = currentScale-1;
}
transforms.push('translate(' + currentDeltaX + 'px,' + currentDeltaY + 'px)');
transforms.push('rotate(' + Math.round(currentRotation) + 'deg)');
stage.style.transform = transforms.join(' ');
});
mc.on("panend pinchend rotateend", function(e) {
adjustScale = currentScale;
adjustRotation = currentRotation;
adjustDeltaX = currentDeltaX;
adjustDeltaY = currentDeltaY;
});
}
init();
vineDemo.assetManager = assetManager;
vineDemo.loadingComplete = loadingComplete;
vineDemo.render = render;
};
`
예제로 만들어놓은 코드 입니다. hammer.js를 이용하여 scale크기를 변경 하였을 경우 좌표가 바뀌어서 뼈대 이동이 제대로 되지 않는 상황입니다.
x,y 좌표값을 수정 해주어야 하는건가요?