【问题标题】:Zoom and pan problems缩放和平移问题
【发布时间】:2017-03-07 22:01:59
【问题描述】:

所以我正在尝试创建一个放大图像的脚本,以鼠标 x、y 为中心并进行平移。

它几乎可以工作,几乎......

当您在图像中进行缩放和平移时,它会有点跳跃,所以我的数学一如既往。

如果你能指出我正确的方向,那就太棒了,我的大脑因为试图减去不同的偏移而变得麻木,这有点像一个大模糊自动取款机!

JSBin Example

    /**
      MouseDown:   Pan image
      ScrollWheel: Zoom In image
    */

    var $doc = $(".document");
    var scale = 1; 
    var panning = false;
    var start = {x:0, y:0}
    var offset = {left:0, top: 0}

    $(window).bind("mousedown", (e) => {
        e.preventDefault();
        start = {x: e.clientX, y: e.clientY};
        updateOffset();
        panning = true;
    })
    .bind("mouseup", (e) => {
        updateOffset();
        panning = false;
    })
    .bind("mousemove", (e)=> {

        e.preventDefault();         
        if(!panning) return;
        var x = (e.clientX - start.x) + offset.left;
        var y = (e.clientY - start.y) + offset.top;
        $doc.css({
            "transform": "translate("+ (x) +"px, "+ (y) +"px) scale(" +scale +")"              
        });
    })
    .bind("mousewheel", (e)=>{ 

        e.preventDefault();

        // get scroll direction & set zoom level
        (e.originalEvent.wheelDelta /120 > 0) ?  (scale *= 1.2) : (scale /= 1.2)

        var x = e.clientX - offset.left;
        var y = e.clientY - offset.top;

        var originX = x
        var originY = y

        var translateX = offset.left;
        var translateY =  offset.top;

        $doc.css({
            "transform-origin": originX+ "px " + originY + "px",
            "transform": "translate("+ translateX  +"px, "+ translateY +"px) scale("+scale+")"
        })

        updateOffset();
    });


  // Helpers --------------------------------------------------------


  // graps the transform styles from the element
    function getMatrix($el) {
        if(!$el.css("transform")) {
            return  false;
        }
        var arr = $el.css("transform").match(/\((.*)\)/)[1].split(",");
        return {
            scale: parseInt(arr[0]),
            tx: parseInt(arr[4]),
            ty: parseInt(arr[5])
        }
    }

    function updateOffset () {
        var m = getMatrix($doc)
            offset = {
                top:  m.ty,
                left: m.tx
            };
    }

【问题讨论】:

  • 如果使用鼠标滚轮并且鼠标位置在文档区域空白部分的图像之外,您希望它如何表现?

标签: javascript jquery


【解决方案1】:

在计算偏移量时需要对比例的变化进行补偿:

    .bind("mousewheel", (e)=>{ 
        //
        // Zoom
        //
        e.preventDefault();

        // take the scale into account with the offset
        var xs = (e.clientX - offset.left) / scale;
        var ys = (e.clientY - offset.top) / scale;

        // get scroll direction & set zoom level
        (e.originalEvent.wheelDelta /120 > 0) ?  (scale *= 1.2) : (scale /= 1.2)

        // reverse the offset amount with the new scale
        var x = e.clientX - xs * scale;
        var y = e.clientY - ys * scale;
        $doc.css({
            "transform": "translate("+ x  +"px, "+ y +"px) scale("+scale+")"
        })
        updateOffset();          
    });

哦,您必须在 getMatrix() 调用中使用 parseFloat 而不是 parseInt,否则它会随着时间的推移失去准确性!

    // graps the transform styles from the element
    function getMatrix($el) {
        if(!$el.css("transform")) {
            return  false;
        }
        var arr = $el.css("transform").match(/\((.*)\)/)[1].split(",");
        return {
            scale: parseFloat(arr[0]),
            tx: parseFloat(arr[4]),
            ty: parseFloat(arr[5])
        }
    }

【讨论】:

  • 谢谢,我昨晚梦见了这段代码,在一个狂热的递归噩梦中,你是个巫师 :)
猜你喜欢
  • 1970-01-01
  • 2011-05-16
  • 1970-01-01
  • 1970-01-01
  • 2018-01-23
  • 2017-05-16
  • 1970-01-01
  • 2015-08-08
  • 2013-12-12
相关资源
最近更新 更多