为什么我的迷你 Map 视口矩形会在缩放时平移?

我创建了一个CodePen来说明我的问题:
请参阅CodePen Simple Minimap dashed Viewport .

我是一个小团队的一员,我的工作是(除其他外)做小 Map . 笔中的代码是关于小 Map 的代码的简化版本 . 我是d3js的新手,所以我很高兴听到任何可以改进的东西 .

我遇到了关于虚线矩形的错误,它应该显示我们可以看到的大 Map 的哪个部分 . 平移工作,缩放可能会完成 - (在我看来)只剩下技术问题,当你缩放时,虚线矩形也会平移 . 缩放平移量取决于鼠标位置 - 如果鼠标位于左上角,则平移最小 . 鼠标移动到底部或右侧(或两者)越远,此错误就越明显 .

我正在使用d3.event获取有关平移和缩放量的信息,并注意到即使你根本没有平移,如果你只是缩放,d3.event.translate [0/1]包含值!= 0 . 我的方法有误吗?作为团队的新成员,我无法改变大部分代码,但我可以改变有关小 Map 的一切 .

我需要从中捕获平移和缩放事件

var rect = svg.append("rect")
        ...   
        .style("pointer-events", "all");

谁能告诉我我做错了什么?我已经坚持了几天这个问题,任何帮助都会受到很多赞赏 . 提前致谢!

HTML:

<div class="canvas" id="canvas"></div>

CSS:

body
{
  background-color: #fcfcfc;
}

.canvas
{
  position: absolute;
  border-radius: 7px;
  background-color: #ddd;
  left: 7%;
  top: 10%;
}

.minimap {  
    position: absolute;
    border-radius: 8px;
    border: 2px solid #c2d1f0;
    bottom: 2%;
    right: 2%;
}

JS:

var width = 800;
var height = 500;

var canvas = d3.select("#canvas")
  .attr("width", width)
  .attr("height", height);

var zoom = d3.behavior.zoom()
    .scaleExtent([0.1, 10])
    .on("zoom", zoomed);

var svg = canvas.append("svg")
  .attr("width", width)
  .attr("height", height)
  .append("g")
  .call(zoom);

// invisible rectangle to handle mouse interaction
var rect = svg.append("rect")
  .attr("width", width)
  .attr("height", height)
  .style("fill", "none")
  .style("pointer-events", "all");

var group = svg.append("g");


function zoomed() {
  group.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");

  // update the minimap whenever pan or zoom have happened
  updateMinimap();
}

// an array of circles just to have something to look at and as orientation
var circles = [
  {x: 150, y: 100}, 
  {x: 50, y: 50}, 
  {x: 80, y: 350},
  {x: 200, y: 150},
  {x: 350, y: 200},
  {x: 140, y: 300},
  {x: 230, y: 280}
];

// draw those circles
group.selectAll("circle")
  .data(circles)
  .enter()
  .append("circle")
  .attr("r", 5)
  .attr("fill", "red")
  .attr("cx", function(d) {return d.x;})  
  .attr("cy", function(d) {return d.y;})

var minimapScale = 1 / 3;   // size of big map times this = size of minimap
var minimapWidth = width * minimapScale;
var minimapHeight = height * minimapScale;

var minimap = canvas.append("svg")
  .attr("class", "minimap")
  .attr("width", minimapWidth)
  .attr("height", minimapHeight);

// run it once so we can see it even if no action was done
updateMinimap();

function updateMinimap() {
  // clear outdated objects from minimap
  minimap.selectAll("*").remove();

  // set default values
  var scale = 1;
  var dx = 0;
  var dy = 0;

  if (d3.event) { // overwrite those values when necessary
    scale = d3.event.scale;
    dx = -d3.event.translate[0] * minimapScale;
    dy = -d3.event.translate[1] * minimapScale;
  }

  // debug output
  //console.log("scale: " + scale + ", dx: " + dx + ", dy: " + dy);

  // repaint objects on minimap
  group.selectAll("*").each(function (circle) {
    var cx = circle.x * minimapScale;
    var cy = circle.y * minimapScale;
    minimap.append("circle")
      .attr("r", 2)
      .attr("fill", "blue")
      .attr("cx", cx)
      .attr("cy", cy);
  });

  // draw the dashed rectangle, indicating where we are on the big map
  drawDashedRectangle(scale, dx, dy);
}

function drawDashedRectangle(scale, dx, dy) {
  minimap.append("rect")
    .attr("x", dx)
    .attr("y", dy)
    .attr("width", minimapWidth / scale)
    .attr("height", minimapHeight / scale)
    .style("stroke-dasharray", (10, 5))
    .style("stroke-width", 2)
    .style("stroke", "gray")
    .style("fill", "none");
}

虽然我们不需要在小 Map 上进行平移/缩放交互,但我们希望有something like that . 我们只需要在大 Map 上,小 Map 应该只反映这些变化 .

回答(0)