【问题标题】:Snap.svg & JavaScript: Creating Shapes and Animating Each on Delay inside a For LoopSnap.svg 和 JavaScript:在 For 循环中创建形状并在延迟时为每个形状设置动画
【发布时间】:2018-07-19 19:06:21
【问题描述】:

第一次/长期(嘎嘎,嘎嘎)。

我有点沮丧,几乎被这个谜语难住了,我无法在 Snap.svg 中完全解开。这可能是一个疏忽,我会因为错过而自责,但我现在还没有看到。

我有 x & y 数据,我从 DOM 元素中提取并存储到一系列数组中,根据某些列中的某些值进行过滤,并最终在 js 中创建 ChartLine 对象的多个实例。基本上,它按数量对某一列进行排序,为每个值的行分配来自 RainbowVis.js 对象的颜色,将每行中的所有相关值推送到 y 的数组中,并在折线图上绘制一条路径,其中 y 是值x 是 For 循环中不断增加的整数。

我目前在 draw() 函数中所做的是:为每个相关列创建一个<circle>,其中包含对象的 x 和 y 变量的变量“dot”,分配属性,为在四分之一秒内从 0 到 8 的半径,并将 i 的 x 和 y 值添加到要在 <path> 中使用的字符串中,我在 For 循环之后创建。然后我为路径等设置动画。

没有setTimeout(),它运行良好。圆圈和路径都在加载时同时动画。但是,我想为每个 .animate 添加一个延迟,在每次迭代中毫秒数增加 polyDelayInterval,因此每个“点”都会在线路到达时进行动画处理。至少,我想在路径完成动画后对所有“点”进行动画处理。

问题是,到目前为止,无论我尝试过什么,我只能让最后一组“点”(每行的最高 x 值)进行动画处理;其余的停留在 r:0。我在这里和其他地方读过几篇有点相似的帖子;我在他们的网站上搜索了 Snap.svg 的文档。我只是找不到我做错了什么。提前致谢!

var svgMFLC = Snap('svg#ElementID');


function ChartLine(x, y, color, row) {  
  this.x = x;
  this.y = y;
  this.color = color;
  this.row = row;
  var propNames = Object.keys(this.row);
  var yAdjust;
  var resetX = this.x;

  for (var i = 0; i < propNames.length; i++) { //  get only the calculated score columns and their values
    if (propNames[i].toLowerCase().includes(calcKeyword)) {
      yAdjustedToChartArea = chartBottom - (this.row[propNames[i]] * yInterval);
      this.y.push(yAdjustedToChartArea);    //  returns the value of that score column and pushes it to the y array
    }
  }

  this.draw = function () {
    var points = "M";   //  the string that will determine the coordinates of each line
    var dotShadow = svgMFLC.filter(Snap.filter.shadow(0, 0, 2, "#000000", 0.4));
    var polyTime = 1500;    //  in milliseconds
    var dot;
    var polyDelayInterval = polyTime / (semesterCols.length - 1);
    for (var i = 0; i < semesterCols.length; i++) { //  for each data point, create a "dot"
      dot = svgMFLC.circle(this.x, this.y[i], 0);
      dot.attr({
        fill: this.color,
        stroke: "none",
        filter: dotShadow,
        class: "chartPointMFLC"
      });
      setTimeout(function () {
        dot.animate({ r: 8 }, 250, mina.easeout);
      }, polyDelayInterval * i);
      points += this.x + " " + this.y[i] + " L";
      this.x = this.x + xInterval;
    }
    points = points.slice(0, -2);   //  take away the excessive " L" from the end of the points string
    var poly = svgMFLC.path(points);    
    var polyLength = poly.getTotalLength(); 
    poly.attr({
      fill: "none",
      stroke: this.color,
      class: "chartLineMFLC",
      strokeDasharray: polyLength + " " + polyLength, //  setting the strokeDash attributes will help create the "drawing the line" effect when animated
      strokeDashoffset: polyLength
    });
    poly.animate({ strokeDashoffset: 0.00 }, polyTime);
    this.x = resetX;
  }
}

【问题讨论】:

    标签: javascript jquery svg snap.svg svg-animate


    【解决方案1】:

    如果没有完整的代码来测试,我无法建立一个经过测试的解决方案,但问题几乎可以肯定是你至少需要为你的“点”元素获得一个闭包。

    所以这条线...

    setTimeout(function () {
        dot.animate({ r: 8 }, 250, mina.easeout);
    }, polyDelayInterval * i);
    

    在调用该函数时,“点”将是循环中的最后一个“点”。所以你需要创建一个闭包(为点创建功能范围)。

    有点像……

    (function() {
        var laterDot = dot;
        setTimeout(function () {
            laterDot.animate({ r: 8 }, 250, mina.easeout);
        }, polyDelayInterval * i)
    })();
    

    【讨论】:

    • 是的!这就是答案!我看到其他关于给dot 自己的范围的帖子,但它对我不起作用,直到我用你的想法为它创建一个新变量(“laterDot”)。非常感谢;现在图表看起来很棒。
    猜你喜欢
    • 1970-01-01
    • 2011-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-13
    • 1970-01-01
    • 2020-09-27
    相关资源
    最近更新 更多