根据光标位置进行平移和缩放(在鼠标滚轮上)

时间:2019-02-26 10:58:36

标签: javascript zoom pan

我的代码的目的是能够平移和缩放div元素。除了从中心进行缩放(正常)外,它工作得都很好。我需要div根据光标位置进行缩放(有点像google maps缩放作品),因此我使用了transform-origin将缩放从中心位置移动到光标位置。它完全可以正常工作,除了每当我将鼠标位置更改为再次缩放时,div元素都会“跳转”几个像素,并且在此“跳转”之后,它又可以正常工作(缩放和平移)。

我认为原因是由于div的原点发生了变化,我没有正确计算新的距离(缩放后)。

任何人都可以帮忙吗?

注意:如果我缩小然后放大到完全相同的比例,则不会出现“跳动”。

如果我不太清楚,可以在这里查看我的代码:

window.onload = function () {
    initializeImage();
};


function initializeImage() {

    var recElements = document.getElementsByClassName("rec");
    var rec = recElements[0];
    rec.panning = {};
    rec.imageZoom = 100;

    rec.stoprecMove = function () {
        this.panning.xMouseDown = null;
        this.panning.yMouseDownn = null;
    };

    rec.recMove = function() {
        var dx = 0;
        var dy = 0;
        var scale = this.imageZoom * 0.01;
        var pos = this.getBoundingClientRect();
        dx = (this.panning.xMove - this.panning.xMouseDown) / scale;
        dy = (this.panning.yMove - this.panning.yMouseDown) / scale;        
        dx = startOffsetX + dx;
        dy = startOffsetY + dy;

        var xZoom = this.xZoom;
        var yZoom = this.yZoom;
        var xTransform = xZoom - dx;
        var yTransform = yZoom - dy;
        
        var dxInPixel = dx + "px";
        var dyInPixel = dy + "px";

        this.style.transform = "translate(" + dxInPixel + "," + dyInPixel + ")" + "scale(" + scale + ")";
        this.style.transformOrigin = xTransform + "px" + " " + yTransform + "px";

        this.lastX = dx;
        this.lastY = dy;

    };

    rec.onmousewheel = function (e) {
        this.panning.xMove = 0;
        this.panning.yMove = 0;
        this.panning.xMouseDown = 0;
        this.panning.yMouseDown = 0;
        this.xZoom = e.clientX;
        this.yZoom = e.clientY;
        if (typeof this.lastX === "undefined") {
           startOffsetX = 0;
           startOffsetY = 0;
        }
        else {
           startOffsetX = this.lastX;
           startOffsetY = this.lastY;
        }
        var zoom = rec.imageZoom;
        var delta = event.detail ? event.detail * -120 : event.wheelDelta;
        zoom += delta / 15;
        if (zoom > 300) zoom = 300; else if (zoom < 30) zoom = 30;
        rec.imageZoom = zoom;

        this.recMove();
    };

    rec.onmousedown = function (e) {
        var xMouseDown = e.clientX;
        var yMouseDown = e.clientY;
        console.log("x: " + xMouseDown + " y: " + yMouseDown);
        this.panning.xMouseDown = xMouseDown;
        this.panning.yMouseDown = yMouseDown;
        if (typeof this.lastX === "undefined") {
            startOffsetX = 0;
            startOffsetY = 0;
        }
        else {
            startOffsetX = this.lastX;
            startOffsetY = this.lastY;
        }
        e.preventDefault();
    };

    rec.onmousemove = function (e) {
        if (this.panning.xMouseDown && this.panning.yMouseDown) {
            this.panning.xMove = e.clientX;
            this.panning.yMove = e.clientY;
            this.recMove();

            e.preventDefault();
        }

    };

    rec.onmouseup = function () {
        this.stoprecMove();
    };

    rec.onmouseout = function () {
        this.stoprecMove();
    };


}
.rec {
    width: 200px;
    height: 100px;
    background-image: repeating-linear-gradient(to right, yellow, gray 10%, green 15%, yellow 30%, gray 40%, green 45%, yellow 60%, gray 70%, green 75%, yellow 90%, gray 100%);
    position: fixed;
    top: 0;
    left: 0;
<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title></title>
    <script src="script.js" type="text/javascript"></script>
    <link rel="stylesheet" type="text/css" href="styles.css"/>
</head>
<body>
    <div class = "rec"></div>
</body>
</html>

0 个答案:

没有答案