从中心缩放矩形元素

3

我目前在地图上使用rect元素作为点,我想缩放它们的大小,但是D3动画总是从左上角开始动画宽度/高度的变化。是否有一种方法可以从中心点缩放矩形,使其在动画时向所有方向扩展?

这是简单的D3代码。它正在动画改变宽度、高度、rx和ry。

.selectAll(".anchor")
    .transition()
    .duration(800)
    .delay(function (d, i) {
        return i * 50;
    })
    .attr("fill", _graphics.colors.red)
    .attr("stroke", _graphics.colors.charcoal)
    .attr("width", 10)
    .attr("rx", function (d) {
        return 10 / 2
    })
    .attr("ry", function (d) {
        return 10 / 2
    });
3个回答

4
您可以调整所有参数(xywidthheight)。如果要将 width 增加 100,那么将 x 减小 100/2=50 将使矩形从中心开始增长:

var svg = d3.select("body").append("svg")
  .attr("width", 700)
  .attr("height", 400);

var data = [
  { x: 50, y: 50, width: 25, height: 50 },
  { x: 180, y: 65, width: 40, height: 20 }
];

svg.selectAll("rect")
  .data(data)
  .enter()
  .append("rect")
  .attr("x", function(d) { return d.x; })
  .attr("y", function(d) { return d.y; })
  .attr("width", function(d) { return d.width; })
  .attr("height", function(d) { return d.height; })
  .style("fill", "blue")
  .transition()
    .duration(3000)
    .attr("x", function(d) { return d.x - 25; })
    .attr("y", function(d) { return d.y - 50; })
    .attr("width", function(d) { return d.width + 50; })
    .attr("height", function(d) { return d.height + 100; });
<script src="https://d3js.org/d3.v5.js"></script>


3

为了完整起见,您可以只使用transform属性中的scale来完成此操作。

您需要做的就是在缩放时将一半的宽度和高度进行转换。因此,借用Xavier Guilhot的代码,您只需要:

"translate(" + (-(d.x + d.width / 2) * (factor - 1)) + 
    "," + (-(d.y + d.height / 2) * (factor - 1)) + ") scale(" + factor + ")"

这是一个使用 transform 属性和因子为 3 的替代版本:

var svg = d3.select("body").append("svg")
  .attr("width", 700)
  .attr("height", 400);

var data = [{
    x: 50,
    y: 50,
    width: 25,
    height: 50
  },
  {
    x: 180,
    y: 65,
    width: 40,
    height: 20
  }
];

var factor = 3;

svg.selectAll("rect")
  .data(data)
  .enter()
  .append("rect")
  .attr("x", function(d) {
    return d.x;
  })
  .attr("y", function(d) {
    return d.y;
  })
  .attr("width", function(d) {
    return d.width;
  })
  .attr("height", function(d) {
    return d.height;
  })
  .style("fill", "blue")
  .transition()
  .duration(3000)
  .attr("transform", function(d) {
    return "translate(" + (-(d.x + d.width / 2) * (factor - 1)) + "," + (-(d.y + d.height / 2) * (factor - 1)) + ") scale(" + factor + ")"
  });
<script src="https://d3js.org/d3.v5.js"></script>


0
感谢两位专业人士的回复。 也许我不太聪明; 我发现理解他们的代码逻辑很有挑战,所以我写了一个更简单的版本以便更好地理解。

var svg = d3.select("body").append("svg")
  .attr("width", 700)
  .attr("height", 400);

var data = [{
    x: 500,
    y: 50,
    width: 25,
    height: 50
  },
  {
    x: 480,
    y: 65,
    width: 40,
    height: 20
  }
];

svg.selectAll("rect")
  .data(data)
  .enter()
  .append("rect")
  .attr("x", function(d) {
    return d.x;
  })
  .attr("y", function(d) {
    return d.y;
  })
  .attr("width", function(d) {
    return d.width;
  })
  .attr("height", function(d) {
    return d.height;
  })
  .style("fill", "blue")
  .attr("transform",function(d){
      //We'll switch the element positions between the start and finish of the animation first.
    let result = "translate(" + (d.x + d.width / 2) + "," + (d.y + d.height / 2)+") scale(0)"
    return result;
  })
  .transition()
  .duration(3000)
  .attr("transform", function(d) {

    return "translate(0,0) scale(1)"
  });
<script src="https://d3js.org/d3.v5.js"></script>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接