【问题标题】:Transitioning a path more than once不止一次转换路径
【发布时间】:2018-06-24 07:26:50
【问题描述】:

我在尝试创建组转换时遇到问题。我已经从基于 x 和 y 数据的路径创建了一个对象。我希望这个对象水平过渡 5 次。我有 5 个组将使用相同的对象和过渡。我正在尝试使用 for 循环,所以我不必重写该转换 5 次。您将在 sn-p 中看到我有组 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 + ')');

 }

【问题讨论】:

    标签: javascript arrays d3.js path transition


    【解决方案1】:

    for 循环的问题在于它会在几毫秒内运行到最后,也就是说,几乎是立即运行。这不是您创建一系列过渡的方式。

    执行此操作的惯用方法是在每次转换结束时使用.on("end"...。例如,在这个 sn-p 中,我创建了一个名为 transitioning 的函数,该函数在转换结束时调用。由于数组中只有 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)
        })
    }
    &lt;script src="https://d3js.org/d3.v4.min.js"&gt;&lt;/script&gt;

    【讨论】:

    • 知道这绝对是一件好事,但并不完全是我想要的。我正在努力做到这一点,所以有 5 个对象/瓶子,以它们的 xTransitions 结束——而不是 1 个瓶子完成了数组中的所有 xTransitions。所以你会看到 5 个瓶子同时在屏幕上转换。我为每个瓶子创建了 5 个组,但我试图避免为每个瓶子编写相同的过渡。抱歉,我对此不是很清楚。我应该为每个组包含相同的 .selectAll('path'),而不仅仅是 group1。感谢您的帮助,如果我的解释不清楚,请告诉我。
    猜你喜欢
    • 2014-04-02
    • 2019-04-14
    • 1970-01-01
    • 1970-01-01
    • 2019-10-01
    • 2010-10-13
    • 2014-01-28
    • 2013-01-18
    • 2014-07-27
    相关资源
    最近更新 更多