---
title: "Animations de pages"
weight: 50
---

# Animations de pages

SmartCommon utilise **Framer Motion** pour animer les transitions entre pages. Les animations sont configurables par route.

## Configuration de base

Dans la configuration du Provider :

```
const config = {
  pages: {
    "*": "fade" // Animation par défaut pour toutes les pages
  }
};
```

## Animations disponibles

| Animation | Description | Effet |
| --- | --- | --- |
| `fade` | Fondu enchaîné | Opacité 0 -> 1 |
| `slideLeft` | Glissement gauche | Entrée par la droite |
| `slideRight` | Glissement droite | Entrée par la gauche |
| `zoom` | Effet de zoom | Scale 0.9 -> 1 |

## Configuration par route

Vous pouvez définir des animations différentes selon la route d'origine et de destination :

```
const config = {
  pages: {
    // Depuis la page d'accueil
    "/": {
      "/dashboard": "slideLeft",  // Vers dashboard: glisse à gauche
      "/settings": "slideLeft",   // Vers settings: glisse à gauche
      "*": "fade"                 // Vers autres: fondu
    },

    // Depuis le dashboard
    "/dashboard": {
      "/": "slideRight",          // Retour accueil: glisse à droite
      "/details": "slideLeft",    // Vers détails: glisse à gauche
      "*": "fade"
    },

    // Depuis les paramètres
    "/settings": {
      "/": "slideRight",
      "*": "fade"
    },

    // Pour toutes les autres pages
    "*": "fade"
  }
};
```

## Logique de navigation

L'animation est choisie selon ce schéma :

1. Cherche une config pour la page actuelle
2. Si trouvée, cherche une animation pour la page précédente
3. Si pas trouvée, utilise `*` de la page actuelle
4. Si pas de config pour la page actuelle, utilise `*` global

### Exemple

Navigation de `/dashboard` vers `/` :

```
pages: {
  "/": {
    "/dashboard": "slideRight", // <- Cette animation sera utilisée
    "*": "fade"
  },
  "/dashboard": {
    "/": "slideRight",
    "*": "fade"
  }
}
```

La page `/` s'affiche avec `slideRight` car on vient de `/dashboard`.

## Désactiver les animations sur desktop

Par défaut, les animations de glissement sont remplacées par `fade` sur desktop pour une meilleure UX :

```
// Dans le composant Page (comportement interne)
if (device?.type === "desktop") {
  return "fade";
}
```

## Utiliser le composant Page

Le composant `Page` gère automatiquement les animations :

```
import { Page, Block } from '@cap-rel/smartcommon';
import { useLocation } from 'react-router-dom';

const Dashboard = () => {
  const location = useLocation();

  return (
    <Page location={location}>
      <Block>
        Contenu du dashboard
      </Block>
    </Page>
  );
};
```

> [!IMPORTANT]
> Le prop `location` est requis pour que les animations fonctionnent correctement.

## Personnaliser les animations

Vous pouvez créer des animations personnalisées en modifiant les variants Framer Motion :

```
// Animations par défaut dans SmartCommon
const animations = {
  slideRight: {
    initial: { x: "50%", opacity: 0 },
    animate: { x: 0, opacity: 1, transition: { duration: 0.15, ease: "easeInOut" } },
    exit: { x: "50%", opacity: 0, transition: { duration: 0.15, ease: "easeInOut" } }
  },
  slideLeft: {
    initial: { x: "-50%", opacity: 0 },
    animate: { x: 0, opacity: 1, transition: { duration: 0.15, ease: "easeInOut" } },
    exit: { x: "-50%", opacity: 0, transition: { duration: 0.15, ease: "easeInOut" } }
  },
  fade: {
    initial: { opacity: 0 },
    animate: { opacity: 1, transition: { duration: 0.15, ease: "easeOut" } },
    exit: { opacity: 0, transition: { duration: 0.15, ease: "easeOut" } }
  },
  zoom: {
    initial: { scale: 0.9, opacity: 0 },
    animate: { scale: 1, opacity: 1 },
    exit: { scale: 0.9, opacity: 0 },
    transition: { duration: 0.2, ease: "easeOut" }
  }
};
```

## Hook useAnimation

Pour des animations personnalisées dans vos composants :

```
import { useAnimation } from '@cap-rel/smartcommon';

const MyComponent = () => {
  const { start, animations, setAnimations } = useAnimation({
    fadeIn: { value: false, state: null },
    slideIn: { value: false, state: null }
  });

  useEffect(() => {
    if (start) {
      // Déclencher l'animation après le premier rendu
      setAnimations(prev => ({
        ...prev,
        fadeIn: { ...prev.fadeIn, state: 'visible' }
      }));
    }
  }, [start]);

  return (
    <motion.div
      initial={{ opacity: 0 }}
      animate={animations.fadeIn.value ? { opacity: 1 } : {}}
    >
      Contenu animé
    </motion.div>
  );
};
```

## Animations avec Framer Motion

Pour des animations plus complexes, utilisez directement Framer Motion :

```
import { motion, AnimatePresence } from 'framer-motion';

const MyList = ({ items }) => (
  <AnimatePresence>
    {items.map(item => (
      <motion.div
        key={item.id}
        initial={{ opacity: 0, y: 20 }}
        animate={{ opacity: 1, y: 0 }}
        exit={{ opacity: 0, y: -20 }}
        transition={{ duration: 0.2 }}
      >
        {item.name}
      </motion.div>
    ))}
  </AnimatePresence>
);
```

## Exemples de configurations

### Application mobile classique

Navigation hiérarchique (liste -> détail -> sous-détail) :

```
pages: {
  "/": {
    "*": "slideLeft"
  },
  "/items": {
    "/": "slideRight",
    "/items/*": "slideLeft",
    "*": "fade"
  },
  "/items/*": {
    "/items": "slideRight",
    "*": "fade"
  },
  "*": "fade"
}
```

### Application avec onglets

Navigation entre onglets sans animation de glissement :

```
pages: {
  "/home": { "*": "fade" },
  "/search": { "*": "fade" },
  "/profile": { "*": "fade" },
  "/settings": {
    "*": "slideLeft" // Seul settings a une animation différente
  },
  "*": "fade"
}
```

### Désactiver toutes les animations

```
pages: {
  "*": "fade" // Utiliser uniquement fade (le plus discret)
}

// Ou modifier la durée à 0
// (nécessite de modifier les animations dans le code)
```

## Voir aussi
- [Configuration](/front/configuration) - Configuration du Provider
- [SmartCommon](/front/smartcommon) - Composant Page
- [Framer Motion](https://www.framer.com/motion/) - Documentation officielle
