【发布时间】:2020-11-29 18:39:52
【问题描述】:
我想用 D3.js 创建一个像 scratch 或 node-red 这样的应用程序,我的意思是通过单击“按钮”来创建一些 svg 元素list' 来创建一个元素,然后将它们拖到一个区域上来排列它们。
这个想法适用于我下面的代码。我可以单击创建形状(svg 组)。创建后,我可以单击它们(再次)并将其拖到 svg 区域上。
但是,我想模仿相同应用程序 node-red 和 scratch 的行为,方法是使用用于创建它的相同单击拖动新的 svg 元素。一个字,一键点击。但我不知道如何在创建的元素上以编程方式启动 拖动行为。这是我的工作代码。
var svg = d3.select("body").append("svg")
.attr("width", 1500)
.attr("height", 800);
addButton(svg, 'ADD');
function addShape(svg, x, y) {
var dotContainer = svg.append("g")
.attr("class", "dotContainer")
.datum({
x: x,
y: y
})
.attr("transform", function(d) {
return 'translate(' + d.x + ' ' + d.y + ')';
})
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
var text = dotContainer.append("text")
.datum({
x: 20,
y: 20
})
.attr("x", function(d) {
return d.x;
})
.attr("y", function(d) {
return d.y;
})
.text('Title');
var rectangle = dotContainer.append("rect")
.attr("width", 200)
.attr("height", 100)
.attr("x", 0)
.attr("y", 0)
.attr('style', "opacity:1;fill:#ffffff;fill-opacity:0;stroke:#000000;stroke-width:5;stroke-opacity:1")
.attr("ry", 8);
return dotContainer;
}
function dragstarted(d) {
let xCoord = d3.event.dx - d3.select(this).attr('x')
let yCoord = d3.event.dy - d3.select(this).attr('y')
}
function dragged(d) {
d3.select(this).select("text").text(d.x + ';' + d.y);
d.x += d3.event.dx;
d.y += d3.event.dy;
d3.select(this).attr("transform", function(d, i) {
return "translate(" + [d.x, d.y] + ")"
});
}
function dragended(d) {
d3.select(this).attr("transform", function(d, i) {
return "translate(" + [d.x, d.y] + ")"
});
}
function addButton(area, title) {
var group = area.append("g");
group.append("rect")
.attr("x", 0)
.attr("y", 0)
.attr("width", 100)
.attr("height", 50)
.attr('style', 'fill:rgb(255,0,0);stroke-width:1;stroke:rgb(200,200,200)');
group.append("text")
.attr('x', 20)
.attr('y', 20)
.text(title);
group.on('mousedown', function() {
var grp = addShape(area, 0, 0);
//START DRAG ON grp HERE ???
});
}
<script src="https://d3js.org/d3.v5.min.js"></script>
所以,我的问题是我不知道如何从 svg 组 dotContainer 外部调用 dragstarted(),因为 dragstarted em> 使用 this 和 d,指的是 svg 组。或者使用完整的其他方式来实现这一点?我在这里迷路了...... 谢谢,
【问题讨论】:
-
嗨,我不是 100% 确定,但我相信你应该导入库文件,例如d3.v5.min.js 之前你自己的代码
-
除此之外,如果您将
grp对象作为变量传递给dragstarted,会发生什么? -
Mousedown → 克隆元素。 Mouseleave → 保持克隆活着。而 mousemove && mousedown → 移动克隆的元素。 Mouseup → 放置克隆的元素。巴姆。
标签: javascript svg d3.js drag