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 좌표값을 수정 해주어야 하는건가요?