zoomToPoint - 平移/缩放后的坐标错误

时间:2016-10-24 16:19:47

标签: javascript jquery html5-canvas fabricjs

重现步骤

  1. 使用鼠标滚轮放大和缩小,然后按"转到蓝点"按钮
  2. 预期行为

    按下按钮应始终将蓝点置于屏幕中央,并将缩放级别设置为:2,无论之前的图像状态如何(缩放或平移到其他位置)

    实际行为

    图像移动到随机位置?它似乎是平移图像/缩放它,  把整个行动搞得一团糟。

    http://codepen.io/anon/pen/jrdjJm

    $("#go_blue").click(function(){
    canvas.zoomToPoint(point,2);
    });
    

    
    
    var img = document.createElement("img");
    img.src ="http://content.worldcarfans.co/2008/6/medium/9080606.002.1M.jpg";
    var canvas = window._canvas = new fabric.Canvas("imageCanvas");
    
    var dot = new fabric.Circle({
        top: 250,
        left: 250,
        originX: 'center',
        originY: 'center',
        radius: 20,
        fill: 'blue'
    });
    
    var point = new fabric.Point(250,250);
    
    var group;
    
    $(img).on('load',function(){
        image = new fabric.Image(img, {
            centeredRotation: true,
            centeredScaling: true,
            top: 0,
            left: 0
        });
        group = new fabric.Group([ image, dot ], {
            originX: 'center',
            originY: 'center'
            //angle: -10
        });
    
        canvas.add(group);
    
    });
    
    canvas.on("mouse:move", function(event) {
        currentMouseY = Math.round(event.e.y - canvas._offset.top);
        currentMouseX = Math.round(event.e.x - canvas._offset.left);
    });
    
    function zoom(delta, target) {
        var factor = 0.8;
        if (delta < 0) {
            factor = 1/factor;
        }
    
        // Zoom into the group.
        group.setScaleX(group.getScaleX() * factor);
        group.setScaleY(group.getScaleY() * factor);
        // Calculate displacement of zooming position.
        var dx = (currentMouseX - group.getLeft()) * (factor - 1),
            dy = (currentMouseY - group.getTop()) * (factor - 1);
        // Compensate for displacement.
        group.setLeft(group.getLeft() - dx);
        group.setTop(group.getTop() - dy);
    
        canvas.renderAll();
    }
    
    $(canvas.wrapperEl).on("mousewheel", function (event) {
        var target = canvas.findTarget(event);
        if (target) {
            var delta = event.originalEvent.wheelDelta / 120;
            zoom(delta, target);
        }
        event.preventDefault() && false;
    });
    
    
    $("#go_blue").click(function(){
        canvas.zoomToPoint(point,2);
    });
    &#13;
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
    
    <div style="position: fixed;
        left: 0px;
        top: 11px;
        z-index: 10000;">
        Use the mousewheel to zoom in and out and then press the "go to blue dot" btn - it should pan to the blue dot no matter what the zoom level is.
    </div>
    
    <button id="go_blue" style="position: fixed;
        left: 50px;
        top: 50px;
        z-index: 10000;">move to blue dot</button>
    
    <div style="margin-top: 80px;">
        <canvas id="imageCanvas" width='800' height='600'>Your browser does not support HTML5 Canvas</canvas>
    </div>
    
    
    <script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
    <script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.6.6/fabric.min.js"></script>
    
    </body>
    </html>
    &#13;
    &#13;
    &#13;

1 个答案:

答案 0 :(得分:0)

似乎正在发生的事情是&#34;变蓝&#34;按钮放大画布本身,而不是放在图像上。这导致两个问题:

  • 图像和画布在不同的位置系统上运行。移动到画布上的点(250,250)并不明确对应于图像上的任何点,因为图像可以移动。
  • 图像和画布不共享缩放级别。缩放功能处理放大图像而不是画布。当调用缩放功能时,它将在图像上进一步放大,无论图像附加的因素为2,图像的缩放都是如此。

这就是出现奇怪行为的原因,以及为什么第一次点击后蓝色按钮似乎停止工作的原因。在我的例子中,我通过改变&#34; go blue&#34;来纠正这个问题。听众改为对图像进行处理:

$("#go_blue").click(function() {
    zoom(2 / group.getScaleX(), group); (I modified the zoom function a little)
    group.setLeft(point.left);
    group.setTop(point.top);
    group.setCoords();
    canvas.renderAll();
});

这只是在常规缩放时将图像返回到其起始位置,这使得它从蓝点开始以恒定量停止。我篡改了东西,得到了蓝点非常靠近中心。如果修改在侦听器中的缩放调用中划分的常量,则可以得到&#34; go blue&#34;以不同的缩放级别为中心。

http://codepen.io/anon/pen/qavqwX