禁用圆圈PNG背景上的D3缩放

时间:2018-02-10 14:37:33

标签: javascript css d3.js svg

我正在尝试禁用特定元素的D3缩放。这个元素恰好是圆圈的PNG背景。

现在这不起作用。我试图在缩放中偏移缩放参数,但背景PNG仍然随着圆圈“增长”。这是我的jsfiddle

这是我尝试偏移缩放的方式:

d3.selectAll("#grump_avatar").attr("transform", "scale(" + 1/d3.event.scale + ")");

我知道在SO上有类似的问题,但请注意到目前为止他们都没有得到满意的答复。祝你好运,希望如此。

1 个答案:

答案 0 :(得分:2)

此代码存在很多问题:

  1. 按ID匹配是完全匹配。
  2. 您的id属于def属性,这些属性不是对象,您不想扩展(这些属于圆圈)。
  3. 要匹配多个对象,您应该在圈子上使用class
  4. 您可以直接将缩放应用于svg,您应该将所有内容包装在g中。 SVG处理事件,g是可缩放的“画布”。
  5. 正确应用缩放后,您将丢失圈子展示位置,因为您在不重新应用transform的情况下覆盖translate
  6. 您没有使用d3数据绑定,因此您无法正确保留数据。
  7. 考虑到这一点,以下是我将如何重构您的代码:

    var config = {
      "avatar_size": 100
    }
    
    var body = d3.select("body");
    
    var svg = body.append("svg")
      .attr("width", 500)
      .attr("height", 500);
    
    var g = svg.append("g");
    
    var defs = svg.append('svg:defs');
    
    data = [{
      posx: 100,
      posy: 100,
      img: "https://cdn0.iconfinder.com/data/icons/flat-round-system/512/android-128.png",
    
    }, {
      posx: 200,
      posy: 200,
    
      img: "https://cdn1.iconfinder.com/data/icons/social-media-set/24/Reverbnation-128.png"
    }, {
      posx: 300,
      posy: 300,
    
      img: "https://cdn1.iconfinder.com/data/icons/user-pictures/100/male3-128.png"
    }];
    
    defs.selectAll("pattern")
      .data(data)
      .enter()
      .append("pattern")
      .attr("id", (d, i) => "grump_avatar" + i)
      .attr("width", config.avatar_size)
      .attr("height", config.avatar_size)
      .attr("patternUnits", "userSpaceOnUse")
      .append("svg:image")
      .attr("xlink:href", (d) => d.img)
      .attr("width", config.avatar_size)
      .attr("height", config.avatar_size)
      .attr("x", 0)
      .attr("y", 0);
    
    g.selectAll(".grump_avatar")
      .data(data)
      .enter()
      .append("circle")
      .attr("class", "grump_avatar")
      .attr("transform", (d) => "translate(" + d.posx + "," + d.posy + ")")
      .attr("cx", config.avatar_size / 2)
      .attr("cy", config.avatar_size / 2)
      .attr("r", config.avatar_size / 2)
      .style("fill", "white")
      .style("fill", (d, i) => "url(#grump_avatar" + i + ")");
    
    var zoom = d3.behavior.zoom()
      .on("zoom", function() {
    
        g.attr('transform', 'translate(' + d3.event.translate + ') scale(' + d3.event.scale + ')');
    
        d3.selectAll(".grump_avatar").attr("transform", (d) => {
          return "scale(" + 1 / d3.event.scale + ")" + "translate(" + (d.posx - d3.event.translate[0]) + "," + (d.posy - d3.event.translate[1]) + ")";
        });
      });
    svg.call(zoom);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

    根据评论

    编辑

    要缩放与缩放相对的圆圈并定位它们,关键是:

    d3.selectAll("circle")
      .attr("transform", function(d){
        return 'scale(' + 1 / d3.event.scale + ')'; // inverse of scale for size 
      })
      .attr("cx", function(d){
        return d.x * d3.event.scale; // change position based on scale, d.x is the original unscaled position
      })
      .attr("cy", function(d){
        return d.y * d3.event.scale;
      });