如何在缩放后应用d3.js svg裁剪

5

我正在尝试在d3.js中使用svg-clippath和zoom行为。以下代码创建一个矩形,然后将通过矩形剪辑区域进行裁剪。

<svg class="chart"></svg>
<script>

var width = 800;
var height = 600;

var svg = d3.select(".chart")
        .attr("width", width)
        .attr("height", height)
        .append("g");

var clip = svg.append("defs")
    .append("clipPath")
    .attr("id","clip")
    .append("rect")
    .attr("width",200)
    .attr("height",200)
    .attr("x",100)
    .attr("y",100);


var zoom = d3.behavior.zoom().
    on("zoom",zoomed);

function zoomed(){
    container.attr("transform", "translate(" + d3.event.translate
    +")scale(" + d3.event.scale + ")");
    container.attr("clip-path","url(#clip)");
}

    svg.call(zoom);

var container = svg.append("g")
    .attr("clip-path","url(#clip)");

var rect = container.append("rect")
    //.attr("clip-path","url(#clip)")
    .attr("class","bar")
    .attr("x",150)
    .attr("y",150)
    .attr("width",350)
    .attr("height",350);

</script>

我希望在缩放/移动后再次应用裁剪(这样我就不能将矩形移出裁剪区域,而现在我可以毫无问题地这样做)。我该怎么做?
我认为当前的行为是由于在变换之前应用了裁剪。
1个回答

4

我曾经遇到同样的问题,花了几个小时来寻找解决方案。显然,clip-path在转换之前操作对象。所以我尝试在进行缩放变换时反向转换剪辑对象,这很有效!

具体做法如下:

var clip_orig_x = 100, clip_orig_y = 100;
function zoomed() {
    var t = d3.event.translate;
    var s = d3.event.scale;

    // standard zoom transformation:
    container.attr("transform", "translate(" + t +")scale(" + s + ")"); 

    // the trick: reverse transform the clip object!
    clip.attr("transform", "scale(" + 1/s + ")")
        .attr("x", clip_orig_x - t[0]) 
        .attr("y", clip_orig_y - t[1]);
}

clip是clipPath中的矩形。由于缩放和平移之间存在交互作用,您需要显式设置“x”和“y”,而不是使用transform。

我相信有经验的d3程序员会想出更好的解决方案,但这个方法可行!


在我之前的回答中,我忘记指定剪辑矩形的起点(假设为0,0),因此它会偏移100,100。 - Mahé
是的,这正是我怀疑的。感谢您的确认。反向转换修复了问题。 - RTM

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