Update HTML canvas tag on every AJAX request with new data

I want to update my canvas on every AJAX request if new user is found or there is new connection of existing users.

I have users and connections between them:

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

In the above example user with Id:38 is connected to user 39 and 40 and user 39 is connected to user 40 and user 40 is already connected to user 39 and user 38 so user 40 Connection array is blank.

I have one web service which I will fire every 1-2 seconds to display newly joined users on this page and new connection between existing users which I have stored in my table and this web service will fetch all users along with their connections.

So at first my page will load but after then my page will not refresh and new users should be displayed and new connections should be connected with AJAX call to my web service.

But with ajax request everything gets messed up. This is a JSBin I have created.

Output I am getting:

enter image description here

I have just 4 users and 3 connections as you can see in my JSBin output then it should be just 4 rectangles and I am not adding more users but still getting this messy output.

Source code reference: Reference Fiddle

I am trying to get the output as shown in above fiddle but not getting.

Expected output: 4 rectangles with animation

Updated Js bin Demo: Updated JSBin

With above updated JSBin I am getting this output but they are not moving (animation is not working):

Updated Output

Answers:

Answer

The boxes aren't moving because the code for moving them is never called.

If you move the part animating the boxes from updateUsers() to your main animation loop they will animate.

Move the section from this part:

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);
}

to here:

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);
}

Since we don't have access to the web service you're using, and assuming the data is correctly returned, I had to uncomment the predefined data to make a working demo:

Updated jsbin

Answer

I worked from your Source Code Reference Fiddle, which worked pretty ok to me.

Added a couple of things:

First of a seperate function to add a user to the users array. This way, users can easily be added after a successful webservice call.

Second, addded a couple of helper functions to get random positions and directions.

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

When you connect your webservice, you can ditch the getRandomConnections function and reference. In your webservice success callback, make sure you have an object in the format:

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

Pass that object to the addUser function.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.