À une époque où les ordinateurs bourdonnaient doucement sous Windows 98, le screensaver était bien plus qu’un simple gadget. C’était une petite parenthèse visuelle, un moment où la machine « rêvait » pendant que son utilisateur s’éloignait du clavier.
Des tuyaux en 3D aux étoiles filantes, ces animations emblématiques mêlaient esthétique, technique et symbolique de la pause numérique.
Mais derrière cette poésie de l’écran en veille se cache une histoire fascinante : celle d’une technologie née pour protéger les moniteurs cathodiques, devenue au fil du temps une véritable forme d’expression visuelle et ludique.
Plongeons ensemble dans l’art perdu du screensaver, entre nostalgie, curiosité technique et hommage à une époque où même le sommeil du PC avait du style.
A quoi servaient-ils ?
De leur création …
À l’origine, les screensavers n’avaient rien de décoratif. Leur rôle était de protéger les écrans cathodiques (CRT) de la “brûlure d’écran”.
Ce phénomène survenait lorsque la même image restait affichée trop longtemps, marquant de façon permanente le phosphore du tube par une empreinte fantôme.
Les économiseurs d’écran faisaient donc défiler des formes, du texte ou des animations pour éviter que les pixels ne restent figés trop longtemps.
Avec Windows 98, ces petits programmes sont devenus bien plus qu’une simple mesure de précaution. Ils se sont transformés en terrain de créativité pour les développeurs et en signature visuelle pour les utilisateurs : les tuyaux 3D, le texte rebondissant ou les mystères de “Mystify” sont devenus les symboles d’une époque où même l’attente avait du style.
… à leur disparition
Mais cette ère a fini par s’éteindre avec l’évolution des technologies d’affichage.
Les écrans LCD, puis LED, ne risquaient plus de brûlure permanente, rendant le screensaver obsolète.
Parallèlement, la consommation d’énergie est devenue une préoccupation majeure : laisser un écran allumé pour afficher une animation n’avait plus de sens. Les systèmes modernes ont donc remplacé les économiseurs d’écran par des modes veille et veille prolongée, conçus pour éteindre l’écran et économiser la batterie.
Aujourd’hui, les screensavers ne survivent plus que comme objets de nostalgie — ou comme curiosités techniques pour les amateurs de rétro-informatique. Pourtant, il reste quelque chose de poétique dans ces pixels qui dansaient sur nos écrans endormis : une trace du moment où les ordinateurs semblaient vraiment… rêver.
Quatre exemples revenus à la vie
Screensaver 1 : Flying icons
Explication
Je commence par récupérer deux éléments de la page :
- l’image à faire rebondir (
img) ; - et le conteneur (
container) qui sert de surface de déplacement.
Ensuite, je définis une taille fixe pour l’image (80×80 pixels) et je lui attribue une position de départ aléatoire à l’intérieur du conteneur, avec une vitesse horizontale et verticale aléatoire (vx, vy).
À chaque image de l’animation :
- Je mets à jour la position de l’image selon sa vitesse ;
- Si elle atteint un bord du conteneur, j’inverse la direction correspondante (en multipliant la vitesse par -1), ce qui crée l’effet de rebond ;
- Je corrige la position pour qu’elle reste toujours à l’intérieur de la zone ;
- J’applique les nouvelles coordonnées à l’image en ajustant son style (
left,top) ; - Enfin, j’appelle
requestAnimationFrame(move)pour relancer le calcul à la frame suivante, créant ainsi une animation fluide et continue.
Le résultat, c’est ce petit logo qui glisse tranquillement d’un bord à l’autre, rebondit avec précision et semble ne jamais s’arrêter
Code
function() {
const img = document.getElementById('logo');
const container = document.getElementById('bounce-area');
if (!img || !container) {
console.error("Erreur : img ou container manquant");
return;
}
const W = 80;
const H = 80;
let x = 50 + Math.random() * (container.clientWidth - W - 100);
let y = 50 + Math.random() * (container.clientHeight - H - 100);
let vx = 1 + Math.random() * 2;
let vy = 1 + Math.random() * 2;
function move() {
x += vx;
y += vy;
if (x <= 0 || x >= container.clientWidth - W) {
vx = -vx;
x = Math.max(0, Math.min(x, container.clientWidth - W));
}
if (y <= 0 || y >= container.clientHeight - H) {
vy = -vy;
y = Math.max(0, Math.min(y, container.clientHeight - H));
}
img.style.left = x + 'px';
img.style.top = y + 'px';
requestAnimationFrame(move);
}
move();
})();
Screensaver 2 : Mystify
Explication
Derrière cet effet hypnotique se cache en réalité une idée toute simple : des points qui bougent et des lignes qui les relient.
Je commence par dessiner quatre points disposés grossièrement en carré.
Chaque point possède une position (x, y) et une vitesse (vx, vy), ce qui lui permet de se déplacer dans la fenêtre.
À chaque frame, ces points sont déplacés selon leur vitesse.
S’ils atteignent un bord, leur direction est inversée, comme une balle qui rebondit sur les murs.
Ensuite, je relie ces points entre eux en traçant un polygone fermé.
Ce simple tracé, répété en continu, crée un motif géométrique changeant en permanence, puisque la forme se déforme à mesure que les points bougent indépendamment les uns des autres.
Code
(function() {
const canvas = document.getElementById('mystify-canvas');
if (!canvas) return;
const ctx = canvas.getContext('2d');
function resize() {
canvas.width = canvas.parentElement.clientWidth;
canvas.height = canvas.parentElement.clientHeight;
}
resize();
window.addEventListener('resize', resize);
const points = [
{ x: canvas.width * 0.3, y: canvas.height * 0.3, vx: 2.5, vy: 1.8 },
{ x: canvas.width * 0.7, y: canvas.height * 0.3, vx: -2.2, vy: 2.3 },
{ x: canvas.width * 0.7, y: canvas.height * 0.7, vx: -1.9, vy: -2.6 },
{ x: canvas.width * 0.3, y: canvas.height * 0.7, vx: 2.8, vy: -1.7 }
];
const colors = '#66ff66';
function animate() {
ctx.fillStyle = 'rgba(0, 0, 0, 0.08)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
points.forEach(p => {
p.x += p.vx;
p.y += p.vy;
if (p.x <= 0 || p.x >= canvas.width) p.vx *= -1;
if (p.y <= 0 || p.y >= canvas.height) p.vy *= -1;
});
ctx.strokeStyle = colors;
ctx.lineWidth = 1;
ctx.beginPath();
ctx.moveTo(points[0].x, points[0].y);
ctx.lineTo(points[1].x, points[1].y);
ctx.lineTo(points[2].x, points[2].y);
ctx.lineTo(points[3].x, points[3].y);
ctx.closePath();
ctx.stroke();
requestAnimationFrame(animate);
}
animate();
})();
Screensaver 3 : Starfield
Explication
Pour simuler un champ d’étoiles, je commence par générer des points aléatoires dans un espace en trois dimensions.
Imagine un grand cube dont la largeur et la hauteur correspondent à la taille de la fenêtre, et dont la profondeur est fixée à une valeur arbitraire (ici 1000).
Chaque étoile possède donc trois coordonnées :
- x et y, pour sa position sur l’écran ;
- z, pour sa distance par rapport à l’observateur.
La largeur et la hauteur servent à placer l’étoile sur le plan de l’écran, tandis que la profondeur (z) permet d’ajouter un effet de perspective : plus z est grand, plus l’étoile paraît petite et lointaine.
Au fil du temps, je fais diminuer la valeur de z, ce qui donne l’impression que les étoiles se rapprochent du spectateur.
Chaque étoile se déplace le long d’une ligne imaginaire partant du centre de l’écran.
À mesure que sa profondeur diminue, sa position projetée s’éloigne du centre, ce qui donne l’illusion qu’elle file vers l’extérieur. Exactement comme si l’on traversait une galaxie à grande vitesse.
Quand une étoile arrive “trop près” (z ≤ 0), je la réinitialise à l’arrière du cube, avec une nouvelle position aléatoire. Cela crée un flux continu d’étoiles.
Pour rendre le mouvement plus fluide et réaliste :
- j’utilise un effet de traînée (un léger rectangle noir semi-transparent à chaque frame) pour conserver une trace des étoiles ;
- et je modifie la taille et la luminosité en fonction de la distance, pour accentuer l’effet 3D.
Le résultat final donne cette illusion familière : un vol stellaire hypnotique.
Code
(function() {
const canvas = document.getElementById('starfield-canvas');
if (!canvas) return;
const ctx = canvas.getContext('2d');
function resize() {
canvas.width = canvas.parentElement.clientWidth;
canvas.height = canvas.parentElement.clientHeight;
}
resize();
window.addEventListener('resize', resize);
const stars = [];
for (let i = 0; i < 200; i++) {
stars.push({
x: Math.random() * canvas.width,
y: Math.random() * canvas.height,
z: Math.random() * 1000
});
}
function animate() {
ctx.fillStyle = 'rgba(0, 0, 0, 0.1)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
const cx = canvas.width / 2;
const cy = canvas.height / 2;
stars.forEach(s => {
const px = cx + (s.x - cx) / s.z * 500;
const py = cy + (s.y - cy) / s.z * 500;
s.z -= 1;
if (s.z <= 0) {
s.x = Math.random() * canvas.width;
s.y = Math.random() * canvas.height;
s.z = 1000;
}
const x = cx + (s.x - cx) / s.z * 500;
const y = cy + (s.y - cy) / s.z * 500;
const size = (1000 - s.z) / 1000 * 3;
ctx.beginPath();
ctx.moveTo(px, py);
ctx.lineTo(x, y);
ctx.strokeStyle = 'rgba(255,255,255,0.8)';
ctx.lineWidth = size * 0.5;
ctx.stroke();
ctx.fillStyle = 'white';
ctx.beginPath();
ctx.arc(x, y, size, 0, Math.PI * 2);
ctx.fill();
});
requestAnimationFrame(animate);
}
animate();
})();
Screensaver 4 : Tube 3D
Explication
Derrière ce spectacle visuel se cache un principe simple, mais efficace : des segments de ligne reliés les uns aux autres, qui se déplacent par pas sur une grille.
Chaque tuyau commence à une position aléatoire dans une grille, et possède une direction initiale (haut, droite, bas ou gauche).
À chaque “pas”, le tuyau avance d’une case et crée un nouveau segment entre sa position précédente et la nouvelle.
Quand il atteint un bord ou qu’un changement aléatoire se produit, le tuyau tourne à 90° pour continuer son parcours.
Si le tuyau arrive trop près du bord, il se réinitialise à un point aléatoire, assurant un flux infini et toujours renouvelé.
Pour recréer l’effet “3D” :
- Chaque segment est dessiné avec un gradient de couleur qui simule l’éclairage et la profondeur.
- Une ombre subtile derrière le segment donne l’impression que le tuyau se détache de l’écran.
- Un reflet léger ajoute une touche réaliste et brillante, comme si la lumière glissait sur le métal ou le plastique.
- La traînée sur le fond très sombre crée un effet de persistance visuelle, donnant l’illusion que les tuyaux continuent au-delà du cadre.
La boucle d’animation (requestAnimationFrame) :
- Déplace chaque tuyau
- Dessine chaque segment
- Maintient le fond légèrement transparent pour conserver les traces passées, créant une illusion de mouvement fluide et hypnotique.
Code
(function() {
const canvas = document.getElementById('pipes-canvas');
if (!canvas) return;
const ctx = canvas.getContext('2d');
const GRID = 35;
const PIPE_WIDTH = 12;
const SHADOW_OFFSET = 2;
const MAX_PIPES = 10;
const PIPE_SPEED = 0.2;
const MIN_LENGTH = 60;
const MAX_LENGTH = 240;
function resize() {
canvas.width = canvas.parentElement.clientWidth;
canvas.height = canvas.parentElement.clientHeight;
}
resize();
window.addEventListener('resize', resize);
class Pipe {
constructor() {
this.segments = [];
this.reset();
}
reset() {
this.segments = [];
this.x = Math.floor(Math.random() * (canvas.width / GRID)) * GRID + GRID / 2;
this.y = Math.floor(Math.random() * (canvas.height / GRID)) * GRID + GRID / 2;
this.dir = Math.floor(Math.random() * 4);
this.length = 0;
this.maxLength = MIN_LENGTH + Math.floor(Math.random() * (MAX_LENGTH - MIN_LENGTH));
this.hue = Math.random() * 360;
this.progress = 0;
}
getColor(lightness = 60) {
return `hsl(${this.hue}, 30%, ${lightness}%)`;
}
move() {
this.progress += PIPE_SPEED;
if (this.progress >= 1) {
this.progress = 0;
const dirs = [
{ x: 0, y: -GRID },
{ x: GRID, y: 0 },
{ x: 0, y: GRID },
{ x: -GRID, y: 0 }
];
const d = dirs[this.dir];
const nx = this.x + d.x;
const ny = this.y + d.y;
if (nx < GRID || nx > canvas.width - GRID || ny < GRID || ny > canvas.height - GRID) {
this.reset();
return;
}
this.segments.push({
x1: this.x, y1: this.y,
x2: nx, y2: ny
});
this.x = nx;
this.y = ny;
this.length++;
if (this.length >= this.maxLength || Math.random() < 0.08) {
this.dir = (this.dir + (Math.random() < 0.5 ? 1 : 3)) % 4;
this.length = 0;
this.maxLength = MIN_LENGTH + Math.floor(Math.random() * (MAX_LENGTH - MIN_LENGTH));
}
}
}
draw() {
this.segments.forEach((seg, i) => {
const age = i / this.segments.length;
const alpha = 1 - age * 0.8;
ctx.globalAlpha = alpha * 0.7;
ctx.strokeStyle = 'rgba(0,0,0,0.2)';
ctx.lineWidth = PIPE_WIDTH + 2;
ctx.lineCap = 'round';
ctx.beginPath();
ctx.moveTo(seg.x1 + SHADOW_OFFSET, seg.y1 + SHADOW_OFFSET);
ctx.lineTo(seg.x2 + SHADOW_OFFSET, seg.y2 + SHADOW_OFFSET);
ctx.stroke();
const gradient = ctx.createLinearGradient(seg.x1, seg.y1, seg.x2, seg.y2);
gradient.addColorStop(0, this.getColor(40));
gradient.addColorStop(0.5, this.getColor(30));
gradient.addColorStop(1, this.getColor(40));
ctx.strokeStyle = gradient;
ctx.lineWidth = PIPE_WIDTH;
ctx.beginPath();
ctx.moveTo(seg.x1, seg.y1);
ctx.lineTo(seg.x2, seg.y2);
ctx.stroke();
ctx.strokeStyle = 'rgba(255,255,255,0.1)';
ctx.lineWidth = 1;
ctx.beginPath();
ctx.moveTo(seg.x1, seg.y1);
ctx.lineTo(seg.x2, seg.y2);
ctx.stroke();
});
ctx.globalAlpha = 1;
}
}
const pipes = [];
for (let i = 0; i < MAX_PIPES; i++) {
const p = new Pipe();
for (let j = 0; j < 30; j++) p.move();
pipes.push(p);
}
function animate() {
ctx.fillStyle = 'rgba(10,10,10,0.03)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
pipes.forEach(pipe => {
pipe.move();
pipe.draw();
});
requestAnimationFrame(animate);
}
animate();
})();
En résumé
Les screensavers partagent des mécanismes techniques récurrents qui expliquent leur fluidité et leur charme :
- déplacement ;
- rebonds sur les bords ;
- boucles d’animation ;
- variations visuelles.
Les exemples que j’ai pris valident une grande partie de ces points. Mais, si on regarde les autres (Marquee, Ribbons, Bubbles, …), on retombe encore et encore sur les mêmes principes.
En tant que spécialiste des TPE et particuliers, je développe aussi des outils sur mesure – scripts d’automatisation, interfaces simplifiées…





Laisser un commentaire