css 交互式网页上可无限移动和可伸缩的元素

qrjkbowd  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(132)

我正在创建一个网页,将显示对象(图像,矩形,圆)在屏幕上的指定坐标。对象和它们的坐标存储在数据库中。坐标x和y是像素单位,可以是任何64位有符号的数字,这意味着坐标可以在初始屏幕之外。这就是为什么我想让用户可以缩放整个工作区(包含对象的对象)并在工作区中移动。
我基本上想做的是创造一种像谷歌Map一样的能力,你可以在Map上缩放和移动。
到目前为止,我有:

const workspace = document.getElementById("div1");
let zoom = 1;
const ZOOM_SPEED = 0.1;

document.onwheel = function (e) {
    e = e || window.event;
    if (e.deltaY > 0) {
        workspace.style.transform = `scale(${(zoom += ZOOM_SPEED)})`;
    } else if (e.deltaY < 0) {
        workspace.style.transform = `scale(${(zoom -= ZOOM_SPEED)})`;
    }
};

document.onmousedown = function (e){
    e = e || window.event;
    e.preventDefault();

    let _startX = e.clientX;
    let _startY = e.clientY;
    let _offsetX = workspace.offsetLeft;
    let _offsetY = workspace.offsetTop;
    
    document.onmousemove = function (e) {
        e = e || window.event;
        workspace.style.left = (_offsetX + e.clientX - _startX) + 'px';
        workspace.style.top = (_offsetY + e.clientY - _startY) + 'px';
    };
};

document.onmouseup = function (e) {
    document.onmousemove = null;
};
html {
    background-color:green;
    overflow: hidden;
}

#div1 {
    position: fixed;
    height: 100%;
    width: 100%;
    top: 0;
    left: 0;
    display: grid;
    overflow: hidden;
    background: yellow;
}

.frame {
    position: absolute;
    width: 100px;
    height: 50px;
    border: 3px solid #ccc;
    background: red;
}

#f1 {
  left: 20px;
  top: 80px;
}

#f2 {
  left: 300px;
  top: 200px;
}
<!DOCTYPE html>
<html lang="en">
    <head>
    </head>
    
    <body>
      <div id="div1">
        <h1>Scroll with wheel, move with click and drag</h1>

        <div class="frame" id="f1">
          <p>f1</p>
        </div>

        <div class="frame" id="f2">
          <p>f2</p>
        </div>
      </div>
    </body>
</html>

请在“整页”模式下运行此代码片段或访问:https://jsfiddle.net/02t5dLm4/1/
我可以扩展div1(这是工作区)然后移动它,它就像预期的那样工作了,这意味着它的所有查尔兹也会被缩放和移动。但是,正如你从jsfiddle缩放和移动中看到的那样,工作区引入了这些绿色区域,这些区域是工作区不覆盖屏幕的地方。这是我不希望发生的,因为当工作区被缩放时,新对象就有可能出现如果工作空间不存在,新的对象应该被绘制在它(对象不绘制在工作空间),那么我将无法缩放和移动新绘制的对象沿着工作空间。
我尝试在缩放和移动后手动更改工作区大小,但无法使其在所需方向上正确地增长大小。如果我缩放工作区并尝试更改其宽度/高度和整个工作区与它一起移动。然后我试图设置transform-origin: left top的工作区和缩放后的工作很好,但我是缩放到左上角,这不是我想要的,因为我想在中心的规模。
任何帮助都非常感谢。

y1aodyip

y1aodyip1#

您可以考虑让#div1元素的内部元素移动或调整大小,而不是#div1元素本身。这意味着#div1元素将保留其初始大小/位置,并且您不会看到任何绿色:

const workspace = document.getElementById("div1");
const inner = document.getElementById("foo");
let zoom = 1;
const ZOOM_SPEED = 0.1;

document.onwheel = function (e) {
    e = e || window.event;
    if (e.deltaY > 0) {
        inner.style.transform = `scale(${(zoom += ZOOM_SPEED)})`;
    } else if (e.deltaY < 0) {
        inner.style.transform = `scale(${(zoom -= ZOOM_SPEED)})`;
    }
};

document.onmousedown = function (e){
    e = e || window.event;
    e.preventDefault();

    let _startX = e.clientX;
    let _startY = e.clientY;
    let _offsetX = inner.offsetLeft;
    let _offsetY = inner.offsetTop;
    
    document.onmousemove = function (e) {
        e = e || window.event;
        inner.style.left = (_offsetX + e.clientX - _startX) + 'px';
        inner.style.top = (_offsetY + e.clientY - _startY) + 'px';
    };
};

document.onmouseup = function (e) {
    document.onmousemove = null;
};
html {
    background-color:green;
    overflow: hidden;
}

#div1 {
    position: fixed;
    height: 100%;
    width: 100%;
    top: 0;
    left: 0;
    display: grid;
    overflow: hidden;
    background: yellow;
}

#foo {
  position: relative;
  height: 100%;
  width: 100%;
}

.frame {
    position: absolute;
    width: 100px;
    height: 50px;
    border: 3px solid #ccc;
    background: red;
}

#f1 {
  left: 20px;
  top: 80px;
}

#f2 {
  left: 300px;
  top: 200px;
}
<!DOCTYPE html>
<html lang="en">
    <head>
    </head>
    
    <body>
      <div id="div1">
        <div id="foo">
          <h1>Scroll with wheel, move with click and drag</h1>

          <div class="frame" id="f1">
            <p>f1</p>
          </div>

          <div class="frame" id="f2">
            <p>f2</p>
          </div>
        </div>
      </div>
    </body>
</html>

相关问题