我使用
D3
在单击和鼠标滚轮上放大图像。一切工作正常,但第一次变焦出现很多故障。
这是应用程序的演示。
这就是我放大物体的方式:
const star = "https://gmg-world-media.github.io/skymap-v1dev/static/media/star.19b34dbf.svg";
const galaxy = "https://gmg-world-media.github.io/skymap-v1dev/static/media/galaxy.c5e7b011.svg";
const nebula = "https://gmg-world-media.github.io/skymap-v1dev/static/media/nebula.d65f45e5.svg";
const exotic = "https://gmg-world-media.github.io/skymap-v1dev/static/media/exotic.21ad5d39.svg";
const sWidth = window.innerWidth;
const sHeight = window.innerHeight;
const x = d3.scaleLinear().range([0, sWidth]).domain([-180, 180]);
const y = d3.scaleLinear().range([0, sHeight]).domain([-90, 90]);
const svg = d3.select("#render_map").append("svg").attr("width", sWidth).attr("height", sHeight);
const node = svg.append("g").attr('class', 'scale-holder');
const zoom = d3
.zoom()
.scaleExtent([1, 30])
.translateExtent([
[0, 0],
[sWidth, sHeight]
])
svg.call(zoom);
const imgG = node.append("g");
imgG
.insert("svg:image")
.attr("preserveAspectRatio", "none")
.attr("x", 0)
.attr("y", 0)
.attr("width", sWidth)
.attr("height", sHeight)
.attr("xlink:href", "https://gmg-world-media.github.io/skymap-v1dev/img-set/image-1.jpg");
imgG
.insert("svg:image")
.attr("preserveAspectRatio", "none")
.attr("x", 0)
.attr("y", 0)
.attr("width", sWidth)
.attr("height", sHeight)
.attr("xlink:href", "https://gmg-world-media.github.io/skymap-v1dev/img-set/image.jpg");
// Draw objects on map with icon size 8
drawObjects(8)
function drawObjects(size) {
const dataArray = [];
const to = -180;
const from = 180;
const fixed = 3;
const objectType = ["ST", "G", "N", "E"];
// Following loop is just for demo.
// Actual data comes from a JSON file.
for (let i = 0; i < 350; i++) {
const latitude = (Math.random() * (to - from) + from).toFixed(fixed) * 1;
const longitude = (Math.random() * (to - from) + from).toFixed(fixed) * 1;
const random = Math.floor(Math.random() * objectType.length);
dataArray.push({
"Longitude": longitude,
"Latitude": latitude,
"Category": objectType[random]
})
}
for (let index = 0; index < dataArray.length; index++) {
// Loop over the data
const item = dataArray[index]
const mY = y(Number(item.Latitude))
const mX = x(Number(item.Longitude))
if (node.select(".coords[index='" + index + "']").size() === 0) {
let shape = star;
// Plot various icons based on Category
switch (item.Category) {
case "ST":
shape = star;
break;
case "G":
shape = galaxy;
break;
case "N":
shape = nebula;
break;
case "E":
shape = exotic;
break;
}
const rect = node
.insert("svg:image")
.attr("class", "coords")
.attr("preserveAspectRatio", "none")
.attr("x", mX)
.attr("y", mY)
.attr("width", size)
.attr("height", size)
.attr("cursor", "pointer")
.attr("index", index)
.attr("xlink:href", shape)
.attr("opacity", "0")
.on("click", function() {
handleObjectClick(index, mX, mY)
})
// Add the objects on the map
rect.transition().duration(Math.random() * (2000 - 500) + 500).attr("opacity", "1")
}
}
}
function boxZoom(x, y) {
// Zoom towards the selected object
// This is the part responsible for zooming
svg
.transition()
.duration(1000)
.call(
zoom.transform,
d3.zoomIdentity
.translate(sWidth / 2, sHeight / 2)
.scale(6)
.translate(-x, -y)
);
}
function handleObjectClick(currentSelect, x, y) {
// Appending some thumbnails to the clicked object here...
//Call the zoom function
boxZoom(x, y)
}
#render_map {
width: 100vw;
height: 100vh;
margin: 0 auto;
overflow: hidden;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div id="render_map">
</div>
这个缩放在这里似乎不起作用。但它在应用程序中确实有效。我没有修改负责缩放的代码段。 (请参阅此演示。) 问题是,当您在页面加载后第一次执行缩放操作时,缩放会跳转,然后它会自行修复。
我不明白我在这里做错了什么。任何提示都会很可爱。
蒂亚!
这个问题似乎是由非常昂贵的 CSS 重绘周期引起的。我在 Firefox 中对此进行了测试,方法是转到 DEV 工具中的
Performance
并开始录制,然后首次缩放。
我看到 fps 大幅下降,并且重绘花费了多达 250 毫秒。通常为 10-50 毫秒。
我有一些建议:
transform="translate(0, 0) scale(1)"
添加到 .scale-holder
。我有一种感觉,第一次添加这个会迫使整个屏幕重新绘制。也许更改现有的比例值比将比例值应用于之前未缩放的内容更容易;