2

I am trying to animate a circle svg with Blazor. I have seen this done with the Tetris game so it should be possible i just cant figure out how to get it working.

<svg width="600" height="400">
    <Ball Height="@Ball.Height" Width="@Ball.Width" CurrentPosition="@Ball.CurrentPosition"></Ball>
</svg>

<button class="btn btn-primary" @onclick="@Bounce">bounce</button>

Component

@inherits BallModel;
@using Blong.Client.Model

<circle cx="@CurrentPosition.X" cy="@CurrentPosition.Y" r="@Radius" style="@Style" />

bounce code

 void Bounce()
    {
        for (int i = 0; i < 1000; i++)
        {
            Task.Run(() => SetPosition(Ball.CurrentPosition.X, Ball.CurrentPosition.Y++, GameHeight));
        }
    }

    public async Task<bool> SetPosition(int x, int y, int LastRow)
    {

        if (y <= LastRow)
        {
            Ball.CurrentPosition.Y++;
            Thread.Sleep(500);
            return true;
        }

        return false;

    }

This does kind of work. Every time i push the button my ball hops to the new position. Is there some way to get this to reload as it goes though the loop? I am trying to see my ball moving around the screen.

Linda Lawton - DaImTo
  • 106,405
  • 32
  • 180
  • 449

1 Answers1

1

Basically it should be enough to notify the Blazor to update the UI within the loop:

StateHasChanged();

But there are few things. First the SetPosition method doesn’t contain any awaits and would be run synchronously.

Then the Bounce could be made async, instead of creating new Tasks on your own, in case you don’t want to block the main Thread.

Also the GameHeight seems like a constant or static within a current View’s state and as such I would directly reference it within the called method, instead of passing it as a parameter, but that is just a personal opinion.

Another thing would be, to make sure the Bounce is not called multiple times while already „bouncing“.

And I think the logic coils be simplified a bit.

Here is my suggestion:

public async Task Bounce()
{
  if(Bouncing) return;

  Bouncing = true;

  while(Ball.CurrentPosition.Y <= GameHeight)
  {
    Ball.CurrentPosition.Y++;
    StateHasChanged();
    await Task.Delay(500);
  }
// in case View has been resized, make sure Ball is not out of boundaries
  Ball.CurrentPosition.Y = GameHeight;
  StateHasChanged();
  Bouncing = false;
}
Raul
  • 2,745
  • 1
  • 23
  • 39