Introduction
Les animations basees sur la physique creent des mouvements naturels et satisfaisants qui rendent vos interfaces plus intuitives et engageantes. Contrairement aux transitions CSS lineaires, les simulations physiques produisent des comportements organiques et previsibles que les utilisateurs reconnaissent instinctivement.
Dans ce tutoriel, nous allons explorer 5 techniques essentielles d'animation physique : le rebond (bounce), les ressorts (springs), la gravite, le pendule et l'easing elastique. Chaque technique est accompagnee d'une demo interactive et du code complet.
Les animations physiques reposent principalement sur requestAnimationFrame et les courbes cubic-bezier personnalisees. Ces APIs sont supportees par tous les navigateurs modernes.
1. Bounce Effect
L'effet de rebond est l'animation physique la plus reconnaissable. Il utilise une courbe de Bezier specifique pour simuler un objet qui rebondit, avec une deceleration naturelle a chaque contact avec le sol.
.bounce-ball {
width: 50px;
height: 50px;
background: linear-gradient(135deg, #6366f1, #d946ef);
border-radius: 50%;
/* Courbe de rebond personnalisee */
animation: bounce 1s
cubic-bezier(0.36, 0, 0.66, -0.56)
infinite alternate;
}
@keyframes bounce {
to {
transform: translateY(-150px);
}
}
Comment ca fonctionne
La cle de l'effet bounce reside dans la courbe cubic-bezier :
- cubic-bezier(0.36, 0, 0.66, -0.56) : la valeur negative du 4e parametre cree un depassement (overshoot) qui simule le rebond
- infinite alternate : l'animation boucle en alternant la direction, creant un mouvement de va-et-vient naturel
- translateY : le deplacement vertical simule l'effet de la gravite
2. Spring Animation
L'animation de ressort combine deplacement et deformation pour un effet organique. Le scale applique un ecrasement qui imite un objet souple attache a un ressort.
/* Cubic-bezier elastique pour effet ressort */
.spring-ball {
width: 50px;
height: 50px;
background: linear-gradient(135deg, #6366f1, #d946ef);
border-radius: 50%;
animation: spring 0.6s
cubic-bezier(0.68, -0.55, 0.265, 1.55)
infinite alternate;
}
@keyframes spring {
to {
/* Deplacement + deformation */
transform:
translateY(-100px)
scale(1.1, 0.9);
}
}
La valeur cubic-bezier(0.68, -0.55, 0.265, 1.55) est souvent appelee "easeInOutBack". Les valeurs negatives et superieures a 1 creent le depassement elastique caracteristique des ressorts.
3. Gravity Simulation
Pour une simulation de gravite vraiment realiste, il faut utiliser JavaScript. On calcule la velocite et la position a chaque frame en appliquant une constante de gravite, avec un coefficient de rebond pour l'amortissement.
const ball = document.querySelector('.gravity-ball');
let y = 0;
let velocity = 0;
const gravity = 0.5; // Force de gravite
const bounceCoef = 0.7; // Coefficient de rebond
const floor = 150; // Position du sol
function animate() {
// Appliquer la gravite a la velocite
velocity += gravity;
y += velocity;
// Collision avec le sol
if (y >= floor) {
y = floor;
velocity *= -bounceCoef; // Inverser + amortir
}
// Arreter quand l'energie est epuisee
if (Math.abs(velocity) < 0.5 && y >= floor - 1) {
y = floor;
return;
}
ball.style.top = y + 'px';
requestAnimationFrame(animate);
}
animate();
Les parametres cles
- gravity (0.5) : l'acceleration vers le bas a chaque frame. Plus la valeur est haute, plus la chute est rapide
- bounceCoef (0.7) : determine combien d'energie est conservee apres chaque rebond. 1.0 = rebond parfait, 0.0 = aucun rebond
- floor (150) : la position Y du sol en pixels. La balle rebondit quand elle atteint cette limite
Sans condition d'arret, la boucle requestAnimationFrame tourne indefiniment. Ajoutez toujours un seuil minimum de velocite pour stopper l'animation quand l'objet est "au repos".
4. Pendulum Effect
Le pendule est un classique de la simulation physique. On peut le realiser en CSS pur en combinant transform-origin et une rotation animee avec un easing sinusoidal.
.pendulum-container {
position: relative;
width: 100px;
height: 200px;
}
.pendulum-string {
position: absolute;
top: 0;
left: 50%;
width: 2px;
height: 150px;
background: #a1a1aa;
/* Pivot en haut */
transform-origin: top center;
animation: swing 2s ease-in-out infinite;
}
.pendulum-ball {
position: absolute;
bottom: -25px;
left: 50%;
transform: translateX(-50%);
width: 50px;
height: 50px;
border-radius: 50%;
}
@keyframes swing {
0%, 100% {
transform: rotate(30deg);
}
50% {
transform: rotate(-30deg);
}
}
L'easing ease-in-out est essentiel pour simuler le ralentissement naturel du pendule aux extremites de son mouvement, et l'acceleration au centre.
5. Elastic Easing
L'easing elastique est parfait pour les interactions utilisateur : boutons, menus, modals. Le depassement elastique donne un retour visuel satisfaisant qui rend l'interface plus vivante et reactive.
.elastic-btn {
padding: 16px 32px;
background: #6366f1;
color: white;
border: none;
border-radius: 12px;
cursor: pointer;
font-weight: 600;
/* Easing elastique */
transition: transform 0.3s
cubic-bezier(0.68, -0.55, 0.265, 1.55);
}
.elastic-btn:hover {
transform: scale(1.1);
}
.elastic-btn:active {
transform: scale(0.95);
}
On peut aussi creer un easing elastique plus avance en JavaScript pour des animations personnalisees :
// Fonction d'easing elastique personnalisee
function elasticOut(t) {
const p = 0.3;
return Math.pow(2, -10 * t)
* Math.sin((t - p / 4)
* (2 * Math.PI) / p) + 1;
}
// Utilisation avec une animation manuelle
function animateElastic(element, from, to, duration) {
const start = performance.now();
function tick(now) {
const t = Math.min((now - start) / duration, 1);
const progress = elasticOut(t);
const value = from + (to - from) * progress;
element.style.transform =
`scale(${value})`;
if (t < 1) requestAnimationFrame(tick);
}
requestAnimationFrame(tick);
}
Bonnes pratiques
Avant de conclure, voici quelques recommandations pour utiliser les animations physiques de maniere efficace :
Performance
- Utilisez
transformetopacityuniquement pour les animations. Ces proprietes sont composees par le GPU et ne declenchent pas de reflow - Limitez les simulations JavaScript actives simultanement. Chaque
requestAnimationFrameconsomme des ressources - Ajoutez
will-change: transformsur les elements animes pour prevenire le navigateur - Preferez CSS quand c'est possible : les animations CSS sont souvent plus performantes que leur equivalent JavaScript
Design et UX
- Gardez les durees courtes : 200-500ms pour les micro-interactions, 500ms-1s pour les animations decoratives
- Restez coherent : utilisez le meme type d'easing dans toute votre interface
- Ne surchargez pas : une ou deux animations physiques par page suffisent
Accessibilite
/* Desactiver les animations pour les utilisateurs sensibles */
@media (prefers-reduced-motion: reduce) {
.bounce-ball,
.spring-ball,
.pendulum-string {
animation: none;
}
.elastic-btn {
transition: none;
}
}
Verifiez toujours que prefers-reduced-motion est respecte. Pour les simulations JavaScript, testez ce media query avec window.matchMedia et desactivez les animations en consequence.
Conclusion
Les animations physiques transforment une interface statique en une experience vivante et intuitive. En maitrisant les courbes cubic-bezier personnalisees et les simulations JavaScript avec requestAnimationFrame, vous pouvez creer des interactions qui semblent naturelles et satisfaisantes.
Les cinq techniques presentees ici couvrent les cas d'usage les plus courants : le bounce pour les notifications, le spring pour les transitions d'elements, la gravite pour les simulations realistes, le pendule pour les animations decoratives, et l'easing elastique pour les micro-interactions.
N'hesitez pas a experimenter avec les valeurs et les parametres pour trouver l'equilibre parfait entre realisme et performance pour votre projet.
Retrouvez des dizaines d'effets d'animation prets a l'emploi dans notre bibliotheque d'effets, avec code copiable en un clic.