Skip to content

Commit b3c5dd8

Browse files
committed
update bezier animation classes
1 parent 4b90bbd commit b3c5dd8

File tree

4 files changed

+99
-10
lines changed

4 files changed

+99
-10
lines changed

ComponentsSource/FMX.BezierAnimation.pas

+63-6
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ TBezier = class
2929
epsilon = 1.0E-5;
3030
private
3131
ax, bx, cx, ay, by, cy: Double;
32+
x1, y1, x2, y2: Double;
3233
public
3334
constructor Create(p1x, p1y, p2x, p2y: Double);
3435
procedure SetData(p1x, p1y, p2x, p2y: Double);
@@ -37,6 +38,11 @@ TBezier = class
3738
function SampleCurveDerivativeX(t: Double): Double;
3839
function SolveCurveX(x, epsilon: Double): Double;
3940
function Solve(x, epsilon: Double): Double;
41+
class function GetLinear: TBezier;
42+
class function GetEase: TBezier;
43+
class function GetEaseIn: TBezier;
44+
class function GetEaseOut: TBezier;
45+
class function GetEaseInOut: TBezier;
4046
end;
4147

4248
[ComponentPlatformsAttribute(TFMXPlatforms)]
@@ -58,6 +64,7 @@ TFMXBezierAnimation = class(TFloatAnimation)
5864
constructor Create(AOwner: TComponent); override;
5965
destructor Destroy; override;
6066
procedure SetData(p1x, p1y, p2x, p2y: Double);
67+
procedure SetBezier(bezier: TBezier);
6168
function BezierTime: Single;
6269
published
6370
property P1X: Double read FP1X write SetP1X;
@@ -66,11 +73,13 @@ TFMXBezierAnimation = class(TFloatAnimation)
6673
property P2Y: Double read FP2Y write SetP2Y;
6774
end;
6875

69-
function GetEaseInOut: TBezier;
70-
7176
implementation
7277

7378
var
79+
Linear: TBezier = nil;
80+
Ease: TBezier = nil;
81+
EaseIn: TBezier = nil;
82+
EaseOut: TBezier = nil;
7483
EaseInOut: TBezier = nil;
7584

7685
type
@@ -79,18 +88,49 @@ TAnimationHelper = class helper for TAnimation
7988
function GetDelayTime: Single;
8089
end;
8190

82-
function GetEaseInOut: TBezier;
91+
{ TBezier }
92+
93+
constructor TBezier.Create(p1x, p1y, p2x, p2y: Double);
94+
begin
95+
SetData(p1x, p1y, p2x, p2y);
96+
end;
97+
98+
class function TBezier.GetEase: TBezier;
99+
begin
100+
if not Assigned(Ease) then
101+
Ease := TBezier.Create(0.25,0.1,0.25,1);
102+
Result := Ease;
103+
end;
104+
105+
class function TBezier.GetEaseIn: TBezier;
106+
begin
107+
if not Assigned(EaseInOut) then
108+
EaseInOut := TBezier.Create(0.42,0,1,1);
109+
Result := EaseIn;
110+
end;
111+
112+
113+
class function TBezier.GetEaseInOut: TBezier;
83114
begin
84115
if not Assigned(EaseInOut) then
85116
EaseInOut := TBezier.Create(0.42,0,0.58,1);
86117
Result := EaseInOut;
87118
end;
88119

89-
{ TBezier }
90120

91-
constructor TBezier.Create(p1x, p1y, p2x, p2y: Double);
121+
class function TBezier.GetEaseOut: TBezier;
92122
begin
93-
SetData(p1x, p1y, p2x, p2y);
123+
if not Assigned(EaseInOut) then
124+
EaseInOut := TBezier.Create(0,0,0.58,1);
125+
Result := EaseOut;
126+
end;
127+
128+
129+
class function TBezier.GetLinear: TBezier;
130+
begin
131+
if not Assigned(Linear) then
132+
Linear := TBezier.Create(0, 0, 1, 1);
133+
Result := Linear;
94134
end;
95135

96136
function TBezier.SampleCurveDerivativeX(t: Double): Double;
@@ -111,6 +151,10 @@ function TBezier.SampleCurveY(t: Double): Double;
111151

112152
procedure TBezier.SetData(p1x, p1y, p2x, p2y: Double);
113153
begin
154+
x1 := p1x;
155+
y1 := p1y;
156+
x2 := p2x;
157+
y2 := p2y;
114158
// Calculate the polynomial coefficients, implicit first and last control points are (0,0) and (1,1).
115159
cx := 3.0 * p1x;
116160
bx := 3.0 * (p2x - p1x) - cx;
@@ -215,6 +259,15 @@ procedure TFMXBezierAnimation.ProcessAnimation;
215259
end;
216260
end;
217261

262+
procedure TFMXBezierAnimation.SetBezier(bezier: TBezier);
263+
begin
264+
FP1X := bezier.x1;
265+
FP1Y := bezier.y1;
266+
FP2X := bezier.x2;
267+
FP2Y := bezier.y2;
268+
FBezier.SetData(bezier.x1, bezier.y1, bezier.x2, bezier.y2);
269+
end;
270+
218271
procedure TFMXBezierAnimation.SetData(p1x, p1y, p2x, p2y: Double);
219272
begin
220273
FP1X := p1x;
@@ -275,5 +328,9 @@ function TAnimationHelper.GetDelayTime: Single;
275328

276329
initialization
277330
finalization
331+
Linear.Free;
332+
Ease.Free;
333+
EaseIn.Free;
334+
EaseOut.Free;
278335
EaseInOut.Free;
279336
end.

ComponentsSource/FMX.LoadingIndicator.pas

+4-4
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ procedure TFMXLoadingIndicator.DrawInnerLineSpinFade;
396396
Path := TPathData.Create;
397397
try
398398
T := GetNormalizedAnimationTime;
399-
Ani := GetEaseInOut;
399+
Ani := TBezier.GetEaseInOut;
400400
for I := 0 to 7 do
401401
begin
402402
TI := T + (7 - I) * 0.1;
@@ -555,7 +555,7 @@ procedure TFMXLoadingIndicator.DrawBallClipRotateMultiple;
555555
Ani: TBezier;
556556
begin
557557
P := LocalRect.CenterPoint;
558-
Ani := GetEaseInOut;
558+
Ani := TBezier.GetEaseInOut;
559559
T := GetNormalizedAnimationTime;
560560
CalcAS(Ani, T, A1, S1);
561561
T := T * 2 - Trunc(T * 2);
@@ -794,7 +794,7 @@ procedure TFMXLoadingIndicator.DrawLineScalePulseOut;
794794
W := (Width - 20) / 5;
795795
H := Height;
796796
Space := 0;
797-
Ani := GetEaseInOut;
797+
Ani := TBezier.GetEaseInOut;
798798
for I := 0 to 4 do
799799
begin
800800
case I of
@@ -836,7 +836,7 @@ procedure TFMXLoadingIndicator.DrawLineScalePulseOutRapid;
836836
W := (Width - 20) / 5;
837837
H := Height;
838838
Space := 0;
839-
Ani := GetEaseInOut;
839+
Ani := TBezier.GetEaseInOut;
840840
for I := 0 to 4 do
841841
begin
842842
case I of

Demo/FMXComponentsDemo.res

8 Bytes
Binary file not shown.

Documents/FMXBezierAnimation.md

+32
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,35 @@ use these code to set the cubic-bezier parameters
1010
BezierAnimation1.SetData(X1, Y1, X2, Y2);
1111
BezierAnimation1.Start;
1212
```
13+
14+
This is the interface of TBezier
15+
```pascal
16+
TBezier = class
17+
public
18+
constructor Create(p1x, p1y, p2x, p2y: Double);
19+
procedure SetData(p1x, p1y, p2x, p2y: Double);
20+
function SampleCurveX(t: Double): Double;
21+
function SampleCurveY(t: Double): Double;
22+
function SampleCurveDerivativeX(t: Double): Double;
23+
function SolveCurveX(x, epsilon: Double): Double;
24+
function Solve(x, epsilon: Double): Double;
25+
class function GetLinear: TBezier;
26+
class function GetEase: TBezier;
27+
class function GetEaseIn: TBezier;
28+
class function GetEaseOut: TBezier;
29+
class function GetEaseInOut: TBezier;
30+
end;
31+
```
32+
33+
there are 5 predefined bezier curves, linear, ease, ease-in, ease-out, ease-in-out, you can call corresponding class function to get the curve.
34+
35+
```pascal
36+
Ani := TBezier.GetEaseInOut;
37+
BezierAnimation1.SetBezier(Ani);
38+
```
39+
40+
or you can defined your curve
41+
42+
```pascal
43+
Ani := TBezier.Create(p1x, p1y, p2x, p2y);
44+
```

0 commit comments

Comments
 (0)