Voir le flux RSS

Blog de Gilles Vasseur - Pascal et compagnie

[Actualité] Les interpolations et fonctions d'easing avec Lazarus II - Une approche empirique

Noter ce billet
par , 14/01/2019 à 12h00 (1393 Affichages)
Pour les besoins du composant TGVTransition qui traite les transitions d'image à image, nous avons déjà présenté des éléments afin de créer des interpolations. Nous reprenons ci-après les formules empiriques qui ont accompagné ce projet dans sa forme initiale.

L'objectif d'une première fonction appelée Exponant était de renvoyer une valeur entre AStart et AEnd modifiée par la puissance AExp utilisée. Quelle que soit la valeur de AExp, nous obtenions une valeur comprise entre 0 et (AEnd - AStart).

Par exemple, si la puissance valait 1, nous étions en présence d'une progression linéaire : en effet, la différence entre AStart et AEnd était alors multipliée par le pas à la puissance 1 (elle était donc inchangée) puis divisée par 100 à la même puissance (donc par 100 inchangé encore une fois). Vous aurez reconnu la formule qui permet de calculer le simple pourcentage d'une valeur ! Pour des puissances supérieures à 1, nous nous retrouvions dans les cas étudiés dans le billet précédent.

Pseudo-code :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
AStart entier (valeur initiale de l'interpolation)
AEnd entier (valeur finale de l'interpolation)
AStep entier (pas/étape en cours)

fonction Exponant
paramètre en entrée : AExp entier
sortie : Result entier

Result = Valeur arrondie de (AStart - AEnd) multipliée par (AStep à la puissance AExp) divisée par (100 à la puissance AExp)
En Pascal, nous avions :

Code delphi : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
function Exponant(AExp: Byte): Integer;
  begin
    Result := Round((AEnd - AStart) * Power(AStep, AExp) / Power(100, AExp));
  end;

Une autre fonction nommée DownExponant permettait de donner l'illusion d'un ralentissement. Pour cela, il suffisait d'inverser les calculs de l'accélération positive par deux soustractions. En partant de (AEnd - AStart), nous arrivions progressivement à 0 :

Code delphi : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
function DownExponant(AExp: Byte): Integer;
  begin
    Result := AEnd - AStart - Round((AEnd - AStart) * Power(100 - AStep, AExp) / Power(100, AExp));
  end;

Ces deux fonctions formaient la base des fonctions d'interpolation utilisées dont l'écriture se trouvait grandement simplifiée.

Les fonctions d'interpolation étaient elles-mêmes définies dans une énumération :

Code delphi : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
type
 
  TInterpolation = (intLinear, intQuadratic, intCubic, intQuartic, intQuintic,
    intSinus, intSpring, intExpo, intSqrt, intSlowDownQuadratic, intSlowDownCubic,
    intSlowDownQuartic, intSlowDownQuintic, intBounceCos, intStepsCos);

Enfin, elles étaient traitées dans une méthode dont la structure comportait essentiellement un case of (choix...parmi) :

Code delphi : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function ComputeInterpolation(AStart, AEnd: Integer; AStep: Integer;
  AInter: TInterpolation; ABack: Boolean): Integer;
// *** calcul des interpolations ***
begin
  case AInter of
    intLinear: Result := Exponant(1);
    intQuadratic: Result := Exponant(2);
    intCubic: Result := Exponant(3);
    intQuartic: Result := Exponant(4);
    intQuintic: Result := Exponant(5);
    // [...]
    intSlowDownQuadratic: Result := DownExponant(2);
    intSlowDownCubic: Result := DownExponant(3);
    intSlowDownQuartic: Result := DownExponant(4);
    intSlowDownQuintic: Result := DownExponant(5);
    // [...]
  end;
  // [...]
end;

Simplement, pour permettre un retour de AEnd vers AStart, un paramètre de type booléen ABack était utilisé à la toute fin de la même méthode :

Code delphi : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
    intSlowDownQuintic: Result := DownExponant(5);
    // [...]
  end;
  if ABack then
    Result := AEnd - Result;
end;

D'autres fonctions ont ensuite été ajoutées pour obtenir des effets variés.

Comme nous pouvions nous y attendre, la racine carrée ou les puissances de 2 produisaient des effets proches des puissances déjà vues. Elles les modulaient seulement avec leur propre progression.

Leur emploi dans le case of s'appuyait aussi sur la fonction Exponant :

Code delphi : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
 intExpo: Result := Round(Exponant(1) * (Power(2, AStep / 100) - 1));
    intSqrt: Result := Round(Exponant(1) * (Sqrt(AStep) / 10));

Nous avions aussi adjoint des formules à base de fonctions trigonométriques. Leurs cycles permettaient en particulier d'envisager des effets de rebonds :

Code delphi : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
case AInter of
    // [...]
    intSinus: Result := Round(Exponant(1) * sin(pi * AStep / 200));
    intSpring: Result := Round(Exponant(1) * (Power(cos(pi * AStep / 100), 2)));
    // [...]
    intBounceCos: Result := Exponant(1) + Round((cos(AStep * pi / 100) + 1) * Exponant(1));
    intStepsCos: Result := Exponant(1) + Round(Power((cos(AStep * pi / 100) + 1), 2) * 100);
    intCos: Result := Round(Exponant(1) * (1 - cos(AStep / 100 * pi)) / 2);
    intHalfCos: Result := Round(Exponant(1) * ((1 - cos(AStep /100 * Pi)) / 4 + AStep / 200));
  end;
  // [...]
end;

Pour le moment, contentons-nous d'avoir un aperçu de ce que produisaient ces interpolations appliquées à de simples boutons :



Ce billet n'a fait que rappeler les outils créés de manière empirique pour l'écriture d'un composant particulier. Cependant, il montre qu'avec peu de moyens, nous pouvons créer des animations déjà sympathiques et variées.

Par la suite, il s'agira de formaliser cette approche en la rendant compatible avec celle qu'offrent CSS ou JavaScript par exemple (souvent via des bibliothèques complémentaires). A très bientôt !

Envoyer le billet « Les interpolations et fonctions d'easing avec Lazarus II - Une approche empirique » dans le blog Viadeo Envoyer le billet « Les interpolations et fonctions d'easing avec Lazarus II - Une approche empirique » dans le blog Twitter Envoyer le billet « Les interpolations et fonctions d'easing avec Lazarus II - Une approche empirique » dans le blog Google Envoyer le billet « Les interpolations et fonctions d'easing avec Lazarus II - Une approche empirique » dans le blog Facebook Envoyer le billet « Les interpolations et fonctions d'easing avec Lazarus II - Une approche empirique » dans le blog Digg Envoyer le billet « Les interpolations et fonctions d'easing avec Lazarus II - Une approche empirique » dans le blog Delicious Envoyer le billet « Les interpolations et fonctions d'easing avec Lazarus II - Une approche empirique » dans le blog MySpace Envoyer le billet « Les interpolations et fonctions d'easing avec Lazarus II - Une approche empirique » dans le blog Yahoo

Mis à jour 14/01/2019 à 12h27 par gvasseur58

Catégories
Free Pascal , Lazarus , Graphisme

Commentaires

  1. Avatar de circular17
    • |
    • permalink
    Sympa l'animation avec toutes les transitions en même temps !
  2. Avatar de SergioMaster
    • |
    • permalink
    Bonjour,

    Heureusement que la vidéo est là parce que je ne voyais pas où ce fil nous conduisait.
    À ma décharge tant que ma vie professionnelle n'est pas terminée (:arf encore 4ans et demi) le traitement d'image et moi resteront à distance et je n'utiliserai que Delphi (et donc ses animations et effets proposés avec le framework FMX).

    Très beau boulot en tout cas les utilisateurs de Lazarus seront ravis
  3. Avatar de gvasseur58
    • |
    • permalink
    Merci à vous deux pour les encouragements !

    @SergioMaster

    Tu remarqueras que les fonctions d'easing sont aussi utilisées par FMX (au moins partiellement puisque les fonctions OutIn n'ont pas été implémentées) : simplement, comme l'a suggéré circular17 en commentaire du précédent billet, les pas ne sont pas traités de manière linéaire. De plus, les animations se font dans des threads dédiés.
    Les utilisateurs de la VCL peuvent aussi être intéressés par ce modeste travail puisque ce framework, comme la LCL de Free Pascal, ignore totalement l'animation.
    Alors, vivement ta retraite
  4. Avatar de SergioMaster
    • |
    • permalink
    Purée, c'est vrai, j'ai complètement zappé la VCL

    Enfin, si je peux me permettre, le titre "interpolations et fonctions d'easing" c'est pas très accrocheur heureusement que la petite vidéo est là pour comprendre de quoi il s'agit.
    Pour des noobs comme moi en matière de gestion graphique c'est du "chinois"