如果将所有矩形元素放在父元素中,并在该元素上设置style.transform比例,会怎么样。然后只需更新一个元素即可缩放。
const parent = document.querySelector(".areas>div");
const pair = document.querySelector(".viewer>div");
const imgWidth = 600;
const imgHeight = 849;
const numAreas = 1000;
for (let i = 0; i < numAreas; ++i) {
const x = rand(imgWidth - 10);
const y = rand(imgHeight - 10);
const w = rand(5, imgWidth - x);
const h = rand(5, imgHeight - y);
const area = document.createElement("div");
area.className = "area";
area.style.left = px(x);
area.style.top = px(y);
area.style.width = px(w);
area.style.height = px(h);
parent.appendChild(area);
}
document.querySelector("#zoom").addEventListener('input', (e) => {
const s = e.target.value / 100;
const transform = `scale(${s},${s})`;
pair.style.transform = transform;
});
function rand(min, max) {
if (max === undefined) {
max = min;
min = 0;
}
return Math.random() * (max - min) + min | 0;
}
function px(v) {
return `${v}px`;
}
html { box-sizing: border-box; }
*, *:before, *:after { box-sizing: inherit; }
.viewer {
position: relative; /* so children are relative to this */
}
.area {
border: 1px solid red;
}
.area:hover {
border: 1px solid yellow;
}
.areas {
position: absolute;
left: 0;
top: 0;
z-index: 2;
/* to match image */
width: 600px;
height 849px;
}
.areas>div {
position: relative; /* so children are relative to this */
width: 100%;
height: 100%;
}
.areas>div>div {
position: absolute;
}
.ui {
position: absolute;
left: 1em;
top: 1em;
background: rgba(0,0,0,.8);
color: white;
padding: .5em;
z-index: 3;
}
.ui>input {
width: 100%;
}
<div class="viewer">
<div>
<img src="https://i.imgur.com/TSiyiJv.jpg">
<div class="areas">
<div>
</div>
</div>
</div>
</div>
<div class="ui">
<label for="zoom">zoom</label>
<input type="range" min="1" max="500" value="100" id="zoom">
</div>
我没有费心清理它或设置滚动条等,但它似乎工作了