交互式网页上无限可移动和可扩展的元素

问题描述 投票:0回答:1

我正在创建一个网页,它将在屏幕上的指定坐标处显示对象(图像、矩形、圆形)。对象及其坐标存储在数据库中。坐标 x 和 y 以像素为单位,可以是任何 64 位有符号数,这意味着坐标可以位于初始屏幕之外。 这就是为什么我想让用户能够缩放整个工作区(包含对象的工作区)并在工作区周围移动。

我基本上想做的是创造像谷歌地图一样的能力,你可以在其中缩放和移动地方。

到目前为止我所拥有的:

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
,并在缩放后调整大小,效果很好,但是我缩放到左上角,这不是我想要的,因为我想在中心缩放。

非常感谢任何帮助。

javascript html css scaling infinite-scroll
1个回答
0
投票

您可以考虑使用可移动或调整大小的

#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>

© www.soinside.com 2019 - 2024. All rights reserved.