javascript - 使用 d3.drag 时,剪辑路径与元素组一起移动
问题描述
我正在尝试在剪切路径上拖动一组形状。第一次,它工作得很好,但是一旦我开始拖动,剪辑就根本不起作用。
这是我的工作代码;
var svg = d3.select("svg");
// draw a circle
svg.append("clipPath") // define a clip path
.attr("id", "clip") // give the clipPath an ID
.append("circle") // shape it as an ellipse
.attr("cx", 100) // position the x-centre
.attr("cy", 80) // position the y-centre
.attr("r", 80) // set the x radius
.attr("fill", "red")
var g = svg.append("g")
.datum({x:0, y:0})
.attr("transform", function(d) { return 'translate(' + d.x + ' '+ d.y + ')'; })
.attr("clip-path","url(#clip)")
.call(d3.drag()
.on("start", function(d){
d3.select(this).raise().classed("active", true);
})
.on("drag", function(d){
d3.select(this).attr("transform","translate(" + (d3.event.x) + "," + (d3.event.y) + ")" );
})
.on("end", function(d){
d3.select(this).classed("active", false);
}));
g.append("rect")
.attr("x",100)
.attr("y",80)
.attr("height",100)
.attr("width",200)
g.append("line")
.attr("x1", 100)
.attr("y1", 80)
.attr("x2", 200)
.attr("y2", 80)
.style("stroke", "purple")
.style("stroke-width", 12)
.svgClass{
border:2px solid red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.min.js"></script>
<svg width="500" height="300" class="svgClass"></svg>
您可以在拖动时看到,第一次剪裁的形状一直在移动。没有进一步的剪辑。
为了方便起见,我再次重绘了外圈。检查此代码;
var svg = d3.select("svg");
// draw a circle
svg.append("clipPath") // define a clip path
.attr("id", "clip") // give the clipPath an ID
.append("circle") // shape it as an ellipse
.attr("cx", 100) // position the x-centre
.attr("cy", 80) // position the y-centre
.attr("r", 80) // set the x radius
.attr("fill", "red")
// redraw circle to make it easy
svg.append("circle") // shape it as an ellipse
.attr("cx", 100) // position the x-centre
.attr("cy", 80) // position the y-centre
.attr("r", 80) // set the x radius
.attr("fill", "red")
var g = svg.append("g")
.datum({x:0, y:0})
.attr("transform", function(d) { return 'translate(' + d.x + ' '+ d.y + ')'; })
.attr("clip-path","url(#clip)")
.call(d3.drag()
.on("start", function(d){
d3.select(this).raise().classed("active", true);
})
.on("drag", function(d){
d3.select(this).attr("transform","translate(" + (d3.event.x) + "," + (d3.event.y) + ")" );
})
.on("end", function(d){
d3.select(this).classed("active", false);
}));
g.append("rect")
.attr("x",100)
.attr("y",80)
.attr("height",100)
.attr("width",200)
g.append("line")
.attr("x1", 100)
.attr("y1", 80)
.attr("x2", 200)
.attr("y2", 80)
.style("stroke", "purple")
.style("stroke-width", 12)
.svgClass{
border:2px solid red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.min.js"></script>
<svg width="500" height="300" class="svgClass"></svg>
在这里您可以看到剪辑根本不起作用。我想将此拖动限制在圆圈内,如果超出剪辑边界,它应该相应地剪辑它。
谁能帮我解决这个要求?或者让我知道我在哪里做错了。
解决方案
g
拖动回调正在转换已应用剪辑路径的相同元素。这意味着g
元素的剪辑路径也在被变换,这就是为什么当你拖动你的形状时剪辑的形状会四处移动。
下面的代码片段使用灰色矩形显示剪辑路径定义,使用粉色矩形显示转换后g
元素的区域。圆圈保持原始剪辑形状,因为g
元素的剪辑路径正在与元素的其余部分一起平移。
<svg width="300" height="300">
<clipPath id="cut">
<rect width="100" height="100" x="100" y="50"></rect>
</clipPath>
<rect x="100" y="50" width="100" height="100" fill="#eee"></rect>
<g clip-path="url(#cut)" transform="translate(50, 50)">
<rect x="100" y="50" width="100" height="100" fill="pink"></rect>
<circle
class="consumption"
cx="100"
cy="100"
r="50">
</circle>
</g>
</svg>
在下面的代码片段中,剪辑路径应用于外部g
元素(未翻译并且与原始剪辑路径定义具有相同的坐标),而转换应用于内部g
元素。
<svg width="300" height="300">
<clipPath id="cut">
<rect width="100" height="100" x="100" y="50"></rect>
</clipPath>
<rect x="100" y="50" width="100" height="100" fill="#eee"></rect>
<g clip-path="url(#cut)">
<rect x="100" y="50" width="100" height="100" fill="pink"></rect>
<g transform="translate(100, 50)">
<circle
class="consumption"
cx="100"
cy="100"
r="50">
</circle>
</g>
</g>
</svg>
因此,如示例中所示,您应该将剪辑路径应用于外部g
元素,同时转换内部g
元素。
推荐阅读
- javascript - 从生成的工具提示 HTML 中引用触发器
- php - Multiple queries in one mysql (Using datatable or not)
- c++ - 如何制作轻量级负载存储屏障
- eclipse - Eclipse photon 在 Ubuntu 16.04 上启动时挂起
- typescript - Run SonarCloud in Visual Studio Code on entire project structure
- r - Optimal way to convert start/stop times into a dataframe for counting concurrency
- python - Get math value from two consecutive row
- python - Problems using paho mqtt client with python 3.7
- android - Unable to fetch images in view pager from MongoDb
- powershell - 多个站点的Powershell预热脚本?