Files
shalom/docs/03-interattivita-coinvolgimento.md
2026-07-02 12:55:16 +02:00

25 KiB
Raw Blame History

03 — Interattività e Coinvolgimento

Come trasformare l'assegnazione di ~20 persone a un set di stanze in uno spettacolo condiviso in stile scommesse / game-show / slot machine, guardato tutti insieme su un unico schermo.

Questo documento raccoglie idee di game design, meccaniche di gamification, sound design, momenti di celebrazione e soluzioni tecniche concrete (con nomi di librerie e URL CDN reali) per rendere la web app massimamente divertente e coinvolgente.


1. Il principio di base: l'attesa vale più del premio

La ricerca sul gambling e sui game-show è concorde: l'anticipazione conta più del risultato. Il rilascio di dopamina è massimo nei momenti che precedono la rivelazione, non nella rivelazione stessa. I "reward" imprevedibili (variable ratio reward schedule) generano una risposta emotiva molto più forte di quelli prevedibili.

Implicazioni di design per la nostra app:

  • Non rivelare tutto insieme. Diluire l'assegnazione nel tempo (una persona / una stanza alla volta) moltiplica i picchi di tensione.
  • Rallentare proprio prima del risultato. Come la ruota della fortuna che decelera: gli ultimi secondi prima dello "stop" sono quelli che valgono.
  • Sfruttare il "quasi-vinto" (near-miss). Far vedere che qualcuno stava per finire nella "stanza VIP" ma poi... no. Il near-miss tiene il cervello in stato di attesa e alza l'engagement di tutta la sala.
  • Incertezza come feature, non come bug. Non mostrare mai l'esito prima del tempo; la sorpresa è il prodotto.

Questi principi guidano tutte le sezioni successive.


2. Meccaniche di engagement e gamification

2.1 Suspense e reveal sociale

  • Reveal una persona alla volta: il nome della persona appare, parte lo "spin", e solo dopo si scopre la stanza. Ogni singola assegnazione diventa un micro-evento.
  • Spinning wheel / slot reel come metafora principale: la ruota/rullo che gira e decelera è una delle meccaniche di suspense più efficaci perché il pubblico vede tutti gli esiti possibili scorrere davanti e può "tifare" per uno di essi.
  • Ordine di rivelazione studiato per il dramma (vedi §6): non alfabetico, ma costruito a crescendo.
  • Countdown visibile (3… 2… 1…) prima di ogni spin, con drumroll audio e vibrazione.

2.2 Scommesse / pronostici prima del reveal (il cuore "gambling")

Prima che l'algoritmo riveli le assegnazioni, si apre una finestra di pronostici:

  • Ogni partecipante (o la sala a mano alzata, in modalità single-screen) prova a indovinare in quale stanza finirà una data persona.
  • Si possono mostrare quote/odds fittizie accanto a ogni stanza ("Stanza VIP paga 5x", "Stanza Sgabuzzino paga 1.2x") per dare sapore da sala scommesse e orientare l'ironia del gruppo.
  • Punti / gettoni virtuali da puntare: chi indovina di più sale in classifica.
  • Il momento della rivelazione diventa doppiamente teso: non scopri solo dove va la persona, ma anche se hai vinto la scommessa.

Questa meccanica sfrutta esattamente la psicologia dell'incertezza del premio: la posta in gioco personale amplifica l'attenzione di tutti.

2.3 Leaderboard e classifiche

  • Classifica pronosticatori: chi ha indovinato più assegnazioni.
  • Aggiornamento live dopo ogni reveal, con animazione di scalata (righe che si riordinano).
  • Ranking individuale e/o a squadre; le squadre aumentano il tifo e le esultanze collettive.
  • La leaderboard è essa stessa un momento di spettacolo: mostrarla a schermo intero tra un blocco di reveal e l'altro.

2.4 Reazioni, emoji e tifo

  • Emoji reactions in tempo reale che volano sullo schermo condiviso (🎉 😱 🔥 👑 💀) quando esce un'assegnazione clamorosa.
  • Se i telefoni sono connessi (vedi §7), i partecipanti "lanciano" emoji dal telefono e appaiono sul proiettore.
  • In modalità puramente single-screen: reazioni scatenate da tasti/hotkey dell'MC, o semplicemente dal tifo dal vivo amplificato dagli effetti audio/visivi.

2.5 Streak e momenti speciali

  • Streak del pronosticatore: 3 assegnazioni indovinate di fila → effetto "on fire" 🔥 con audio e confetti dedicati.
  • Streak di stanza: se la stessa stanza riceve N persone di fila → "HOT ROOM" con luci lampeggianti.
  • Combo/moltiplicatori: più la streak è lunga, più i punti valgono (moltiplicatore visibile che sale), come nei giochi arcade.

2.6 Feedback game-show generale

  • MC / annunciatore (testo + audio): battute pre-scritte a tema per ogni tipo di reveal (vedi §6.4).
  • Barra di "hype" che si riempie con le reazioni della sala.
  • Achievement/badge sbloccabili ("Primo Jackpot", "Cappotto di pronostici", "Sfortunato del giorno").

3. Sound design

Il suono è metà dello spettacolo. Serve un piccolo kit di effetti riutilizzabili.

3.1 Gli effetti chiave da avere

Momento Suono Quando parte
Avvio spin whoosh / rullo che accelera inizio dell'animazione della slot/ruota
Rotazione tick-tick-tick dei rulli durante lo spin (loop)
Decelerazione ticchettio che rallenta ultimi secondi prima dello stop
Assegnazione normale ding / campanello quando si ferma su una stanza
Stanza VIP / jackpot jackpot + monete che cadono (coin drop) reveal di una stanza speciale
Pre-reveal drammatico drumroll (rullo di tamburi) durante il countdown 3-2-1
Vittoria / grande momento crowd cheer (folla che esulta) jackpot, fine evento, streak
Errore / near-miss buzz / sad trombone quando un pronostico fallisce
Cambio schermata swoosh UI transizioni tra i blocchi

3.2 Dove trovare effetti sonori GRATIS (royalty-free)

Tutte fonti utilizzabili in progetti personali e commerciali (verificare la licenza del singolo file).

Mixkit — nessuna registrazione, uso libero personale e commerciale:

Pixabay — royalty-free, nessuna attribuzione richiesta, download MP3:

Freesound — database collaborativo Creative Commons (attenzione: alcuni file richiedono attribuzione, controllare la licenza CC0 vs CC-BY):

Suggerimento pratico: scaricare gli MP3, normalizzare i volumi (un jackpot troppo forte rispetto al ding rovina l'esperienza) e tenerli in una cartella assets/audio/ con nomi parlanti (spin.mp3, ding.mp3, jackpot.mp3, drumroll.mp3, coin.mp3, cheer.mp3, buzz.mp3).

3.3 Come far partire i suoni nel browser

Due strade: <audio> semplice, oppure la Web Audio API / Howler.js per controllo fine e niente latenza.

Attenzione all'autoplay policy. I browser (da Chrome 71 in poi) bloccano l'audio finché non c'è un'interazione utente. Un AudioContext creato prima di un gesto utente nasce in stato suspended. Va sbloccato al primo click/tap (es. il bottone "Inizia lo show") chiamando resume(). Best practice: un unico "gesto di sblocco" all'avvio dell'evento.

Sblocco base con Web Audio API:

const audioCtx = new (window.AudioContext || window.webkitAudioContext)();

// da chiamare dentro un handler di click/tap (es. bottone "Avvia lo show")
function unlockAudio() {
  if (audioCtx.state === 'suspended') {
    audioCtx.resume();
  }
}
document.querySelector('#start-btn').addEventListener('click', unlockAudio, { once: true });

Howler.js (consigliato: gestisce autoplay, sprite audio, volumi, fallback HTML5 in automatico).

CDN:

<script src="https://cdnjs.cloudflare.com/ajax/libs/howler/2.2.4/howler.min.js"></script>

Uso:

const sfx = {
  spin:     new Howl({ src: ['assets/audio/spin.mp3'], volume: 0.6 }),
  ding:     new Howl({ src: ['assets/audio/ding.mp3'] }),
  jackpot:  new Howl({ src: ['assets/audio/jackpot.mp3'], volume: 0.9 }),
  drumroll: new Howl({ src: ['assets/audio/drumroll.mp3'] }),
  coin:     new Howl({ src: ['assets/audio/coin.mp3'] }),
  cheer:    new Howl({ src: ['assets/audio/cheer.mp3'] }),
  buzz:     new Howl({ src: ['assets/audio/buzz.mp3'] }),
};

// esempio: sequenza di un reveal
sfx.drumroll.play();
// ...al momento dello stop
sfx.ding.play();

Perché Howler: parte da ~7KB gzipped, usa Web Audio con fallback su HTML5 Audio, supporta audio sprite (utile per impacchettare tutti gli effetti in un solo file e ridurre le richieste) e semplifica volumi/fade. Docs: https://howlerjs.com/.


4. Momenti di celebrazione (celebration UX)

Gli effetti visivi trasformano un reveal in un evento memorabile. La regola d'oro: scalare l'intensità dell'effetto in base all'importanza del momento (assegnazione normale = piccolo puff; jackpot VIP = tutto lo schermo esplode).

4.1 Confetti — canvas-confetti

Libreria leggera (< 10KB gzip), performante, esposta come funzione globale confetti().

CDN:

<script src="https://cdn.jsdelivr.net/npm/canvas-confetti@1.9.4/dist/confetti.browser.min.js"></script>
<!-- alternativa cdnjs -->
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/canvas-confetti/1.9.3/confetti.min.js"></script> -->

Burst semplice (assegnazione normale):

confetti({ particleCount: 120, spread: 70, origin: { y: 0.6 } });

Fireworks / fuochi d'artificio (jackpot, fine evento) — due getti laterali ripetuti:

const duration = 4 * 1000;
const end = Date.now() + duration;
(function frame() {
  confetti({ particleCount: 7, angle: 60,  spread: 55, origin: { x: 0 } });
  confetti({ particleCount: 7, angle: 120, spread: 55, origin: { x: 1 } });
  if (Date.now() < end) requestAnimationFrame(frame);
}());

Confetti a emoji/testo (es. 👑 per la stanza VIP):

const crown = confetti.shapeFromText({ text: '👑', scalar: 2 });
confetti({ shapes: [crown], scalar: 2, particleCount: 40, spread: 100 });

Opzioni utili: particleCount, spread, angle, startVelocity, gravity, colors (array HEX), shapes (square/circle/star/custom), origin.x/.y, scalar, ticks. Accessibilità: usare disableForReducedMotion: true per rispettare chi preferisce meno animazioni.

Demo/preset ufficiali (fireworks, snow, school pride, ecc.): https://www.kirilv.com/canvas-confetti/

Alternativa con supporto emoji nativo: js-confettihttps://github.com/loonywizard/js-confetti.

4.2 Screen shake, flash e luci lampeggianti

Effetti CSS/JS a basso costo, molto d'impatto sullo schermo grande:

@keyframes shake {
  0%,100% { transform: translate(0,0); }
  20% { transform: translate(-8px, 4px); }
  40% { transform: translate(8px, -4px); }
  60% { transform: translate(-6px, -6px); }
  80% { transform: translate(6px, 6px); }
}
.shake { animation: shake 0.4s ease-in-out; }

@keyframes flash {
  0%,100% { background: transparent; }
  50% { background: rgba(255,255,255,0.85); }
}
.flash { animation: flash 0.15s ease-in-out 3; } /* triplo flash */
  • Screen shake sul reveal del jackpot (aggiungere/rimuovere la classe .shake sul container).
  • Flash bianco al momento dello "stop" della slot.
  • Luci lampeggianti in stile casinò: bordo dello schermo con luci che corrono (box-shadow animato o una fila di "bulbi" attorno al frame).

4.3 Winner spotlight (riflettore sul vincitore)

Al reveal di una persona in stanza speciale, o del "vincitore" dei pronostici:

  • Oscurare lo sfondo (overlay scuro) e lasciare un cono di luce/riflettore (radial-gradient) sul nome/foto della persona.
  • Zoom-in + pop dell'elemento (scala da 0.8 a 1.1 e ritorno) con anime.js o CSS.
  • Nome grande, corona/badge, confetti a corona (§4.1) e crowd cheer (§3).

4.4 Anime.js per orchestrare le animazioni

Per sequenze complesse (countdown → spin → stop → celebrazione) conviene una timeline.

CDN:

<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js"></script>

Esempio di reveal a più elementi con stagger (le lettere/righe che appaiono a cascata):

anime({
  targets: '.reveal-letter',
  translateY: [40, 0],
  opacity: [0, 1],
  delay: anime.stagger(60),   // 60ms tra un elemento e l'altro
  easing: 'easeOutBack'
});

Anime.js gestisce timeline, keyframes, easing e staggering: ideale per sincronizzare animazione visiva e cue audio. Docs: https://animejs.com/documentation/.


5. Haptics / feedback su mobile (navigator.vibrate)

Se i partecipanti tengono il telefono in mano (modalità connessa, §7), la vibrazione aggiunge un canale sensoriale al reveal.

API base:

// vibrazione singola (ms)
navigator.vibrate(200);

// pattern: [vibra, pausa, vibra, ...]
navigator.vibrate([100, 50, 100]);      // doppio buzz "successo"
navigator.vibrate([300, 100, 300, 100, 300]); // jackpot

Idee d'uso:

  • Countdown: micro-vibrazione a ogni tick (3-2-1).
  • Spin: vibrazione continua/pulsata durante la rotazione.
  • Stop/assegnazione: singolo buzz secco.
  • Pronostico indovinato: doppio buzz "successo"; fallito: triplo buzz "errore".
  • Jackpot: pattern lungo e ritmico.

Best practice (da MDN):

  • Durate brevi: 50200ms sono ideali; una nuova vibrate() annulla la precedente, quindi evitare chiamate a raffica.
  • Va invocata dentro un gesto utente (sticky user activation): legarla a click/tap.
  • Additiva, mai unico canale di feedback: offrire un toggle per disattivarla (c'è chi la odia o non la percepisce).

Supporto: Chrome/Edge/Opera/Samsung Internet e Android. Safari (iOS/macOS) non la supporta e Firefox l'ha rimossa da v129: fare feature-detection e degradare con grazia.

if ('vibrate' in navigator) { navigator.vibrate(200); }

Riferimento: https://developer.mozilla.org/en-US/docs/Web/API/Navigator/vibrate


6. Idee specifiche per il reveal "persone → stanze"

Qui sta la vera anima dello spettacolo. Suggerimenti per rendere l'assegnazione un evento condiviso.

6.1 Struttura del reveal, una persona alla volta

  1. Appare il nome (e foto) della persona di turno al centro.
  2. Parte lo spin della slot/ruota con le stanze come simboli.
  3. Countdown 3-2-1 con drumroll + vibrazione.
  4. La ruota decelera (near-miss: rallenta vicino a una stanza "clamorosa" e poi supera).
  5. Stop su una stanza → ding / o jackpot se speciale → confetti scalati all'importanza.
  6. Aggiornamento leaderboard pronostici e reazioni della sala.

6.2 Scommesse su chi va dove

  • Prima del blocco, la sala pronostica: "Dove finirà Marco?".
  • Quote/odds mostrate accanto alle stanze per ironia e strategia.
  • La rivelazione risolve due tensioni insieme (dove va Marco + chi ha indovinato).

6.3 Stanze speciali e "VIP room jackpot"

  • Designare una o più stanze come speciali: "Stanza VIP" 👑, "Suite Presidenziale", oppure la temutissima "Sgabuzzino" 💀.
  • Quando qualcuno ci finisce → trattamento jackpot: full-screen fireworks, crowd cheer, coin drop, screen shake, spotlight.
  • Le stanze speciali possono avere posti limitati (scarsità = più tensione a ogni assegnazione: "resta un solo posto VIP!").
  • Progressive jackpot: una stanza "misteriosa" il cui contenuto/premio cresce a ogni reveal finché non viene assegnata.

6.4 Ordine di rivelazione per il massimo dramma

  • Non alfabetico. Costruire un crescendo: prima assegnazioni "normali", poi i colpi di scena.
  • Tenere per ultimi i reveal più attesi (le stanze speciali, le persone-chiave, il pareggio di una scommessa).
  • Alternare ritmo: qualche reveal veloce di fila, poi uno rallentato al massimo con countdown lungo.
  • Blocchi tematici con schermate-ponte (leaderboard, "coming up next") per far respirare la tensione e ripartire.

6.5 Testi da MC / annunciatore

Frasi pre-scritte (testo a schermo + eventuale TTS/audio) a seconda dell'esito. Esempi:

  • Apertura: "Signore e signori, benvenuti alla GRANDE ASSEGNAZIONE! 20 persone, X stanze, un solo destino. Che la sorte decida!"
  • Pre-spin: "Il prossimo concorrente è… MARCO. Dove lo manderà la ruota? Fate le vostre puntate!"
  • Near-miss: "Ohhh! Era a un passo dalla Suite VIP… ma no!"
  • Assegnazione normale: "E Marco va nella Stanza 3! Un applauso."
  • Jackpot: "JACKPOT!!! Marco conquista la STANZA VIP! 👑 Che fortuna sfacciata!"
  • Sfortuna: "Ahia… Sgabuzzino. Condoglianze, Marco. 💀"
  • Chiusura: "E con questo le stanze sono assegnate! Applauso finale per tutti i concorrenti!"

6.6 Reazioni ed emoji legate al reveal

  • Set di emoji rapide (👑 😱 🔥 💀 🎉 👏) scatenabili dalla sala/telefoni al momento giusto.
  • Contatore reazioni per rendere "virale" il momento in sala.

7. Multiplayer / schermo condiviso (anche senza backend)

Obiettivo: farlo funzionare bene anche senza server, con opzioni di upgrade se serve interazione dai telefoni.

7.1 Modalità "single-screen / projector" (zero backend) — consigliata per partire

  • Un solo schermo (proiettore o TV) mostra tutto lo show; l'MC guida con tastiera/telecomando.
  • Tutta la logica gira client-side nel browser: l'assegnazione può essere pre-calcolata o generata in loco, poi il reveal è pura animazione.
  • I pronostici si fanno a voce / a mano alzata, l'MC li registra o semplicemente la sala tifa.
  • Pro: nessuna infrastruttura, nessun rischio di rete, massima affidabilità in evento dal vivo.
  • Il modello dei party game (Jackbox, Kahoot) conferma che un solo schermo condiviso è al centro dell'esperienza collettiva; i telefoni sono solo controller opzionali.

7.2 Aggiungere i telefoni con un QR code

Come Jackbox.tv / Kahoot: a schermo appare un QR code + codice stanza; i partecipanti scansionano e aprono una pagina "controller" nel browser (nessuna app da installare).

Generare il QR lato client:

<script src="https://cdn.jsdelivr.net/npm/qrcodejs@1.0.0/qrcode.min.js"></script>
<div id="qr"></div>
<script>
  new QRCode(document.getElementById('qr'), 'https://tuo-dominio/join?room=AB12');
</script>

(libreria: qrcodejshttps://github.com/davidshimjs/qrcodejs)

7.3 Sincronizzazione telefoni ↔ schermo con backend minimale

Se vuoi che i pronostici/emoji dai telefoni appaiano in tempo reale sul proiettore, serve un piccolo canale realtime. Opzioni leggere:

  • BroadcastChannel APIgratis, zero backend, ma solo tra schede dello stesso dispositivo/ browser (utile per prototipare o per setup a più finestre sullo stesso PC). Non attraversa dispositivi diversi.
  • WebSocket su un piccolo server (Node) o servizio serverless.
  • Cloudflare Durable Objects — ottimi per "stanze" realtime multiplayer con stato condiviso (coordinamento di una room, WebSocket, stato per-stanza) senza gestire server tradizionali.
  • Servizi realtime gestiti (es. Firebase Realtime Database / Firestore, Supabase Realtime) se si preferisce non scrivere backend.

Raccomandazione: partire single-screen (§7.1), aggiungere il QR + controller (§7.2) solo se si vuole l'interazione dai telefoni, e introdurre un backend realtime solo se i pronostici live diventano centrali.


8. Stack tecnico consigliato (riepilogo librerie e CDN)

Scopo Libreria CDN
Confetti / fuochi canvas-confetti https://cdn.jsdelivr.net/npm/canvas-confetti@1.9.4/dist/confetti.browser.min.js
Confetti con emoji (alt.) js-confetti https://github.com/loonywizard/js-confetti
Audio / SFX Howler.js https://cdnjs.cloudflare.com/ajax/libs/howler/2.2.4/howler.min.js
Animazioni / timeline anime.js https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js
QR code join qrcodejs https://cdn.jsdelivr.net/npm/qrcodejs@1.0.0/qrcode.min.js
Haptics Vibration API (nativa) navigator.vibrate()
Sblocco/gestione audio Web Audio API (nativa) AudioContext + resume()
Realtime opzionale Cloudflare Durable Objects / WebSocket / Firebase

Checklist di implementazione

  • Sbloccare l'audio al primo tap (bottone "Avvia lo show").
  • Precaricare tutti gli SFX (Howler) e le immagini prima dell'evento.
  • Scalare gli effetti (confetti/shake/audio) sull'importanza del reveal.
  • Rispettare prefers-reduced-motion (disableForReducedMotion) e offrire toggle audio/haptics.
  • Feature-detection per navigator.vibrate (assente su iOS/Safari e Firefox recenti).
  • Testare su schermo grande + audio potente (l'evento è dal vivo, il volume conta).
  • Curare l'ordine di reveal per il crescendo drammatico.

Fonti

Confetti / animazioni

Audio / Web Audio

Effetti sonori gratuiti

Haptics

Gamification / game-show / psicologia

Schermo condiviso / multiplayer