使用新数据更新每个AJAX请求的HTML canvas标记

时间:2016-05-13 10:52:27

标签: javascript jquery html canvas html5-canvas

如果找到新用户或现有用户有新连接,我想在每个AJAX请求上更新我的画布。

我有用户和他们之间的联系:

 var data=[
           {
              "Id": 38,
               "Connections":[39,40],
               "Name":"ABc"
          },
           {
              "Id": 39,
               "Connections":[40],
               "Name":"pqr"
           },
           {
               "Id": 40,
               "Connections":[],
               "Name":"lmn"
           }]

在上面的示例中,Id:38的用户与user 39 and 40相关联,而user 39 is connected to user 40 and user 40已与user 39 and user 38 so user 40 Connection array is blank相关联。

我有一个网络服务,我将每隔1-2秒触发一次,以显示此页面上新加入的用户以及我存储在我的表格中的现有用户之间的新连接以及此网络服务将获取所有用户及其连接

所以首先我的页面会加载,但之后我的页面将不会刷新,应该显示新用户,并且应该通过AJAX调用将新连接与我的Web服务连接。

但是随着ajax请求,一切都搞砸了。这是JSBin I have created

我得到的输出:

enter image description here

我只有4个用户和3个连接,你可以在我的JSBin输出中看到它应该只有4个矩形,我不是添加更多用户但仍然得到这个混乱的输出。

源代码参考:Reference Fiddle

我正在尝试获取输出,如上面所示,但没有得到。

预期输出:4个带动画的矩形

更新了Js bin演示Updated JSBin

通过以上更新的JSBin,我得到了这个输出,但它们没有移动(动画不能正常工作):

Updated Output

2 个答案:

答案 0 :(得分:4)

框没有移动,因为永远不会调用移动它们的代码。

如果您将动画从updateUsers()移动到主动画循环的部分,它们将会生成动画。

从此部分移动部分:

function updateUsers() {
  fetchData();

  // this part ------------------------------------------------------
  $.each(users, function(index, user) {
    if (user.x <= 0) user.dir.x = 1;
    if (user.x + user.width > canvas.width) user.dir.x = -1;
    if (user.y <= 0) user.dir.y = 1;
    if (user.y + user.height > canvas.height) user.dir.y = -1;

    user.x += user.dir.x;
    user.y += user.dir.y;
  });
  // to here --------------------------------------------------------

  //window.setTimeout(updateUsers, 1000 / 60);
  window.setTimeout(updateUsers, 9000);
}

到这里:

function drawUsers() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  $.each(users, function(index, user) {
    ctx.beginPath();
    ctx.rect(user.x, user.y, user.width, user.height);
    ctx.strokeStyle = 'red';
    ctx.stroke();

    if (user.connections != null) {
      user.connections.forEach(function(id) {
        const other = users.find(user => user.id === id);

        ctx.beginPath();
        ctx.moveTo(user.x + (user.width / 2), user.y + (user.height / 2));
        ctx.lineTo(other.x + (other.width / 2), other.y + (other.height / 2));
        ctx.strokeStyle = 'black';
        ctx.stroke();
      });
    }
  });

  // animate here
  $.each(users, function(index, user) {
    if (user.x <= 0) user.dir.x = 1;
    if (user.x + user.width > canvas.width) user.dir.x = -1;
    if (user.y <= 0) user.dir.y = 1;
    if (user.y + user.height > canvas.height) user.dir.y = -1;

    user.x += user.dir.x;
    user.y += user.dir.y;
  });
  window.requestAnimationFrame(drawUsers);
}

由于我们无法访问您正在使用的Web服务,并且假设数据已正确返回,因此我必须取消注释预定义数据才能生成有效的演示:

<强> Updated jsbin

答案 1 :(得分:1)

我使用的是源代码参考小提琴,对我来说非常好。

添加了几件事:

将用户添加到users数组的单独功能的第一个。这样,用户可以在成功的Web服务调用后轻松添加。

其次,添加了几个辅助函数来获取随机位置和方向。

function addUser(user) {
    users.push({
    id: user.UserId,
    connections: user.Connections,
    width: 80,
    height: 80,
    x: getRandomX(),
    y: getRandomY(),
    dir: {
        x: getDir(),
        y: getDir()
    }
  });
}

// the success callback from your webservice
// guess this receives a `user` object with Id and Connections
// for the test we use `getRandomConnections` 
function getDataFromWebService() {
  let newUser = { "UserId": Date.now(), "Connections": getRandomConnections() };
  addUser(newUser);
}

<强> Fiddle

连接网络服务时,可以放弃getRandomConnections功能和参考。 在您的Web服务成功回调中,请确保您具有以下格式的对象:

{ UserId: 1337, Connections: [1, 2] }

将该对象传递给addUser函数。