androiddelphiandroid-animationdelphi-10.1-berlinc++builder-10.1-berlin

How to make the Google loading spinner with TArc?


I'm considering to put a loading animation and a progress arc in a single object (like WhatsApp when loading a record), so I thought it was better to use TArc and TFloatAnimation, since I can control the StartAngle and EndAngle of the stroke. I'm trying to make the Google loading spinner logic but I'm very confused, it looks like there is a FloatAnimation with "linear" interpolation property that controls one of the angles and another one that looks to have a exponential or sinusoidal interpolation that start/end very fast and I can't see it, anyone had already tried to reproduce it? Thanks.

Image from web: enter image description here


Solution

  • Requirement to make this:

    I find that you calling it a spinner is wrong. It's a spring in a harmonic motion plus a rotation effect.

    This is the effect if you don't know it

    enter image description here

    You could read about it in Wikipedia (Warning it's written in French)

    Now to solve this problem you need to define an array which will hold the values of the potential energy required to compress and stretch the spring.

    PotentialEnergy: array[0..10] of Single;
    

    The animation you are seeing is this

    enter image description here

    the spring stretching then getting compressed again. And in order to make it rotate we will define a rotation speed

    RotationSpeed : Single;  
    

    and the finale animation would look like this

    enter image description here

    This is final implementation of this animation:

    var
      Form6: TForm6;
      Increment: Integer;
      PotentialEnergy: array[0..10] of Single;
      ReverseMotion : Boolean;
      RotationSpeed : Single;
    implementation
    
    {$R *.fmx}
    
    procedure SetArray(var aData: array of Single; const aSource: array of Single);
    var
      I: Integer;
    begin
      for I := Low(aSource) to High(aSource) do
        begin
        aData[I] := aSource[I];
        end;
    end;
    
    procedure TForm6.Button1Click(Sender: TObject);
    begin
      SetArray(PotentialEnergy, [5, 64, 48, 32, 24, 16, 14, 10, 8, 7]);
      Increment := -1;
      ReverseMotion := False;
      arc1.StartAngle := 0;
      arc1.EndAngle := 1;
      RotationSpeed := strtoint(edit1.text); // Degrees per 0.1 second
      timer1.Enabled := True;
    end;
    
    procedure TForm6.Timer1Timer(Sender: TObject);
    begin
      if not ReverseMotion then
        begin
        Inc(Increment);
        arc1.EndAngle := arc1.EndAngle + PotentialEnergy[Increment];
        arc1.StartAngle := arc1.StartAngle + RotationSpeed;
        end
      else
        begin
        Inc(Increment);
        arc1.StartAngle := arc1.StartAngle + PotentialEnergy[Increment] + RotationSpeed;
        arc1.EndAngle := arc1.EndAngle - PotentialEnergy[Increment];
        end;
    
     if (Increment > 10)then
        begin
        ReverseMotion  := not ReverseMotion;
        Increment := -1;
        end;
    end;
    

    Also you could create animation like these

    enter image description here

    enter image description here


    Update: after some synchronization(don't ask me how)

    I found the could be exact replica of that google animation

    Steps:

    and the result is this (the google animation on the right)

    enter image description here