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

Blog de Gilles Vasseur - Pascal et compagnie

Les transitions entre images sous Lazarus avec BGRABitmap (X) - Des transitions spectaculaires...

Noter ce billet
par , 29/03/2018 à 10h00 (862 Affichages)
Il ne faudrait pas croire que les transitions qui ne demandent qu'une ligne de calcul sans utiliser des procédés plus complexes comme les calques soient limitées à quelques déplacements triviaux. Les quelques exemples qui suivent montrent qu'il n'en est rien et qu'un peu d'imagination permet de rapidement élargir sa palette d'outils !

Les pouvoirs de l'imagination

L'inversion des images de travail

Une première idée est d'inverser l'image d'origine et celle de destination. Ainsi, nous obtenons facilement des transitions de découvrement en lieu et place de celles de recouvrement !

Comme exemple, nous pouvons fournir le code suivant :

Code pascal : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
// traitement 2 devenu 1 ici (destination)...
LX := 0;
LY := 0;
LBGRATemp.PutImage(LX, LY, fBGRATo, dmSet, Opacity);
// traitement 1 devenu 2 ici (source)...
LX := imgResult.ClientWidth * fStep div 100; // UNCOVERBOTTOMRIGHT
LY := imgResult.ClientHeight * fStep div 100;
LBGRATemp.PutImage(LX, LY, fBGRAFrom, dmDrawWithTransparency, Opacity(False));

Nous dessinons tout d'abord l'image de destination sur laquelle nous dessinons avec un décalage de plus en plus grand l'image d'origine. Cette dernière paraît ainsi quitter l'écran en découvrant celle qui nous intéresse. Il s'agit de l'inverse de OverBottomRight, une transition que nous pourrions nommer UncoverBottomRight.

Si vous voulez vous entraîner, vous pouvez transcrire les transitions que nous avions regroupées sous la bannière du recouvrement, multipliant ainsi les transitions à votre disposition.

Les fonctions trigonométriques

Les fonctions trigonométriques sont d'autres outils qui permettent des effets intéressants. Nous pouvons par exemple nous appuyer sur le fait que la valeur retournée par des fonctions comme le sinus ou le cosinus est comprise entre 0 et 1, ce qui autorise des jeux simples avec le pourcentage de réalisation d'une transition et le déphasage de ces fonctions.

Dans l'exemple suivant, on obtient un équivalent de OverTopLeft, mais avec une pente arrondie du meilleur effet :

Code pascal : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
// traitement 1 ici (source)...
LX := 0;
LY := 0;
LBGRATemp.PutImage(LX, LY, fBGRAFrom, dmSet, Opacity(False));
// traitement 2 ici (destination)...
LY := imgResult.ClientHeight - Round(sin(fStep * pi / 200) * imgResult.ClientHeight);
LX := Round(cos(fStep * pi / 200) * imgResult.ClientWidth);
LBGRATemp.PutImage(LX, LY, fBGRATo, dmDrawWithTransparency, Opacity);

Les fonctions sin et cos de Lazarus attendent un paramètre en radians : si vous utilisez des mesures en degrés, il faut penser à leur conversion !

Une partie des calculs peut rester linéaire, une seule fonction trigonométrique étant alors utilisée. Voici un exemple de variante de OverTopRight avec l'ordonnée de l'image de destination traitée avec un sinus :

C'est encore un déplacement arrondi que nous obtenons, surtout visible en fin de transition.

Nous pouvons même prévoir que l'image de destination parte d'un bord du contrôle d'accueil et décrive une portion de la courbe sinusoïdale prévue. Voici une portion de code qui utilise cette possibilité :

Code pascal : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
// traitement 1 ici (source)...
LX := 0;
LY := 0;
LBGRATemp.PutImage(LX, LY, fBGRAFrom, dmSet, Opacity(False));
// traitement 2 ici (destination)...
LY := Round(sin(fStep * pi / 100) * imgResult.ClientHeight);
LX := imgResult.ClientWidth - imgResult.ClientWidth * fStep div 100;
LBGRATemp.PutImage(LX, LY, fBGRATo, dmDrawWithTransparency, Opacity);

Une dernière portion de code montre un autre déplacement original avec une combinaison de fonctions trigonométriques simples :

Code pascal : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
// traitement 1 ici (source)...
LX := 0;
LY := 0;
LBGRATemp.PutImage(LX, LY, fBGRAFrom, dmSet, Opacity(False));
// traitement 2 ici (destination)...
LX := round(imgResult.ClientWidth * sin(fStep * pi / 100));
LY := round(imgResult.ClientHeight * cos(fStep * pi / 200));
LBGRATemp.PutImage(LX, LY, fBGRATo, dmDrawWithTransparency, Opacity);

Une courte vidéo permet de se rendre compte exactement de ce que fait notre transition :



Un soupçon de paraboles pour les rebonds


Dans le même esprit de découverte, les paraboles offrent des possibilités de transitions qui évoqueront les rebonds d'un objet élastique sur le sol (bouncing). Comme nous connaissons au moins les coordonnées du premier point d'où doit démarrer notre animation (il s'agira par exemple du coin inférieur gauche du composant qui affiche le résultat de notre transition à un instant donné) et que nous pouvons décider de même du sommet de notre parabole, en fait de la hauteur du rebond, son équation est assez facilement déterminable.

Prenons un point A de coordonnées (0, 0) et un point S de coordonnées (sx, sy). Si notre parabole passe par A et par S et que S est son sommet, l'équation de la parabole peut être donnée sous la forme : y = a * (x – sx)² + sy. Pour déterminer le coefficient a, il suffit d'utiliser les coordonnées du point connu A qui obéiront à l'équation : 0 = a * (0 – sx)² + sy.

Nous en tirons : a = - sy / sx², d'où y = - sy / sx² (x – sx)² + sy.

Le code correspondant n'est pas très compliqué à comprendre si ce n'est qu'il faut prendre garde au fait que nous utilisons dans notre programme un pourcentage des dimensions et qu'il faut par conséquent en tenir compte dans nos calculs. De même, il faut faire attention à ce que l'origine des calculs soit bien le point d'abscisse 0 ou de la ramener à lui si nécessaire (c'est le rôle de la variable AOffset).

Voici un schéma qui montre une étape du déplacement de l'image en suivant le dessin de cinq paraboles :


Nom : paraboles2.png
Affichages : 97
Taille : 3,8 Ko
C'est le point inférieur droit de l'image qui est choisi ici pour les déplacements, mais ces déplacements sont exactement les mêmes que ceux du point supérieur gauche puisqu'il s'agit encore une fois d'une série de translations qui conservent les formes géométriques. Pour obtenir les rebonds, il suffit que le point choisi parcoure le tracé de toutes les paraboles.

Code pascal : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
function Parabole(AOffset, AMax, APerCent: Byte): Byte;
var
  LL: Real;
begin
  LL := (AMax - AOffset) * imgResult.ClientWidth / 100;
  Result := Round((-imgResult.ClientHeight * APerCent / 100 / power(LL, 2)) *
    power((imgResult.ClientWidth * (fStep - AOffset) div 100) - LL, 2) +
    imgResult.ClientHeight * APerCent div 100);
end;

En fournissant la distance entre l'abscisse du premier point coupant l'axe des x et l'origine de cet axe (AOffset), l'abscisse du sommet de la parabole (AMax) et le pourcentage désiré de rebond (APerCent), nous avons tous les éléments nécessaires au calcul de l'équation de la parabole et donc des ordonnées correspondant au point de l'image à déplacer.

Afin d'imiter des rebonds, nous choisissons de soumettre l'image de destination à la fonction qui vient d'être définie avec cinq équations différentes pour des paraboles aux sommets de plus en plus bas et dessinées sur des distances de plus en plus courtes. C'est la variable fStep qui sert à déterminer les paramètres de la fonction :

Code pascal : 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
20
21
22
23
24
25
26
27
28
29
30
31
begin
  btnGo.Enabled := False;
  LBGRATemp := TBGRABitmap.Create(imgResult.ClientWidth, imgResult.ClientHeight, BGRABlack);
  try
    fStep := 0;
    repeat
      Inc(fStep);
      LBGRATemp.FillRect(ClientRect, BGRABlack);
      // traitement 1 ici (source)...
      LX := 0;
      LY := 0;
      LBGRATemp.PutImage(LX, LY, fBGRAFrom, dmSet, Opacity(False));
      LX := -imgResult.ClientWidth + imgResult.ClientWidth * fStep div 100;
      case fStep of
        0..30: LY :=  - Parabole(0, 15, 80);
        31..50: LY :=  - Parabole(30, 40, 60);
        51..70: LY :=  - Parabole(50, 60, 50);
        71..80: LY := - Parabole(70, 75, 35);
        81..90: LY := - Parabole(80, 85, 20);
        91..100: LY := - Parabole(90, 95, 5);
      end;
      LBGRATemp.PutImage(LX, LY, fBGRATo, dmDrawWithTransparency, Opacity);
      LBGRATemp.Draw(imgResult.Canvas, 0, 0);
      imgResult.Repaint;
      sleep(100 - fSpeed);
    until fStep = 100;
  finally
    LBGRATemp.Free;
    btnGo.Enabled := True;
  end;
end;

Le signe moins devant l'appel de la fonction Parabole permet de prendre en compte l'inversion de l'axe des ordonnées en informatique par rapport aux habitudes scolaires.

L'effet obtenu est plutôt spectaculaire et n'aura pas nécessité beaucoup de travail. Surtout, notre fonction s'adapte à des images de n'importe quelles dimensions, ce qui est appréciable !

Voici un petit film pour vous en convaincre :



Malgré la rédaction d'une formule plus complexe, il s'agit d'une transition qui se contente des méthodes que nous avons déjà utilisées. Là encore c'est votre imagination, accompagnée d'un peu de tâtonnement et de quelques connaissances en mathématiques, qui vous fera découvrir les possibilités insoupçonnées d'outils d'apparence rudimentaire !

Prochainement, nous aborderons des transitions qui exigeront l'utilisation d'autres outils que ceux vus jusqu'à présent...

Envoyer le billet « Les transitions entre images sous Lazarus avec BGRABitmap (X) - Des transitions spectaculaires... » dans le blog Viadeo Envoyer le billet « Les transitions entre images sous Lazarus avec BGRABitmap (X) - Des transitions spectaculaires... » dans le blog Twitter Envoyer le billet « Les transitions entre images sous Lazarus avec BGRABitmap (X) - Des transitions spectaculaires... » dans le blog Google Envoyer le billet « Les transitions entre images sous Lazarus avec BGRABitmap (X) - Des transitions spectaculaires... » dans le blog Facebook Envoyer le billet « Les transitions entre images sous Lazarus avec BGRABitmap (X) - Des transitions spectaculaires... » dans le blog Digg Envoyer le billet « Les transitions entre images sous Lazarus avec BGRABitmap (X) - Des transitions spectaculaires... » dans le blog Delicious Envoyer le billet « Les transitions entre images sous Lazarus avec BGRABitmap (X) - Des transitions spectaculaires... » dans le blog MySpace Envoyer le billet « Les transitions entre images sous Lazarus avec BGRABitmap (X) - Des transitions spectaculaires... » dans le blog Yahoo

Mis à jour 29/03/2018 à 13h45 par gvasseur58

Catégories
Programmation , Free Pascal , Lazarus , Graphisme

Commentaires