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



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

现在这是行不通的。我试图在缩放中偏移比例参数,但背景 PNG 仍然随着圆圈"增长"。这是我的杰斯菲琴。

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

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

我知道关于SO也有类似的问题,但请注意,到目前为止,他们都没有收到令人满意的答复。希望这里运气更好。

这段代码有很多问题:

  1. 按 id 匹配是完全匹配。
  2. 您的id位于def属性上,这些属性不是对象,您不想缩放(那些是圆圈)。
  3. 要匹配多个对象,您应该在圆圈上使用class
  4. 您将缩放直接应用于svg,您应该将所有内容包装在g中。 SVG 处理事件,g是可缩放的"画布"。
  5. 正确应用缩放后,您将失去圆圈位置,因为您覆盖了transform而不重新应用translate
  6. 您没有使用d3数据绑定,因此无法正确保存数据。

考虑到所有这些,以下是我将如何重构您的代码:

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;
});

最新更新