Skip to content

Commit

Permalink
Minor Update
Browse files Browse the repository at this point in the history
  • Loading branch information
Zeus64 committed Nov 29, 2024
1 parent 8d1a419 commit c4baefb
Show file tree
Hide file tree
Showing 6 changed files with 173 additions and 159 deletions.
125 changes: 99 additions & 26 deletions Source/Alcinoe.FMX.Ani.pas
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,9 @@ TChoreographerFrameCallback = class(TJavaLocal, JChoreographer_FrameCallback
FTimerEvent: TNotifyEvent;
FInterval: Cardinal;
FEnabled: Boolean;
procedure SetEnabled(const Value: Boolean);
procedure SetInterval(const Value: Cardinal);
protected
procedure SetEnabled(Value: Boolean); virtual;
procedure SetInterval(Value: Cardinal); virtual;
public
constructor Create(AOwner: TComponent); virtual;
destructor Destroy; override;
Expand Down Expand Up @@ -129,8 +130,9 @@ TDisplayLinkListener = class(TOCLocal)
FTimerEvent: TNotifyEvent;
FInterval: Cardinal;
FEnabled: Boolean;
procedure SetEnabled(const Value: Boolean);
procedure SetInterval(const Value: Cardinal);
protected
procedure SetEnabled(Value: Boolean); virtual;
procedure SetInterval(Value: Cardinal); virtual;
public
constructor Create(AOwner: TComponent); virtual;
destructor Destroy; override;
Expand All @@ -145,7 +147,6 @@ TALAniThread = class({$IF defined(ANDROID)}TALChoreographerThread{$ELSEIF defi
private
FAniList: TList<TALAnimation>;
FTime: Double;
procedure OneStep;
procedure DoSyncTimer(Sender: TObject);
public
constructor Create; reintroduce;
Expand All @@ -159,6 +160,9 @@ TALAnimation = class(TObject)
public const
DefaultAniFrameRate = 60;
public class var
// The AniFrameRate property is unnecessary on Android and iOS since
// the animation is synchronized with the system's Choreographer (Android)
// or DisplayLink (iOS)
AniFrameRate: Integer;
private class var
FAniThread: TALAniThread;
Expand Down Expand Up @@ -222,6 +226,19 @@ TALDisplayAnimation = class(TALAnimation)
procedure StopAtCurrent; override;
end;

{~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
TALDisplayTimer = class(TALDisplayAnimation)
private
FInterval: Single;
FIntervalTimeLeft: Single;
protected
procedure ProcessTick(const ATime, ADeltaTime: Double); override;
public
constructor Create; override;
procedure Start; override;
property Interval: Single read FInterval write FInterval;
end;

{~~~~~~~~~~~~~~~~~~~~~~}
TALInterpolationType = (
Linear,
Expand Down Expand Up @@ -904,8 +921,8 @@ destructor TALChoreographerThread.Destroy;
inherited;
end;

{****************************************************************}
procedure TALChoreographerThread.SetEnabled(const Value: Boolean);
{**********************************************************}
procedure TALChoreographerThread.SetEnabled(Value: Boolean);
begin
if FEnabled <> Value then begin
FEnabled := Value;
Expand All @@ -914,10 +931,10 @@ procedure TALChoreographerThread.SetEnabled(const Value: Boolean);
end;
end;

{******************************************************************}
procedure TALChoreographerThread.SetInterval(const Value: Cardinal);
{************************************************************}
procedure TALChoreographerThread.SetInterval(Value: Cardinal);
begin
FInterval := Max(Value, 1);
FInterval := Value;
end;

{$ENDIF}
Expand Down Expand Up @@ -989,8 +1006,8 @@ destructor TALDisplayLinkThread.Destroy;
inherited;
end;

{**************************************************************}
procedure TALDisplayLinkThread.SetEnabled(const Value: Boolean);
{********************************************************}
procedure TALDisplayLinkThread.SetEnabled(Value: Boolean);
begin
if FEnabled <> Value then begin
FEnabled := Value;
Expand All @@ -999,10 +1016,10 @@ procedure TALDisplayLinkThread.SetEnabled(const Value: Boolean);
end;
end;

{****************************************************************}
procedure TALDisplayLinkThread.SetInterval(const Value: Cardinal);
{**********************************************************}
procedure TALDisplayLinkThread.SetInterval(Value: Cardinal);
begin
FInterval := Max(Value, 1);
FInterval := Value;
end;

{$ENDIF}
Expand All @@ -1011,7 +1028,7 @@ procedure TALDisplayLinkThread.SetInterval(const Value: Cardinal);
constructor TALAniThread.Create;
begin
inherited Create(nil);
TALAnimation.AniFrameRate := EnsureRange(TALAnimation.AniFrameRate, 5, 100);
TALAnimation.AniFrameRate := EnsureRange(TALAnimation.AniFrameRate, 5, 120);
Interval := Trunc(1000 / TALAnimation.AniFrameRate / 10) * 10;
if (Interval <= 0) then
Interval := 1;
Expand Down Expand Up @@ -1050,16 +1067,7 @@ procedure TALAniThread.RemoveAnimation(const Ani: TALAnimation);
{**************************************************}
procedure TALAniThread.DoSyncTimer(Sender: TObject);
begin
OneStep;
if TALAnimation.AniFrameRate < 5 then
TALAnimation.AniFrameRate := 5;
Interval := Trunc(1000 / TALAnimation.AniFrameRate / 10) * 10;
if (Interval <= 0) then Interval := 1;
end;

{*****************************}
procedure TALAniThread.OneStep;
begin
{$IF not defined(ALDPK)}
var NewTime := ALElapsedTimeSecondsAsDouble;
var LDeltaTime := NewTime - FTime;
FTime := NewTime;
Expand All @@ -1075,6 +1083,7 @@ procedure TALAniThread.OneStep;
I := FAniList.Count - 1;
end;
end;
{$ENDIF}
end;

{******************************}
Expand Down Expand Up @@ -1215,6 +1224,70 @@ procedure TALDisplayAnimation.StopAtCurrent;
DoFinish;
end;

{*********************************}
constructor TALDisplayTimer.Create;
begin
inherited Create;
FInterval := 0.05;
end;

{*********************************************************************}
procedure TALDisplayTimer.ProcessTick(const ATime, ADeltaTime: Double);
begin
if (not FRunning) or FPause then
Exit;

if (FDelay > 0) and (FDelayTimeLeft <> 0) then begin
FDelayTimeLeft := FDelayTimeLeft - ADeltaTime;
if FDelayTimeLeft <= 0 then begin
FDelayTimeLeft := 0;
FirstFrame;
ProcessAnimation;
DoProcess;
end;
Exit;
end;

FIntervalTimeLeft := FIntervalTimeLeft - ADeltaTime;
if CompareValue(FIntervalTimeLeft, 0, 0.001) > 0 then exit;
FIntervalTimeLeft := FInterval;

FTime := FTime + ADeltaTime;

ProcessAnimation;
DoProcess;

if not FRunning then begin
if AniThread <> nil then
AniThread.RemoveAnimation(Self);
DoFinish;
end;
end;

{******************************}
procedure TALDisplayTimer.Start;
begin
if (FRunning) then
Exit;
FEnabled := True;
FRunning := True;
FTime := 0;
FIntervalTimeLeft := FInterval;
FDelayTimeLeft := FDelay;
if FDelay = 0 then begin
FirstFrame;
ProcessAnimation;
DoProcess;
end;

if AniThread = nil then
FAniThread := TALAniThread.Create;

AniThread.AddAnimation(Self);
if not AniThread.Enabled then
Stop;
end;

{******************************************}
constructor TALInterpolatedAnimation.Create;
begin
Expand Down
1 change: 1 addition & 0 deletions Source/Alcinoe.FMX.Common.pas
Original file line number Diff line number Diff line change
Expand Up @@ -5272,6 +5272,7 @@ function ALGetResourceFilename(const AResourceName: String): String;
if not TFile.Exists(Result) then begin
if TFile.Exists(Result + '.png') then Result := Result + '.png'
else if TFile.Exists(Result + '.jpg') then Result := Result + '.jpg'
else if TFile.Exists(Result + '.json') then Result := Result + '.json' // Skottie - Lottie Animation
else Result := '';
end;
end;
Expand Down
50 changes: 21 additions & 29 deletions Source/Alcinoe.FMX.Confetti.pas
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ TParticule = record
FOriginalOnPaint: TOnPaintEvent;
FOnFinish: TNotifyEvent;
FParticules: TList<TParticule>;
FTimer: {$IF defined(ANDROID)}TALChoreographerThread{$ELSEIF defined(IOS)}TALDisplayLinkThread{$ELSE}TTimer{$ENDIF};
function updateParticule(const ACanvas: TCanvas; const ARect: TRectF; var AParticule: TParticule): boolean;
function randomPhysics(
FDisplayAnimation: TALDisplayAnimation;
function UpdateParticule(const ACanvas: TCanvas; const ARect: TRectF; var AParticule: TParticule): boolean;
function RandomPhysics(
const AX: Single;
const AY: Single;
const AAngle: Single;
Expand All @@ -69,9 +69,9 @@ TParticule = record
const AGravity: Single;
const ADrift: Single;
const AScalar: Single): TParticule;
procedure onTimer(Sender: TObject);
procedure onPaint(Sender: TObject; Canvas: TCanvas; const ARect: TRectF);
function getParticuleCount: integer;
procedure OnDisplayAnimationProcess(Sender: TObject);
procedure OnPaint(Sender: TObject; Canvas: TCanvas; const ARect: TRectF);
function GetParticuleCount: integer;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
Expand All @@ -90,7 +90,7 @@ TParticule = record
const AGravity: Single = 1; // How quickly the particles are pulled down. 1 is full gravity, 0.5 is half gravity, etc., but there are no limits. You can even make particles go up if you'd like.
const ADrift: Single = 0; // How much to the side the confetti will drift. The default is 0, meaning that they will fall straight down. Use a negative number for left and positive number for right.
const AScalar: Single = 1); // Scale factor for each confetti particle. Use decimals to make the confetti smaller. Go on, try teeny tiny confetti, they are adorable!
Property ParticuleCount: integer read getParticuleCount;
Property ParticuleCount: integer read GetParticuleCount;
published
property OnFinish: TNotifyEvent read FOnFinish write FOnFinish;
End;
Expand All @@ -111,29 +111,21 @@ constructor TALConfetti.Create(AOwner: TComponent);
FOriginalOnPaint := nil;
FOnFinish := nil;
Fparticules := TList<TParticule>.create;
{$IF defined(ANDROID)}
FTimer := TALChoreographerThread.Create(nil);
{$ELSEIF defined(IOS)}
FTimer := TALDisplayLinkThread.Create(nil);
{$ELSE}
FTimer := TTimer.Create(nil);
{$ENDIF}
FTimer.Enabled := False;
Ftimer.Interval := Trunc(1000 / TALAnimation.AniFrameRate / 10) * 10;
if (Ftimer.Interval <= 0) then Ftimer.Interval := 1;
FTimer.OnTimer := OnTimer;
FDisplayAnimation := TALDisplayAnimation.Create;
FDisplayAnimation.Enabled := False;
FDisplayAnimation.OnProcess := OnDisplayAnimationProcess;
end;

{*****************************}
destructor TALConfetti.Destroy;
begin
AlFreeAndNil(FParticules);
AlFreeAndNil(FTimer);
AlFreeAndNil(FDisplayAnimation);
inherited;
end;

{*********************************************************************************************************************}
function TALConfetti.updateParticule(const ACanvas: TCanvas; const ARect: TRectF; Var AParticule: TParticule): boolean;
function TALConfetti.UpdateParticule(const ACanvas: TCanvas; const ARect: TRectF; Var AParticule: TParticule): boolean;
begin
AParticule.x := AParticule.x + (Cos(AParticule.angle2D) * AParticule.velocity + AParticule.drift);
AParticule.y := AParticule.y + (Sin(AParticule.angle2D) * AParticule.velocity + AParticule.gravity);
Expand Down Expand Up @@ -243,15 +235,15 @@ function TALConfetti.randomPhysics(
Result.scalar := Ascalar;
end;

{*********************************************}
procedure TALConfetti.onTimer(Sender: TObject);
{***************************************************************}
procedure TALConfetti.OnDisplayAnimationProcess(Sender: TObject);
begin
if Parent is TCustomForm then TCustomForm(Parent).Invalidate
else if Parent is Tcontrol then Tcontrol(Parent).Repaint;
end;

{***********************************************************************************}
procedure TALConfetti.onPaint(Sender: TObject; Canvas: TCanvas; const ARect: TRectF);
procedure TALConfetti.OnPaint(Sender: TObject; Canvas: TCanvas; const ARect: TRectF);
begin
if assigned(FOriginalOnPaint) then FOriginalOnPaint(Sender, Canvas, ARect);
for var i := FParticules.Count - 1 downto 0 do begin
Expand All @@ -260,8 +252,8 @@ procedure TALConfetti.onPaint(Sender: TObject; Canvas: TCanvas; const ARect: TRe
else FParticules[i] := LParticule;
end;
if FParticules.Count = 0 then begin
onTimer(nil);
Ftimer.Enabled := false;
OnDisplayAnimationProcess(nil);
FDisplayAnimation.Enabled := false;
if Parent is TCustomForm then TCustomForm(Parent).OnPaint := FOriginalOnPaint
else if Parent is Tcontrol then Tcontrol(Parent).OnPaint := FOriginalOnPaint;
FOriginalOnPaint := nil;
Expand Down Expand Up @@ -292,7 +284,7 @@ procedure TALConfetti.Fire(
var LCustomForm := TCustomForm(Parent);
if not isRunning then begin
FOriginalOnPaint := LCustomForm.OnPaint;
LCustomForm.OnPaint := onPaint;
LCustomForm.OnPaint := OnPaint;
end;
LStartX := LCustomForm.width * AOriginX;
LStartY := LCustomForm.height * AOriginY;
Expand All @@ -301,7 +293,7 @@ procedure TALConfetti.Fire(
var LControl := Tcontrol(Parent);
if not isRunning then begin
FOriginalOnPaint := LControl.OnPaint;
LControl.OnPaint := onPaint;
LControl.OnPaint := OnPaint;
end;
LStartX := LControl.width * AOriginX;
LStartY := LControl.height * AOriginY;
Expand Down Expand Up @@ -342,7 +334,7 @@ procedure TALConfetti.Fire(
ADrift, // const ADrift: Single;
AScalar)); // const AScalar: Single)

FTimer.Enabled := true;
FDisplayAnimation.Enabled := true;

end;

Expand All @@ -355,7 +347,7 @@ function TALConfetti.getParticuleCount: integer;
{**************************************}
function TALConfetti.isRunning: Boolean;
begin
result := FTimer.Enabled;
result := FDisplayAnimation.Enabled;
end;

{*****************}
Expand Down
Loading

0 comments on commit c4baefb

Please sign in to comment.