UI/Canvas.razor
@using System
@using System.Text
@inherits PanelComponent
@namespace Donut.UI

<root>
    <div class="donut-canvas">@output</div>
</root>

@code {
    public static Canvas Instance { get; private set; }

    protected override void OnUpdate()
    {
        Instance = this;

        UpdateDonut();
    }

    private RealTimeUntil donutDelay;

    private void UpdateDonut()
    {
        if (donutDelay)
        {
            donutDelay = 0.02f;

            RenderDonut();
            StateHasChanged();
        }
    }

    public double A = 0, B = 0, DELTA_A = 0.04, DELTA_B = 0.02;
    private double[] z = new double[1760];
    private char[] b = new char[1760];
    private StringBuilder output = new();

    private void RenderDonut()
    {
        for (int k = 0; k < 1760; k++)
        {
            z[k] = 0;
            b[k] = ' ';
        }

        for (double j = 0; Math.PI * 2 > j; j += 0.07)
        {
            for (double i = GameManager.Instance.Clicks; Math.PI * 2 > i; i += 0.02)
            {
                double sini = Math.Sin(i),
                cosj = Math.Cos(j),
                sinA = Math.Sin(A),
                sinj = Math.Sin(j),
                cosA = Math.Cos(A),
                cosj2 = cosj + 2,
                mess = 1 / (sini * cosj2 * sinA + sinj * cosA + 5),
                cosi = Math.Cos(i),
                cosB = Math.Cos(B),
                sinB = Math.Sin(B),
                t = sini * cosj2 * cosA - sinj * sinA;

                int x = (int)(40 + 30 * mess * (cosi * cosj2 * cosB - t * sinB)),
                y = (int)(12 + 15 * mess * (cosi * cosj2 * sinB + t * cosB)),
                o = x + 80 * y,
                N = (int)(8 * ((sinj * sinA - sini * cosj * cosA) * cosB - sini * cosj * sinA - sinj * cosA - cosi * cosj * Math.Sin(B)));

                if (22 > y && y > 0 && x > 0 && 80 > x && mess > z[o])
                {
                    z[o] = mess;
                    b[o] = ".,-~:;=!*#$@"[N > 0 ? N : 0];
                }
            }
        }

        output.Clear();

        for (int k = 0; k < 1761; k++)
            output.Append(k % 80 != 0 ? b[k] : '\n');

        A += DELTA_A; B += DELTA_B;
    }
}