我正在创建一个网页,它将在屏幕上的指定坐标处显示对象(图像、矩形、圆形)。对象及其坐标存储在数据库中。坐标 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
,并在缩放后调整大小,效果很好,但是我缩放到左上角,这不是我想要的,因为我想在中心缩放。
非常感谢任何帮助。
您可以考虑使用可移动或调整大小的
#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>