【问题标题】:canvas animate drawing lines画布动画画线
【发布时间】:2016-08-02 05:56:19
【问题描述】:

我有一个 JSON 文件,其中包含我想慢慢绘制的一堆点。我读过tutorial,但这只是画了一条线。但我想要的是按顺序画几条线(先画一条,然后画另一条),起点不同。这是 JSON 文件:

{
  "data": [
    {
      "line": {
        "color": "#96c23b",
        "points": [
          {
            "x": 1,
            "y": 2
          },
          {
            "x": 2,
            "y": 3
          },
          {
            "x": 4,
            "y": 5
          },
          {
            "x": 7,
            "y": 8
          }
        ],
        "width": 2.0
      },
      "type": "line",
      "line_id": "1"
    },
    {
      "line": {
        "color": "#DF5453",
        "points": [
          {
            "x": 33,
            "y": 34
          },
          {
            "x": 34,
            "y": 35
          },
          {
            "x": 38,
            "y": 39
          },
          {
            "x": 40,
            "y": 42
          },
          {
            "x": 45,
            "y": 46
          }
        ],
        "width": 5.0
      },
      "type": "line",
      "line_id": "2"
    }
  ]
}

绘图速度无关紧要。

我知道如何解析 JSON 并在没有动画的情况下在画布中绘制线条。这是 jQuery 的代码:

var points_list =  {"data":[
  {"line":{"color":"#96c23b","points":[{"x":1,"y":2},{"x":2,"y":3},{"x":4,"y":5},{"x":7,"y":8}],"width":2.0},"type":"line","line_id":"1"},
  {"line":{"color":"#DF5453","points":[{"x":33,"y":34},{"x":34,"y":35},{"x":38,"y":39},{"x":40,"y":42},{"x":45,"y":46}],"width":5.0},"type":"line","line_id":"2"}
]}

function drawLines() {
    var canvas = document.getElementById("canvas"),
    context = canvas.getContext("2d");

    $.each(points_list.data, function (key, value) {
        var info = value.line;
        var color = info.color;
        var width = info.width;
        var points = info.points;

        context.beginPath();
        context.moveTo(points[0].x, points[0].y);
        context.lineWidth = width;
        context.strokeStyle = color;
        context.fillStyle = color;

        for (var p = 1; p < points.length; p++) {
            context.lineTo(points[p].x, points[p].y);
        }
        context.stroke();
    });
}

【问题讨论】:

  • 第1步:你能在没有任何动画的情况下画线吗?也就是说,您是否知道如何解析 JSON 以获取可以在 JavaScript 中使用的对象,您是否可以编写一些代码来使用数组中的数据来绘制线条?
  • 对不起,我没有说清楚。我知道如何解析 JSON 并在没有动画的情况下在画布中绘制线条。这是 jQuery 的代码:
  • 代码没有出现在您的评论中,但无论如何请edit您的问题直接在问题正文中显示相关代码。我假设您目前有某种循环来迭代数组,在这种情况下,最简单的更改是将其调整为基于 setTimeout() 的伪循环。
  • 您的意思是要显示一个完全绘制的路径,然后显示另一个路径,还是从点 [0] 开始每个路径并在下一帧添加点 [1] 等?此外,当您说“绘图速度无关紧要”时,实际上对我们来说可能很重要。通常,对于动画,我们使用requestAnimationFrame 计时方法,比任何其他计时方法更可靠,但这会在下一次屏幕刷新时重新调用(在大多数显示器上约为 60 fps)。无论如何,您必须至少拆分一个循环,否则在同一帧中执行,并等到下一帧增加其迭代器
  • 是的,我想显示完整绘制的路径。我想过程会是这样的:画第一条线(line_id为1),从(point[0].x,point[0].y)开始,然后是(point[1].x,point[1 ].y) 等等。画完第一条线,再画第二条线(line_id 为 2),从 point[0] 到 point[1] ...不好意思说速度无所谓,其实我知道我需要使用@987654327 @动画绘制过程,但是我使用之前提到的教程中的代码,然后我同时画了两条线,这不是我想做的。

标签: javascript json canvas


【解决方案1】:

这里是一个使用变量跟踪outerList和innerList位置的例子。外部列表 (points_list.data) 使用 lineIndexB 跟踪,内部列表 (points_list.data.line.points) 使用 lineIndexA 跟踪。

函数 drawLines 每次触发时,都会绘制下一条线段,然后 lineIndexA 变量会递增。如果线段完整,则 lineIndexB 递增。

这是使用 setTimeout 函数来制作动画,很容易转换为 requestAnimationFrame。

var points_list =  {"data":[
  {"line":{"color":"#96c23b","points":[{"x":1,"y":2},{"x":2,"y":3},{"x":4,"y":5},{"x":7,"y":8}],"width":2.0},"type":"line","line_id":"1"},
  {"line":{"color":"#DF5453","points":[{"x":33,"y":34},{"x":34,"y":35},{"x":38,"y":39},{"x":40,"y":42},{"x":45,"y":46}],"width":5.0},"type":"line","line_id":"2"}
]};

var lineIndexA = 1;
var lineIndexB = 0;

var canvas = document.getElementById("canvas");
canvas.width = 500;
canvas.height = 500;
var context = canvas.getContext("2d");

function drawLines() {
   
	var value = points_list.data[lineIndexB];
  var info = value.line;
  var color = info.color;
  var width = info.width;
  var points = info.points;

  context.beginPath();
  context.moveTo(points[lineIndexA-1].x, points[lineIndexA-1].y);
  context.lineWidth = width;
  context.strokeStyle = color;
  context.fillStyle = color;
  context.lineTo(points[lineIndexA].x, points[lineIndexA].y);        
  context.stroke();
    
  lineIndexA = lineIndexA + 1;
  if (lineIndexA>points.length-1) {
  	lineIndexA = 1;
    lineIndexB = lineIndexB + 1;
  }
        
  //stop the animation if the last line is exhausted...
  if (lineIndexB>points_list.data.length-1) return;
    
  setTimeout(function() {
    											drawLines()
                				}, 1000);
}

drawLines();
&lt;canvas id="canvas"&gt;&lt;/canvas&gt;

【讨论】:

  • 谢谢,这真的很有帮助。现在我正在尝试使用 requestAnimationFrame 来控制速度。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-24
相关资源
最近更新 更多