IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

Les interpolations et fonctions d'easing avec Lazarus, effet d'élastique, aller-retour et rebonds
Un billet de Gilles Vasseur

Le , par gvasseur58

0PARTAGES

Les fonctions avec effet d'élastique, aller-retour ou rebond produisent les effets d'easing les plus spectaculaires. Ce sont aussi elles qui font appel à des constantes énigmatiques, mais qui trouvent leur origine dans des calculs complexes très peu (voire pas) documentés : il faudra par conséquent accepter ses constantes parfois modulables et se réjouir de leur effet !

Les fonctions à effet d'élastique

Bien sûr, les fonctions de la catégorie Elastic sont plutôt complexes. Elles s'appuient à la fois sur le caractère amplificateur des puissances de 2 et sur les cycles créés par la fonction sinus :

function TMainForm.EaseInElastic(AStart, AChange, AStep: Single): Single;
// *** INELASTIC ***
begin
if AStep = 0 then
Result := AStart
else
begin
AStep := AStep / fDuration;
if AStep = 1 then
Result := AChange + AStart
else
begin
AStep := AStep - 1;
Result := - (AChange * Power(2, 10 * AStep) * sin((AStep * fDuration
- (fDuration * 0.3 / 4)) * 2 * Pi / (fDuration * 0.3))) + AStart;
end;
end;
end;

function TMainForm.EaseOutElastic(AStart, AChange, AStep: Single): Single;
// *** OUTELASTIC ***
begin
if AStep = 0 then
Result := AStart
else
begin
AStep := AStep / fDuration;
if AStep = 1 then
Result := AChange + AStart
else
Result := AChange * Power(2, - 10 * AStep) * sin((AStep * fDuration -
(fDuration * 0.3 / 4)) * 2 * Pi / (fDuration * 0.3)) + AChange + AStart;
end;
end;

function TMainForm.EaseInOutElastic(AStart, AChange, AStep: Single): Single;
// *** INOUTELASTIC ***
begin
if AStep = 0 then
Result := AStart
else
begin
AStep := AStep / fDuration * 2;
if AStep = 2 then
Result := AChange + AStart
else
begin
// 0.45 = 0.3*1.5 0.1125 = 0.45 / 4
if AStep < 1 then
begin
AStep := AStep - 1;
Result := - (AChange * Power(2, 10 * AStep) * sin((AStep * fDuration -
fDuration * 0.1125) * 2 * Pi / (fDuration * 0.45))) / 2 + AStart;
end
else
begin
AStep := AStep - 1;
Result := AChange * Power(2, - 10 * AStep) * sin((AStep * fDuration -
fDuration * 0.1125) * 2 * Pi / (fDuration * 0.45)) / 2 + AChange + AStart;
end;
end;
end;
end;

function TMainForm.EaseOutInElastic(AStart, AChange, AStep: Single): Single;
// *** OUTINELASTIC ***
begin
if AStep < fDuration / 2 then
Result := EaseOutElastic(AStart, AChange / 2, AStep * 2)
else
Result := EaseInElastic(AStart + AChange / 2, AChange / 2, AStep * 2 - fDuration);
end;


Les fonctions avec aller-retour

Les fonctions relatives à la catégorie Back complexifient encore les calculs. Nous les implémenterons en prenant une valeur correspondant à un rebond de 10%, mais d'autres valeurs indiquées dans le code sont utilisables : comme nous l'avons annoncé, ces nombres mystérieux cachent en fait des calculs plutôt fastidieux qui permettent de calculer l'amplitude des allers-retours.

Voici l'implémentation adoptée :

function TMainForm.EaseInBack(AStart, AChange, AStep: Single): Single;
// *** INBACK ***
begin
// 1.70158 = 10% 2.592389 = 20% 3.394051 = 30% 4.15574465 = 40%
Result := AChange * Power(AStep / fDuration, 2) * (2.70158 *
AStep / fDuration - 1.70158) + AStart;
end;

function TMainForm.EaseOutBack(AStart, AChange, AStep: Single): Single;
// *** OUTBACK ***
begin
Result := AChange * (Power(AStep / fDuration - 1, 2) *
(2.70158 * (AStep / fDuration - 1) + 1.70158) + 1) + AStart;
end;

function TMainForm.EaseInOutBack(AStart, AChange, AStep: Single): Single;
// *** INOUTBACK ***
begin
// 2.5949095 = 1.70158 * 1.525
AStep := AStep / fDuration * 2;
if AStep < 1 then
Result := AChange / 2 * Power(AStep, 2) * (3.594905 * AStep - 2.594905)
+ AStart
else
Result := AChange / 2 * (Power(AStep - 2, 2) * (3.594905 * (AStep - 2)
+ 2.594905) + 2) + AStart;
end;

function TMainForm.EaseOutInBack(AStart, AChange, AStep: Single): Single;
// *** OUTINBACK ***
begin
if AStep < fDuration / 2 then
Result := EaseOutBack(AStart, AChange / 2, AStep * 2)
else
Result := EaseInBack(AStart + AChange / 2, AChange / 2, AStep * 2 - fDuration);
end;

Les fonctions avec rebond


Enfin, les fonctions relatives à la catégorie Bounce sont les plus longs. Il faut en effet calculer chaque étape afin d'obtenir les résultats les plus proches possibles de rebonds qui paraissent naturels.

Voici l'implémentation adoptée :

function TMainForm.EaseInOutBounce(AStart, AChange, AStep: Single): Single;
// *** INOUTBOUNCE ***
begin
if AStep < fDuration / 2 then
Result := EaseInBounce(0, AChange, AStep * 2) / 2 + AStart
else
Result := EaseOutBounce(0, AChange, AStep * 2 - fDuration) / 2 + AChange / 2
+ AStart;
end;

function TMainForm.EaseOutInBounce(AStart, AChange, AStep: Single): Single;
// *** OUTINBOUNCE ***
begin
if AStep < fDuration / 2 then
Result := EaseOutBounce(AStart, AChange / 2, AStep * 2)
else
Result := EaseInBounce(AStart + AChange / 2, AChange / 2, AStep * 2 - fDuration);
end;

function TMainForm.EaseInBounce(AStart, AChange, AStep: Single): Single;
// *** INBOUNCE ***
begin
Result := AChange - EaseOutBounce(0, AChange, fDuration - AStep) + AStart;
end;

function TMainForm.EaseOutBounce(AStart, AChange, AStep: Single): Single;
// *** OUTBOUNCE ***
begin
AStep := AStep / fDuration;
if AStep < 1 / 2.75 then
Result := AChange * 7.5625 * Power(AStep, 2) + AStart
else
if AStep < 2 / 2.75 then
begin
AStep := AStep - 1.5 / 2.75;
Result := AChange * (7.5625 * Power(AStep, 2) + 0.75) + AStart;
end
else
if AStep < 2.5 / 2.75 then
begin
AStep := AStep - 2.25 / 2.75;
Result := AChange * (7.5625 * Power(AStep, 2) + 0.9375) + AStart;
end
else
begin
AStep := AStep - 2.625 / 2.75;
Result := AChange * (7.5625 * Power(AStep, 2) + 0.984375) + AStart;
end;
end;


Vous aurez remarqué que ces dernières fonctions sont fondées sur la fonction EaseOutBounce, celle qui introduit les valeurs "magiques".

Dans le prochain épisode, nous mettrons au point l'application de test. A très bientôt !

Vous avez lu gratuitement 5 010 articles depuis plus d'un an.
Soutenez le club developpez.com en souscrivant un abonnement pour que nous puissions continuer à vous proposer des publications.

Une erreur dans cette actualité ? Signalez-nous-la !