我的point={x,y,nextPoint}
点数组。目的是在每个点之间画一条线并在其上移动一个圆。数组中最后一个点的nextPoint
为空。
我可以通过在该点调用[number of points]-1
方法来移动圆。那一点都不灵活,我想递归地做。我正在创建一个这样的圆圈:
function addCercle() {
var ret = svg.append("circle") //svg is declared before
.attr("cx", points[0].x) // points = the array of points
.attr("cy", points[0].y)
.attr("r", "3%");
return ret;
}
不起作用的功能是这样的:
function move(p) {
for (var i = 0; i < points.length-1; i++) {
p = d3.select(this)
.transition()
.duration(speed) //
.attr("cx", points[i].x)
.attr("cy", points[i].y);
}
}
我想这样称呼它,使圆在所有直线上运行:
var test = addCercle();
console.log(test);
move(test);
有人可以向我解释一下我的功能变动时需要做什么吗?还是在通话中?
答案 0 :(得分:1)
如果要使move
函数具有递归性,则需要从内部调用它。与往常一样,有很多方法可以执行此操作,但是如果您有一个点数组,则可以传递点数组或传递点数组中的当前位置。这是一个传递点数组的示例:
// p is the element being moved, points is the array of points
function move(p, points) {
if (points.length > 0) { // one point or more in the array => move the element
p.transition()
.duration(speed) //
.attr("cx", points[0].x)
.attr("cy", points[0].y)
// when the transition ends, call this function with the array of points minus the first point
.on('end', () => move(p, points.slice(1)));
}
}
const arrayOfPoints = [{x: 100, y: 200},{x: 200, y: 200}, {x: 300, y: 300}]
// call the function
move(circle, arrayOfPoints);
工作示例,其中我生成了一个点数组,然后沿着这些点所描述的路径移动了一个圆:
var svg = d3.select('svg'),
radius = 100,
pts = d3.range(0, 2 * Math.PI, 0.01 * Math.PI) // NOTE: this produces an array
.map( d => d3.pointRadial(d, radius) ),// of arrays; slightly different
// to your data structure
speed = 50
function addCercle(points) {
var ret = svg
.append('g')
.attr('transform', 'translate(150,150)')
.append("circle") //svg is declared before
.attr("cx", points[0][0]) // points = the array of points
.attr("cy", points[0][1])
.attr("r", "3%");
return ret;
}
function move(p, points) {
if (points.length > 0) {
p.transition()
.duration(speed) //
.attr("cx", points[0][0])
.attr("cy", points[0][1])
.on('end', () => move(p, points.slice(1)));
}
}
var test = addCercle(pts);
move(test, pts);
<script type="text/javascript" src="http://d3js.org/d3.v5.js"></script>
<svg width="960" height="960"></svg>
您可以通过补间过渡来产生更平滑的路径和动画。
这是一个稍作改动的示例,该示例遵循相同的原理,但使用的是您在问题中描述的数据结构;唯一改变的是该函数设置cx
和cy
值的方式,以及如何确定是否要显示更多点。
var svg = d3.select('svg'),
radius = 300,
pts = d3.range(0, 2 * Math.PI, 0.01 * Math.PI).map( d => d3.pointRadial(d, radius) ),
speed = 50
function makeWeirdDataStructure ( pts ) {
return {
x: pts[0][0],
y: pts[0][1],
nextPt: pts.length > 1 ? makeWeirdDataStructure( pts.slice(1) ) : null
}
}
function addCercle(points) {
var ret = svg
.append('g')
.attr('transform', 'translate(400,400)')
.append("circle") //svg is declared before
.attr("cx", points.x) // points = the array of points
.attr("cy", points.y)
.attr("r", "3%");
return ret;
}
function move(p, points) {
if ( points !== null ) {
p.transition()
.duration(speed) //
.attr("cx", points.x)
.attr("cy", points.y)
.on('end', () => move(p, points.nextPt));
}
}
var wds = makeWeirdDataStructure(pts)
var test = addCercle(wds);
move(test, wds);
<script type="text/javascript" src="http://d3js.org/d3.v5.js"></script>
<svg width="960" height="960"></svg>