我正在尝试在TChromeTabs中实现标签的流畅移动。我可以在这里看到缓动公式,但我不是数学家,也不知道如何将其转换为代码。到目前为止,我的尝试无济于事。
是否有可用的缓动功能的 Delphi 实现?
我正在尝试在TChromeTabs中实现标签的流畅移动。我可以在这里看到缓动公式,但我不是数学家,也不知道如何将其转换为代码。到目前为止,我的尝试无济于事。
是否有可用的缓动功能的 Delphi 实现?
我在网上找到了几个有用的示例,并使用这些算法编写了我自己的 Delphi Easing 函数。他们来了:
...
type
TChromeTabsEaseType = (
ttlinearTween,
tteaseInQuad,
tteaseOutQuad,
tteaseInOutQuad,
tteaseInCubic,
tteaseOutCubic,
tteaseInOutCubic,
tteaseInQuart,
tteaseOutQuart,
tteaseInOutQuart,
tteaseInQuint,
tteaseOutQuint,
tteaseInOutQuint,
tteaseInSine,
tteaseOutSine,
tteaseInOutSine,
tteaseInExpo,
tteaseOutExpo,
tteaseInOutExpo,
tteaseInCirc,
tteaseOutCirc,
tteaseInOutCirc
);
function CalculateEase(CurrentTime, StartValue, ChangeInValue, Duration: Real; EaseType: TChromeTabsEaseType): Real; overload;
function CalculateEase(StartPos, EndPos, PositionPct: Real; EaseType: TChromeTabsEaseType): Real; overload;
implementation
function CalculateEase(CurrentTime, StartValue, ChangeInValue, Duration: Real; EaseType: TChromeTabsEaseType): Real;
begin
case EaseType of
ttLinearTween:
begin
Result := ChangeInValue * CurrentTime / Duration + StartValue;
end;
ttEaseInQuad:
begin
CurrentTime := CurrentTime / Duration;
Result := ChangeInValue * CurrentTime * CurrentTime + StartValue;
end;
ttEaseOutQuad:
begin
CurrentTime := CurrentTime / Duration;
Result := -ChangeInValue * CurrentTime * (CurrentTime-2) + StartValue;
end;
ttEaseInOutQuad:
begin
CurrentTime := CurrentTime / (Duration / 2);
if CurrentTime < 1 then
Result := ChangeInValue / 2 * CurrentTime * CurrentTime + StartValue
else
begin
CurrentTime := CurrentTime - 1;
Result := -ChangeInValue / 2 * (CurrentTime * (CurrentTime - 2) - 1) + StartValue;
end;
end;
ttEaseInCubic:
begin
CurrentTime := CurrentTime / Duration;
Result := ChangeInValue * CurrentTime * CurrentTime * CurrentTime + StartValue;
end;
ttEaseOutCubic:
begin
CurrentTime := (CurrentTime / Duration) - 1;
Result := ChangeInValue * ( CurrentTime * CurrentTime * CurrentTime + 1) + StartValue;
end;
ttEaseInOutCubic:
begin
CurrentTime := CurrentTime / (Duration/2);
if CurrentTime < 1 then
Result := ChangeInValue / 2 * CurrentTime * CurrentTime * CurrentTime + StartValue
else
begin
CurrentTime := CurrentTime - 2;
Result := ChangeInValue / 2 * (CurrentTime * CurrentTime * CurrentTime + 2) + StartValue;
end;
end;
ttEaseInQuart:
begin
CurrentTime := CurrentTime / Duration;
Result := ChangeInValue * CurrentTime * CurrentTime * CurrentTime * CurrentTime + StartValue;
end;
ttEaseOutQuart:
begin
CurrentTime := (CurrentTime / Duration) - 1;
Result := -ChangeInValue * (CurrentTime * CurrentTime * CurrentTime * CurrentTime - 1) + StartValue;
end;
ttEaseInOutQuart:
begin
CurrentTime := CurrentTime / (Duration / 2);
if CurrentTime < 1 then
Result := ChangeInValue / 2 * CurrentTime * CurrentTime * CurrentTime * CurrentTime + StartValue
else
begin
CurrentTime := CurrentTime - 2;
Result := -ChangeInValue / 2 * (CurrentTime * CurrentTime * CurrentTime * CurrentTime - 2) + StartValue;
end;
end;
ttEaseInQuint:
begin
CurrentTime := CurrentTime / Duration;
Result := ChangeInValue * CurrentTime * CurrentTime * CurrentTime * CurrentTime * CurrentTime + StartValue;
end;
ttEaseOutQuint:
begin
CurrentTime := (CurrentTime / Duration) - 1;
Result := ChangeInValue * (CurrentTime * CurrentTime * CurrentTime * CurrentTime * CurrentTime + 1) + StartValue;
end;
ttEaseInOutQuint:
begin
CurrentTime := CurrentTime / (Duration / 2);
if CurrentTime < 1 then
Result := ChangeInValue / 2 * CurrentTime * CurrentTime * CurrentTime * CurrentTime * CurrentTime + StartValue
else
begin
CurrentTime := CurrentTime - 2;
Result := ChangeInValue / 2 * (CurrentTime * CurrentTime * CurrentTime * CurrentTime * CurrentTime + 2) + StartValue;
end;
end;
ttEaseInSine:
begin
Result := -ChangeInValue * Cos(CurrentTime / Duration * (PI / 2)) + ChangeInValue + StartValue;
end;
ttEaseOutSine:
begin
Result := ChangeInValue * Sin(CurrentTime / Duration * (PI / 2)) + StartValue;
end;
ttEaseInOutSine:
begin
Result := -ChangeInValue / 2 * (Cos(PI * CurrentTime / Duration) - 1) + StartValue;
end;
ttEaseInExpo:
begin
Result := ChangeInValue * Power(2, 10 * (CurrentTime/Duration - 1) ) + StartValue;
end;
ttEaseOutExpo:
begin
Result := ChangeInValue * (-Power(2, -10 * CurrentTime / Duration ) + 1 ) + StartValue;
end;
ttEaseInOutExpo:
begin
CurrentTime := CurrentTime / (Duration/2);
if CurrentTime < 1 then
Result := ChangeInValue / 2 * Power(2, 10 * (CurrentTime - 1) ) + StartValue
else
begin
CurrentTime := CurrentTime - 1;
Result := ChangeInValue / 2 * (-Power(2, -10 * CurrentTime) + 2 ) + StartValue;
end;
end;
ttEaseInCirc:
begin
CurrentTime := CurrentTime / Duration;
Result := -ChangeInValue * (Sqrt(1 - CurrentTime * CurrentTime) - 1) + StartValue;
end;
ttEaseOutCirc:
begin
CurrentTime := (CurrentTime / Duration) - 1;
Result := ChangeInValue * Sqrt(1 - CurrentTime * CurrentTime) + StartValue;
end;
ttEaseInOutCirc:
begin
CurrentTime := CurrentTime / (Duration / 2);
if CurrentTime < 1 then
Result := -ChangeInValue / 2 * (Sqrt(1 - CurrentTime * CurrentTime) - 1) + StartValue
else
begin
CurrentTime := CurrentTime - 2;
Result := ChangeInValue / 2 * (Sqrt(1 - CurrentTime * CurrentTime) + 1) + StartValue;
end;
end;
end;
end;
function CalculateEase(StartPos, EndPos, PositionPct: Real; EaseType: TChromeTabsEaseType): Real;
var
t, b, c, d: Real;
begin
c := EndPos - StartPos;
d := 100;
t := PositionPct;
b := StartPos;
Result := CalculateEase(t, b, c, d, EaseType);
end;
...