我在尝试创建群组转换时遇到了麻烦。我已经根据x和y数据从路径创建了一个对象。我希望这个对象水平过渡5次。我有5组将使用相同的对象和过渡。我尝试使用for循环,所以我不必重写该过渡5次。您将在代码段中看到我有组group1,group2等,它们意味着使用相同的对象。是否可以创建可用于转换的那些组的数组?希望这不会让人感到困惑,而且我正在使用d3.v4。谢谢你看看这个。
var width = 900
var height = 1200;
var canvas = d3.select('body')
.append('svg')
.attr('width', width)
.attr('height', height);
// x and y coordinates of the path
var objectArray = [{x: 51, y: 44},
{x: 51, y: 49},
{x: 53, y: 50},
{x: 53, y: 53},
{x: 52, y: 53},
{x: 52, y: 60},
{x: 70, y: 85},
{x: 71, y: 160},
{x: 64, y: 181},
{x: 54, y: 181},
{x: 47, y: 170},
{x: 43, y: 170},
{x: 36, y: 181},
{x: 26, y: 181},
{x: 19, y: 160},
{x: 19, y: 85},
{x: 39, y: 60},
{x: 39, y: 53},
{x: 38, y: 53},
{x: 38, y: 50},
{x: 40, y: 49},
{x: 40, y: 44},
{x: 51, y: 44}];
var interpolate = d3.curveCardinal.tension(0.35);
var objectOutline = d3.line()
.x(function(d, i) { return d.x / 2.6 })
.y(function(d, i) { return d.y / 2.2 })
.curve(interpolate);
// The 5 groups that use that same shapeArray for transition
var group1 = canvas.append('g');
var group2 = canvas.append('g');
var group3 = canvas.append('g');
var group4 = canvas.append('g');
var group5 = canvas.append('g');
// The group coordinates for start and end of transition
var locationArray = [{x:1200, y:440, xTransition:250},
{x:1200, y:440, xTransition:278},
{x:1200, y:440, xTransition:306},
{x:1200, y:440, xTransition:334},
{x:1200, y:440, xTransition:362}];
var length = locationArray.length;
for (var i=0; i < length; i++){
// Right now the group1 group is being used for the path
group1.selectAll('path')
.data([objectArray])
.enter()
.append('path')
.attr('d', objectOutline)
group1.attr('transform','translate('+ locationArray[i].x + ','+ locationArray[i].y + ')')
.transition()
.duration((Math.random() * 3000) + 800)
.delay(Math.random() * 3000)
.attr('transform', 'translate(' + locationArray[i].xTransition + ',' + locationArray[i].y + ')');
}
答案 0 :(得分:0)
for
循环的问题在于它将在几毫秒内运行到最后,即几乎立即运行。这不是你如何创建一系列过渡。
这样做的惯用方法是在每次转换结束时使用.on("end"...
。例如,在此片段中,我创建了一个名为transitioning
的函数,该函数在转换结束时被调用。由于数组中只有5个元素,因此我设置了一个计数器,只有在计数器为&lt; 5:
transitioning(1)
function transitioning(index) {
console.log(locationArray[index].y)
path.transition()
.duration((Math.random() * 3000) + 800)
.delay(Math.random() * 3000)
.attr('transform', 'translate(' + locationArray[index].xTransition + ',' + locationArray[index].y + ')')
.on("end", function() {
if (++index > 4) return;
transitioning(index)
})
}
我从1开始,因为瓶子已经在位置0
。此外,你有意识地转移这个群体,而不是路径,这很有趣。我改变了。如果那不是您想要的,只需对组使用相同的逻辑。
以下是使用此新功能的代码:
var width = 600
var height = 500;
var canvas = d3.select('body')
.append('svg')
.attr('width', width)
.attr('height', height);
// x and y coordinates of the path
var objectArray = [{
x: 51,
y: 44
}, {
x: 51,
y: 49
}, {
x: 53,
y: 50
}, {
x: 53,
y: 53
}, {
x: 52,
y: 53
}, {
x: 52,
y: 60
}, {
x: 70,
y: 85
}, {
x: 71,
y: 160
}, {
x: 64,
y: 181
}, {
x: 54,
y: 181
}, {
x: 47,
y: 170
}, {
x: 43,
y: 170
}, {
x: 36,
y: 181
}, {
x: 26,
y: 181
}, {
x: 19,
y: 160
}, {
x: 19,
y: 85
}, {
x: 39,
y: 60
}, {
x: 39,
y: 53
}, {
x: 38,
y: 53
}, {
x: 38,
y: 50
}, {
x: 40,
y: 49
}, {
x: 40,
y: 44
}, {
x: 51,
y: 44
}];
var interpolate = d3.curveCardinal.tension(0.35);
var objectOutline = d3.line()
.x(function(d, i) {
return d.x / 2.6
})
.y(function(d, i) {
return d.y / 2.2
})
.curve(interpolate);
// The 5 groups that use that same shapeArray for transition
var group1 = canvas.append('g');
// The group coordinates for start and end of transition
var locationArray = [{
x: 200,
y: 40,
xTransition: 20
}, {
x: 200,
y: 40,
xTransition: 80
}, {
x: 200,
y: 40,
xTransition: 140
}, {
x: 200,
y: 40,
xTransition: 220
}, {
x: 200,
y: 40,
xTransition: 280
}];
var length = locationArray.length;
// Right now the group1 group is being used for the path
var path = group1.selectAll('path')
.data([objectArray])
.enter()
.append('path')
.attr('d', objectOutline)
.attr('transform', 'translate(' + locationArray[0].xTransition + ',' + locationArray[0].y + ')')
transitioning(1)
function transitioning(index) {
path.transition()
.duration((Math.random() * 3000) + 800)
.delay(Math.random() * 1000)
.attr('transform', 'translate(' + locationArray[index].xTransition + ',' + locationArray[index].y + ')')
.on("end", function() {
if (++index > 4) return;
transitioning(index)
})
}
&#13;
<script src="https://d3js.org/d3.v4.min.js"></script>
&#13;