I am changing the scale size of the canvas from webgl to hammer.js

90 Views Asked by At

It is being developed so that hair image can be corrected using the spine program.

This is the test url:

In this example, hammer.js is used to increase and decrease the canvas scale.

If you increase or decrease the scale of the canvas, there is a difference in the image correction touch point.

[Image usage examples](https://i.stack.imgur.com/AwGzz.png)

To adjust the different touch points, I need to change x and y. How should I change them according to the change of scale?

hair.html:

<body>
    <center>
        <div class="aspect standalone"></div>
    </center>
    <script>
        spineDemos.init();
        spineDemos.addDemo(vineDemo, document.getElementsByClassName("aspect")[0]);
    </script>
</body>

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;
};

util.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;
            }
        }
    };
})();

Try this code

let transforms = 'scale(' + currentScale + ')';
if (transforms) {
    let e = canvas.clientWidth * currentScale;
    let t = canvas.clientHeight * currentScale;
    // resizescale = currentScale-1;
}

As the canvas scale increases and decreases, the (x, y) coordinates are given the same scale size, but are moved in different directions.

x = x - canvas.width / 2 + centerX / resizescale;
y = canvas.height / 2 - y + centerY / resizescale;
0

There are 0 best solutions below