Animations Ease-In-Ease-Out avec les Fonctions Trigonométriques et Implémentation en C#

Les animations avec un effet ease-in-ease-out sont courantes, comme :

  1. Une barre de défilement avec un effet ease-in-ease-out.
  2. Une lumière de respiration avec un effet ease-in-ease-out.

Ces effets utilisent principalement les fonctions trigonométriques. Cet article explique comment les réaliser étape par étape.

Fondamentaux Théoriques

Les fonctions trigonométriques

Les fonctions trigonométriques courantes sont le sinus (sin), le cosinus (cos) et la tangente (tan). En animation, le sinus et le cosinus sont les plus utilisés, et comme ils sont liés, nous utiliserons le sinus pour cet article.

Pour un triangle rectangle ABC, où A est un angle, a la longueur du côté opposé à A et c la longueur de l'hypoténuse :

sin(A) = a / c

La courbe sinusoïdale

La courbe sinusoïdale relie les fonctions trigonométriques à l'animation. La formule générale est : y = A * sin(B*x + C) + D, où y et x sont les coordonnées sur les axes vertical et horizontal.

  1. La fonction de base y = sin(x) oscille entre -1 et +1.
  2. Le paramètre A contrôle l'amplitude. Par exemple, y = 2 * sin(x) a une amplitude de 2.
  3. Le paramètre B contrôle la période. Par exemple, y = sin(2x) a une période plus courte.
  4. Le paramètre C déplace la courbe horizontalement. Par exemple, y = sin(x + 1) déplace la courbe vers la gauche.
  5. Le paramètre D déplace la courbe verticalement. Par exemple, y = sin(x) + 1 déplace la courbe vers le haut.

Conversion Degrés-Radians

Les fonctions comme Math.Sin() en C# utilisent des radians. La conversion est :

  • Radians = Degrés * π / 180
  • Degrés = Radians * 180 / π

Un angle de 180 degrés équivaut à π radians, et un angle de 360 degrés équivaut à 2π radians.

Implémentation de l'Animation

L'idée est d'utiliser la variation des valeurs y et x de la courbe sinusoïdale. Pour une animation ease-in-ease-out, la vitesse varie. En pratique, on fixe l'intervalle de temps et on fait varier la distance parcourue à chaque intervalle.

Implémentation Simple

Approche

  1. La fonction y = sin(x) produit des valeurs entre -1 et +1.
  2. Décaler la courbe verticalement de +1 pour obtenir y = sin(x) + 1 (valeurs entre 0 et 2).
  3. Diviser par 2 pour obtenir y = (sin(x) + 1) / 2 (valeurs entre 0 et 1).
  4. Multiplier ce résultat par la distance totale de déplacement de l'animation.

Code C# (Démo de Base)

// Animer un curseur avec un mouvement sinusoïdal simple
void AnimerCurseurSimple()
{
    int angleDegres = 0;
    double distanceDeplacement = largeurConteneur - largeurCurseur;
    while (true)
    {
        angleDegres = (angleDegres + 1) % 360;
        Thread.Sleep(10);
        double angleRadians = angleDegres * Math.PI / 180.0;
        double nouvellePosition = distanceDeplacement * (1 + Math.Sin(angleRadians)) / 2.0;
        MettreAJourPositionCurseur(Convert.ToInt32(nouvellePosition));
    }
}

void MettreAJourPositionCurseur(int position)
{
    if (curseurGlissant.InvokeRequired)
    {
        curseurGlissant.Invoke(new Action<int>(MettreAJourPositionCurseur), new object[] { position });
    }
    else
    {
        curseurGlissant.Left = position;
    }
}

Le curseur démarre au milieu de la course.

Optimisation du Point de Départ

Approche

Pour démarrer depuis l'extrémité gauche, décaler la courbe horizontalement de -π/2 radians (ou -90 degrés). La formule devient : y = (sin(x - π/2) + 1) / 2.

Code C# Optimisé

// Animer le curseur en commençant depuis l'extrémité gauche
void AnimerCurseurOptimise()
{
    int angleDegres = 0;
    double distanceDeplacement = largeurConteneur - largeurCurseur;
    while (true)
    {
        angleDegres = (angleDegres + 1) % 360;
        Thread.Sleep(10);
        double angleAjuste = (angleDegres - 90) * Math.PI / 180.0;
        double nouvellePosition = distanceDeplacement * (1 + Math.Sin(angleAjuste)) / 2.0;
        MettreAJourPositionCurseur(Convert.ToInt32(nouvellePosition));
    }
}

Animation avec Durée Contrôlée

Approche

Pour fixer la durée d'un cycle complet (par exemple, 1 seconde pour un aller-retour) :

  1. Définir l'intervalle de temps (intervalleTemps, ex: 10ms).
  2. Calculer le nombre total d'étapes : nbEtapes = dureeTotalAnimation / intervalleTemps.
  3. L'incrément d'angle par étape pour un demi-cycle (180°) est : incrementAngle = 180.0 / nbEtapes.

Code C# Final (Comparaison Constante vs Ease-In-Ease-Out)

// Animation à vitesse constante
void AnimerVitesseConstante()
{
    double positionActuelle = 0;
    bool deplacementVersDroite = true;
    int intervalleTemps = 10;
    double distanceMax = largeurConteneur - largeurCurseur;
    double incrementPosition = distanceMax / (1000.0 / intervalleTemps);
    
    while (true)
    {
        positionActuelle += deplacementVersDroite ? incrementPosition : -incrementPosition;
        if (positionActuelle >= distanceMax) deplacementVersDroite = false;
        if (positionActuelle <= 0) deplacementVersDroite = true;
        
        Thread.Sleep(intervalleTemps);
        MettreAJourPositionCurseur(Convert.ToInt32(positionActuelle));
    }
}

// Animation ease-in-ease-out avec durée contrôlée
void AnimerEaseInOutDureeControlee()
{
    double angleDegres = 0;
    int intervalleTemps = 10;
    double dureeCycle = 1000.0; // 1 seconde pour un aller-retour
    double distanceDeplacement = largeurConteneur - largeurCurseur;
    double nbEtapes = dureeCycle / intervalleTemps;
    double incrementAngle = 180.0 / nbEtapes;
    
    while (true)
    {
        angleDegres += incrementAngle;
        if (angleDegres >= 360) angleDegres = 0;
        
        Thread.Sleep(intervalleTemps);
        double angleAjuste = (angleDegres - 90) * Math.PI / 180.0;
        double positionCalculee = distanceDeplacement * (1 + Math.Sin(angleAjuste)) / 2.0;
        MettreAJourPositionCurseur(Convert.ToInt32(positionCalculee));
    }
}

Les fonctions trigonométriques permettent de créer non seulement des animations ease-in-ease-out, mais aussi des effets visuels variés comme des vagues (utiles pour des barres de progression ou des indicateurs de chargement). D'autres fonctions, comme les courbes de Bézier, offrent des possibilités encore plus riches pour des animations complexes et élégantes.

Étiquettes: C# Animation Fonctions Trigonométriques Ease-In-Ease-Out Windows Forms

Publié le 19 juin à 05h13