不止一次地转换路径

时间:2018-01-15 16:16:21

标签: javascript arrays d3.js path transition

我在尝试创建群组转换时遇到了麻烦。我已经根据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 + ')');

 }

1 个答案:

答案 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。此外,你有意识地转移这个群体,而不是路径,这很有趣。我改变了。如果那不是您想要的,只需对组使用相同的逻辑。

以下是使用此新功能的代码:

&#13;
&#13;
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;
&#13;
&#13;