Reaction Burst
Barre de réactions emoji pour live streaming : trajectoire bézier cubique par particule, wobble sinus latéral, pool DOM recyclé (40 max) et flux d'autres spectateurs simulé — zéro canvas, prefers-reduced-motion natif.
Vous aurez accès à la démo interactive avec un compte gratuit.
Cet effet fait partie d'Effect.Labs — 811 effets vanilla, une partie gratuite, une partie premium. Atmosphère comprend 57 effets, dont 10 gratuits. Découvrir la catégorie →
3 exemples d'usage



Comment ça marche
L'effet crée une instance RBXScene par .rbx-scene trouvé dans le DOM. Chaque instance gère un pool de <span> réutilisables (max 40 actifs simultanément) : quand un span est libéré en fin de trajectoire, il est repoussé dans le pool au lieu d'être supprimé — zéro création d'éléments à chaud après la première vague.
À chaque clic ou touche Entrée/Espace, react() calcule les coordonnées de départ depuis le bord bas du stage (client → local), puis appelle _launch() pour chaque particule du burst. La trajectoire est une courbe de Bézier cubique 1D (bz(t, p0, p1, p2, p3)) appliquée séparément sur x et y — les quatre points de contrôle sont tirés aléatoirement à chaque lancement. Un wobble sinus (Math.sin(t × π × wFreq) × wAmp) est ajouté à x pour ondulation latérale. L'opacité suit une rampe plate de 0 à 0,55 puis un fondu de 0,55 à 1 ; la taille scale-in de 0→0,12, plafonne, puis réduit légèrement vers la fin.
Un flux live simulé tourne en parallèle via un setTimeout auto-replanifiant (intervalle aléatoire 600–2600 ms par défaut). Il choisit un emoji au hasard, incrémente son compteur, et lance une particule depuis le quart droit du stage pour simuler des réactions d'autres spectateurs. Les compteurs sont formatés par fmt(n) : entiers sous 1 000, une décimale entre 1 000 et 9 999 (1.2k), entier au-dessus de 10 000 (12k) ; les éléments aria-live="polite" les transmettent aux lecteurs d'écran.
La boucle rAF itère le tableau _active à rebours et retire les particules arrivées à t = 1. Si le pool est saturé au moment d'un nouveau lancement, la particule la plus ancienne est evincée (_active.shift()) pour laisser la place — plafond strict de 40. L'API publique window.RBX_0839.scenes[i] expose setBurst(n), setLiveSpeed(preset), fireAll() et resetCounts() pour piloter chaque scène indépendamment.
Accessibilité
- prefers-reduced-motion : détecté au démarrage via
matchMedia. En mode réduit, le CSS désactiverbx-bumping(animation scale bouton) et la pulsation du point LIVE ; le JS envoie 1 seule particule par clic (au lieu de 3), durée 420 ms, en ligne droite (interpolation linéaire sans Bézier). Le flux live ne génère aucune particule mais continue d'incrémenter les compteurs. - Chaque
.rbx-btnest un<button>natif avecaria-labeldescriptif (« J'aime », « Cœur »…). Le JS liekeydownsur Entrée et Espace — l'effet est entièrement utilisable au clavier. .rbx-btn-countet.rbx-total-countportentaria-live="polite": les lecteurs d'écran annoncent chaque mise à jour de compteur sans interrompre la lecture en cours.- Les particules volantes (
.rbx-particle) portentaria-hidden="true"et sont absentes du flux de tabulation — elles n'interfèrent pas avec la navigation clavier ni avec les lecteurs d'écran. - Le bouton actif reçoit un anneau
:focus-visibleorange (outline-color: #f59e0b) visible en fond sombre (ratio de contraste ≥ 3:1 sur#0a0a0f). Le groupe de boutons est annotérole="group" aria-label="Réactions".
Compatibilité navigateur
Nécessite DOM moderne, requestAnimationFrame et classList — aucun canvas, aucune dépendance externe.
Si JS est désactivé, la barre de réactions reste visible en HTML pur avec les compteurs statiques initiaux — aucune erreur, la page reste fonctionnelle.
Le code
Structure HTML à coller dans votre page (CSS + JS disponibles avec un compte premium) :
<div class="rbx-scene" role="region" aria-label="Barre de réactions live — clique sur un emoji pour envoyer une réaction">
<!-- Zone de vol des particules + fond visuel + badge LIVE -->
<div class="rbx-stage">
<div class="rbx-video-bg" aria-hidden="true"></div>
<div class="rbx-live-badge" aria-hidden="true">
<span class="rbx-live-dot"></span>
<span class="rbx-live-text">LIVE</span>
<span class="rbx-viewer-count">1 284 spectateurs</span>
</div>
<!-- Contenu libre : thumbnail, titre, player… -->
<div class="rbx-video-meta" aria-hidden="true">
<div class="rbx-video-icon">…</div>
<span class="rbx-video-title">Titre du live</span>
</div>
</div>
<!-- Barre de réactions -->
<div class="rbx-bar" role="group" aria-label="Réactions">
<button class="rbx-btn" data-initial="847" aria-label="J'aime">
<span class="rbx-btn-emoji" aria-hidden="true">👍</span>
<span class="rbx-btn-count" aria-live="polite">847</span>
</button>
<!-- répéter pour chaque emoji -->
<div class="rbx-total" aria-live="polite" aria-label="Total des réactions">
<span class="rbx-total-label">Total</span>
<span class="rbx-total-count">3.1k</span>
</div>
</div>
</div>
HTML + CSS + JS complet, prêt à coller — avec des centaines d'effets premium.
Personnaliser
Options passées à l'API ou attributs data-* :
| Option / propriété | Défaut | Effet |
|---|---|---|
| data-initial="n" | variable par bouton | Valeur de départ du compteur de chaque .rbx-btn. Changez-la pour afficher un capital social réaliste dès le chargement. |
| RBXScene.setBurst(n) | 3 | Nombre de particules lancées par clic utilisateur. 1 = discret, 3 = défaut, 5–6 = festif. Applicable par scène via window.RBX_0839.scenes[i].setBurst(n). |
| RBXScene.setLiveSpeed(preset) | 2 (600–2600 ms) | Cadence du flux simulé : 1 = lent (1800–4000 ms), 2 = normal, 3 = rapide (200–800 ms). À adapter selon le rythme perçu voulu. |
| RBXScene.fireAll() | — | Déclenche une réaction de chaque des 5 emojis en cascade (90 ms d'écart). Idéal sur un événement métier : paiement confirmé, inscription validée, jalon atteint. |
| RBXScene.resetCounts() | — | Remet tous les compteurs à leur valeur data-initial. Utile pour réinitialiser la démo entre deux tests ou deux sessions. |
| MAX_P (constante JS, ligne 6) | 40 | Plafond strict du pool de particules actives. Réduisez à 20 pour les appareils faibles, montez à 60 pour un effet plus dense — au-delà, la particule la plus ancienne est éjectée. |
| .rbx-scene.rbx-hc | absent | Classe CSS qui passe la barre et les boutons en mode contraste fort (fond #111118, bordures à 40 % d'opacité, textes blancs). À activer via JS selon l'accessibilité détectée. |
| Durée de vol (JS, fonction _launch) | 1100–1800 ms | Constante 1100 + Math.random() * 700 dans _launch(). Réduisez à 600 + Math.random() * 300 pour des réactions vives, augmentez pour un effet plus contemplatif. |
FAQ
<span> positionné en absolute à l'intérieur du .rbx-stage. Les propriétés transform et opacity sont mises à jour à chaque frame via requestAnimationFrame. Cela simplifie l'intégration dans n'importe quel framework (React, Vue, Svelte) et rend les particules intrinsèquement accessibles via aria-hidden._startLive() via un setTimeout. Pour le remplacer, appelez simplement scene.react(emojiIndex, clientX, clientY) depuis votre listener WebSocket — emojiIndex va de 0 (👍) à 4 (👏). Le pool et le plafond de 40 particules s'appliquent identiquement.EMOJIS au sommet de l'IIFE (['👍','❤️','🎉','🔥','👏']). Elle doit rester synchronisée avec les .rbx-btn dans le HTML (même ordre, même longueur) : le bouton d'indice i correspond à EMOJIS[i]. Modifiez les deux ensemble pour changer la palette d'émojis.