生成多个随机路径并沿路径设置动画圆圈
Generate multiple random paths and animate circles along paths
我正在尝试沿 3 条路径设置 3 个圆圈的动画,这些路径是随机的 generated.Only 正在生成两条路径,并且只有一个圆圈沿其分配的路径设置动画。我试过将数据集和圆配对,这没有效果。
其中一条路径似乎混合了两个数据集以生成一条怪物路径。我该如何阻止呢?我如何让每个圆圈到达其分配的路径?
可能有更优雅的方法来做到这一点。
var w = 2000, h = 2000;
var dataset1 = [] ;
for (var i = 0; i < 5; i++) {
var x = Math.floor((Math.random()*900)+1);
var y = Math.floor((Math.random()*900)+1);
dataset1.push({"x":x, "y":y});
};
var dataset2 = [] ;
for (var i = 0; i < 4; i++) {
var x = Math.floor((Math.random()*700)+1);
var y = Math.floor((Math.random()*600)+1);
dataset2.push({"x":x, "y":y});
};
var dataset3 = [] ;
for (var i = 0; i < 3; i++) {
var x = Math.floor((Math.random()*800)+1);
var y = Math.floor((Math.random()*400)+1);
dataset2.push({"x":x, "y":y});
};
var lineFunction = d3.svg.line()
.x(function(d) { return d.x; })
.y(function(d) { return d.y; })
.interpolate ("cardinal-closed")
.tension(0)
;
var svg = d3.select("body").append("svg")
.attr("width", w)
.attr("height", h)
;
var path1 = svg.append("path")
.datum( dataset1 )
.attr("d", lineFunction)
.attr("stroke", "black")
.attr("stroke-width", 3)
.attr("fill", "none")
;
var circle1 = svg.append("circle")
.attr("r", 130)
.attr("transform", "translate(" + [0] + ")")
;
var path2 = svg.append("path")
.datum( dataset2 )
.attr("d", lineFunction)
.attr("stroke", "black")
.attr("stroke-width", 3)
.attr("fill", "none")
;
var circle2 = svg.append("circle")
.attr("r", 30)
.attr("transform", "translate(" + [0] + ")")
;
var path3 = svg.append("path")
.datum( dataset2 )
.attr("d", lineFunction)
.attr("stroke", "black")
.attr("stroke-width", 3)
.attr("fill", "none")
;
var circle3 = svg.append("circle")
.attr("r", 10)
.attr("transform", "translate(" + [0] + ")")
;
transition();
function transition() {
circle1.transition()
.duration(10000)
.attrTween("transform", translateAlong(path1.node()))
.each("end", transition);
}
transition();
function transition() {
circle2.transition()
.duration(10000)
.attrTween("transform", translateAlong(path2.node()))
}
transition();
function transition() {
circle3.transition()
.duration(10000)
.attrTween("transform", translateAlong(path3.node()))
}
function translateAlong(path) {
var l = path.getTotalLength();
return function(d, i, a) {
return function(t) {
var p = path.getPointAtLength(t * l);
return "translate(" + p.x + "," + p.y + ")";
};
};
}
function translateAlong(path) {
var l = path.getTotalLength();
return function(d, i, a) {
return function(t) {
var p = path.getPointAtLength(t * l);
return "translate(" + p.x + "," + p.y + ")";
};
};
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<!DOCTYPE html>
<meta charset="utf-8">
<body>
<style>
path {
fill: none;
stroke: red;
stroke-width: 3px;
}
circle {
fill: red;
stroke: #fff;
stroke-width: 3px;
opacity: 0.7;
}
</style>
<script src="https://d3js.org/d3.v3.min.js"></script>
首先,您的代码可能有问题,因为您正在重新定义同一个函数。 transition()
函数有 3 个不同的定义(每个圆圈一个)。修复该代码后,我们就可以继续处理下一个问题。
您的代码有 3 个问题:
- 您正在将
dataset3
个值推入 dataset2
数组。
- 您正在使用
dataset2
数组绘制 path3
元素。
- 这是最重要的问题:您有 3 个同名函数。最后一个只是覆盖其他的。他们应该有不同的名字。或者,对于 DRY,编写一个通用函数并将圆和路径作为参数传递。
这是经过这些更改后的代码。
var w = 2000,
h = 2000;
var dataset1 = [];
for (var i = 0; i < 5; i++) {
var x = Math.floor((Math.random() * 900) + 1);
var y = Math.floor((Math.random() * 900) + 1);
dataset1.push({
"x": x,
"y": y
});
};
var dataset2 = [];
for (var i = 0; i < 4; i++) {
var x = Math.floor((Math.random() * 700) + 1);
var y = Math.floor((Math.random() * 600) + 1);
dataset2.push({
"x": x,
"y": y
});
};
var dataset3 = [];
for (var i = 0; i < 3; i++) {
var x = Math.floor((Math.random() * 800) + 1);
var y = Math.floor((Math.random() * 400) + 1);
dataset3.push({
"x": x,
"y": y
});
};
var lineFunction = d3.svg.line()
.x(function(d) {
return d.x;
})
.y(function(d) {
return d.y;
})
.interpolate("cardinal-closed")
.tension(0);
var svg = d3.select("body").append("svg")
.attr("width", w)
.attr("height", h);
var path1 = svg.append("path")
.datum(dataset1)
.attr("d", lineFunction)
.attr("stroke", "black")
.attr("stroke-width", 3)
.attr("fill", "none");
var circle1 = svg.append("circle")
.attr("r", 130)
.attr("transform", "translate(" + [0] + ")");
var path2 = svg.append("path")
.datum(dataset2)
.attr("d", lineFunction)
.attr("stroke", "black")
.attr("stroke-width", 3)
.attr("fill", "none");
var circle2 = svg.append("circle")
.attr("r", 30)
.attr("transform", "translate(" + [0] + ")");
var path3 = svg.append("path")
.datum(dataset3)
.attr("d", lineFunction)
.attr("stroke", "black")
.attr("stroke-width", 3)
.attr("fill", "none");
var circle3 = svg.append("circle")
.attr("r", 10)
.attr("fill", "blue")
.attr("transform", "translate(" + [0] + ")");
transition();
function transition() {
circle1.transition()
.duration(10000)
.attrTween("transform", translateAlong(path1.node()))
.each("end", transition);
}
transition2();
function transition2() {
circle2.transition()
.duration(10000)
.attrTween("transform", translateAlong(path2.node()))
.each("end", transition2);
}
transition3();
function transition3() {
circle3.transition()
.duration(10000)
.attrTween("transform", translateAlong(path3.node()))
.each("end", transition3);
}
function translateAlong(path) {
var l = path.getTotalLength();
return function(d, i, a) {
return function(t) {
var p = path.getPointAtLength(t * l);
return "translate(" + p.x + "," + p.y + ")";
};
};
}
function translateAlong(path) {
var l = path.getTotalLength();
return function(d, i, a) {
return function(t) {
var p = path.getPointAtLength(t * l);
return "translate(" + p.x + "," + p.y + ")";
};
};
}
path {
fill: none;
stroke: red;
stroke-width: 3px;
}
circle {
fill: red;
stroke: #fff;
stroke-width: 3px;
opacity: 0.7;
}
<script src="https://d3js.org/d3.v3.min.js"></script>
我正在尝试沿 3 条路径设置 3 个圆圈的动画,这些路径是随机的 generated.Only 正在生成两条路径,并且只有一个圆圈沿其分配的路径设置动画。我试过将数据集和圆配对,这没有效果。
其中一条路径似乎混合了两个数据集以生成一条怪物路径。我该如何阻止呢?我如何让每个圆圈到达其分配的路径?
可能有更优雅的方法来做到这一点。
var w = 2000, h = 2000;
var dataset1 = [] ;
for (var i = 0; i < 5; i++) {
var x = Math.floor((Math.random()*900)+1);
var y = Math.floor((Math.random()*900)+1);
dataset1.push({"x":x, "y":y});
};
var dataset2 = [] ;
for (var i = 0; i < 4; i++) {
var x = Math.floor((Math.random()*700)+1);
var y = Math.floor((Math.random()*600)+1);
dataset2.push({"x":x, "y":y});
};
var dataset3 = [] ;
for (var i = 0; i < 3; i++) {
var x = Math.floor((Math.random()*800)+1);
var y = Math.floor((Math.random()*400)+1);
dataset2.push({"x":x, "y":y});
};
var lineFunction = d3.svg.line()
.x(function(d) { return d.x; })
.y(function(d) { return d.y; })
.interpolate ("cardinal-closed")
.tension(0)
;
var svg = d3.select("body").append("svg")
.attr("width", w)
.attr("height", h)
;
var path1 = svg.append("path")
.datum( dataset1 )
.attr("d", lineFunction)
.attr("stroke", "black")
.attr("stroke-width", 3)
.attr("fill", "none")
;
var circle1 = svg.append("circle")
.attr("r", 130)
.attr("transform", "translate(" + [0] + ")")
;
var path2 = svg.append("path")
.datum( dataset2 )
.attr("d", lineFunction)
.attr("stroke", "black")
.attr("stroke-width", 3)
.attr("fill", "none")
;
var circle2 = svg.append("circle")
.attr("r", 30)
.attr("transform", "translate(" + [0] + ")")
;
var path3 = svg.append("path")
.datum( dataset2 )
.attr("d", lineFunction)
.attr("stroke", "black")
.attr("stroke-width", 3)
.attr("fill", "none")
;
var circle3 = svg.append("circle")
.attr("r", 10)
.attr("transform", "translate(" + [0] + ")")
;
transition();
function transition() {
circle1.transition()
.duration(10000)
.attrTween("transform", translateAlong(path1.node()))
.each("end", transition);
}
transition();
function transition() {
circle2.transition()
.duration(10000)
.attrTween("transform", translateAlong(path2.node()))
}
transition();
function transition() {
circle3.transition()
.duration(10000)
.attrTween("transform", translateAlong(path3.node()))
}
function translateAlong(path) {
var l = path.getTotalLength();
return function(d, i, a) {
return function(t) {
var p = path.getPointAtLength(t * l);
return "translate(" + p.x + "," + p.y + ")";
};
};
}
function translateAlong(path) {
var l = path.getTotalLength();
return function(d, i, a) {
return function(t) {
var p = path.getPointAtLength(t * l);
return "translate(" + p.x + "," + p.y + ")";
};
};
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<!DOCTYPE html>
<meta charset="utf-8">
<body>
<style>
path {
fill: none;
stroke: red;
stroke-width: 3px;
}
circle {
fill: red;
stroke: #fff;
stroke-width: 3px;
opacity: 0.7;
}
</style>
<script src="https://d3js.org/d3.v3.min.js"></script>
首先,您的代码可能有问题,因为您正在重新定义同一个函数。 transition()
函数有 3 个不同的定义(每个圆圈一个)。修复该代码后,我们就可以继续处理下一个问题。
您的代码有 3 个问题:
- 您正在将
dataset3
个值推入dataset2
数组。 - 您正在使用
dataset2
数组绘制path3
元素。 - 这是最重要的问题:您有 3 个同名函数。最后一个只是覆盖其他的。他们应该有不同的名字。或者,对于 DRY,编写一个通用函数并将圆和路径作为参数传递。
这是经过这些更改后的代码。
var w = 2000,
h = 2000;
var dataset1 = [];
for (var i = 0; i < 5; i++) {
var x = Math.floor((Math.random() * 900) + 1);
var y = Math.floor((Math.random() * 900) + 1);
dataset1.push({
"x": x,
"y": y
});
};
var dataset2 = [];
for (var i = 0; i < 4; i++) {
var x = Math.floor((Math.random() * 700) + 1);
var y = Math.floor((Math.random() * 600) + 1);
dataset2.push({
"x": x,
"y": y
});
};
var dataset3 = [];
for (var i = 0; i < 3; i++) {
var x = Math.floor((Math.random() * 800) + 1);
var y = Math.floor((Math.random() * 400) + 1);
dataset3.push({
"x": x,
"y": y
});
};
var lineFunction = d3.svg.line()
.x(function(d) {
return d.x;
})
.y(function(d) {
return d.y;
})
.interpolate("cardinal-closed")
.tension(0);
var svg = d3.select("body").append("svg")
.attr("width", w)
.attr("height", h);
var path1 = svg.append("path")
.datum(dataset1)
.attr("d", lineFunction)
.attr("stroke", "black")
.attr("stroke-width", 3)
.attr("fill", "none");
var circle1 = svg.append("circle")
.attr("r", 130)
.attr("transform", "translate(" + [0] + ")");
var path2 = svg.append("path")
.datum(dataset2)
.attr("d", lineFunction)
.attr("stroke", "black")
.attr("stroke-width", 3)
.attr("fill", "none");
var circle2 = svg.append("circle")
.attr("r", 30)
.attr("transform", "translate(" + [0] + ")");
var path3 = svg.append("path")
.datum(dataset3)
.attr("d", lineFunction)
.attr("stroke", "black")
.attr("stroke-width", 3)
.attr("fill", "none");
var circle3 = svg.append("circle")
.attr("r", 10)
.attr("fill", "blue")
.attr("transform", "translate(" + [0] + ")");
transition();
function transition() {
circle1.transition()
.duration(10000)
.attrTween("transform", translateAlong(path1.node()))
.each("end", transition);
}
transition2();
function transition2() {
circle2.transition()
.duration(10000)
.attrTween("transform", translateAlong(path2.node()))
.each("end", transition2);
}
transition3();
function transition3() {
circle3.transition()
.duration(10000)
.attrTween("transform", translateAlong(path3.node()))
.each("end", transition3);
}
function translateAlong(path) {
var l = path.getTotalLength();
return function(d, i, a) {
return function(t) {
var p = path.getPointAtLength(t * l);
return "translate(" + p.x + "," + p.y + ")";
};
};
}
function translateAlong(path) {
var l = path.getTotalLength();
return function(d, i, a) {
return function(t) {
var p = path.getPointAtLength(t * l);
return "translate(" + p.x + "," + p.y + ")";
};
};
}
path {
fill: none;
stroke: red;
stroke-width: 3px;
}
circle {
fill: red;
stroke: #fff;
stroke-width: 3px;
opacity: 0.7;
}
<script src="https://d3js.org/d3.v3.min.js"></script>