S O N I C SUITE
Seis librerías JavaScript, sin dependencias, para que una web escuche la música y se mueva con ella. Todo lo que ves aquí funciona en vivo con la misma canción.
Usa audífonos. Pista de demostración: «Enamorado tuyo», El Cuarteto de Nos, separada en voz, batería, bajo y melodía.
SonicMotionv4.4.0
El corazón de la suite. Suena la mezcla y, en silencio, analiza cada pista separada: energía real, bandas grave/medio/agudo y el instante exacto de cada golpe, compensando la latencia de los parlantes.
- Atributos
data-sonic: sin escribir animaciones. onFrameconvalue,onsetybandspor stem.- Mezcla por stems: escucha cada pista por separado.
npm i sonicmotionimport SonicMotion from 'sonicmotion';
const sonic = SonicMotion.create({ master: '/audio/master.mp3' });
sonic.addStem('drums', '/audio/drums.mp3');
sonic.addStem('bass', '/audio/bass.mp3', { onsetThreshold: 3, minOnsetGapMs: 120 });
SonicMotion.registerEffect('skyGlow', (el, v) => { // efecto propio
el.style.boxShadow = `0 0 ${v * 40}px rgba(74, 168, 224, ${v})`;
});
sonic.initDOM(); // <div data-sonic="scale" data-sonic-track="drums">
sonic.onFrame((d) => {
if (d.drums.bands.bass.onset > 0) flash(); // cada golpe de bombo
});
playButton.onclick = () => sonic.play(); SonicWavev1.2.0
Forma de onda, ecualizador y espectro en Canvas, livianos y sin dependencias. Una alternativa a WaveSurfer.js que se alimenta directo de SonicMotion.
- La barra de abajo es su forma de onda: tócala para saltar.
- Ecualizador que sigue el puntero cuando no hay música.
- Espectro en barras, línea o espejo, escala logarítmica.
npm i sonicwaveimport SonicWave from 'sonicwave';
const eq = SonicWave.createEqualizer({ container: '#eq', barCount: 28 });
const spectrum = SonicWave.createSpectrum({ container: '#spectrum', mode: 'mirror' });
const wave = SonicWave.createWaveform({ container: '#waveform' });
wave.setPeaks(peaks, duration); // sin decodificar 4 min de audio
wave.enableSeek((p) => sonic.seek(p * duration));
sonic.onFrame(() => {
eq.setAudioData(sonic.getSpectrum('drums'));
spectrum.update(sonic.getSpectrum('other'));
wave.setTime(sonic.currentTime);
}); SonicFXv1.2.0
Degradados, filtros CSS y bordes que reaccionan al audio, con presets listos por instrumento. Solo reescribe un estilo cuando su valor cambia.
- Presets
bassPulse,drumsHit,vocalsWave,otherFlow. - Bordes, filtros y degradados con su propio control.
- Declarativo con
data-sonicfxo por JavaScript.
npm i sonicfximport SonicFX from 'sonicfx';
const fx = SonicFX.create();
let frame = {};
sonic.onFrame((d) => { frame = d; });
fx.setDataSource(() => frame);
// <div data-sonicfx="bassPulse" data-sonicfx-track="bass" data-sonicfx-color="#4aa8e0">
fx.parseDOM();
fx.bind('#titulo', 'borderRainbow', { stem: 'other' });
fx.start(); SonicScrollv1.2.0
Entradas al hacer scroll con IntersectionObserver, una alternativa moderna a AOS. Su modo AudioAware dice qué está en pantalla, así la música solo mueve lo que se ve.
- Todas las secciones de esta página entran con SonicScroll.
slideUp,fadeIn,scaleIn,flipIn…- Respeta
prefers-reduced-motion.
npm i sonicscrollAudioAware: 0 tarjetas en pantalla
import SonicScroll from 'sonicscroll';
const scroll = SonicScroll.create({ once: true });
scroll.init(); // <div data-scroll="slideUp" data-scroll-delay="120">
const aware = scroll.createAudioAware();
aware.trackAll('.scroll-card');
sonic.onFrame((d) => {
const kick = d.drums.bands.bass.punch;
for (const el of aware.getVisible()) // solo lo que está en pantalla
el.style.transform = `scale(${1 + kick * 0.06})`;
}); SonicLyricsv1.3.0
Letra palabra por palabra que sigue lo que realmente se escucha, no el reloj del navegador. Lee el formato de Whisper/WhisperX y sobrevive a los saltos.
- Eventos
onWordyonLine, o consultas por tiempo. - Etiquetas por palabra para disparar efectos.
- Aquí el texto es propio: cada palabra cae en un ataque real de la voz.
npm i soniclyricsimport SonicLyrics from 'soniclyrics';
// { words: [{ word, start, end, line }] } (el formato de Whisper)
const lyrics = SonicLyrics.create({ src: '/audio/lyrics.json', sonic });
lyrics.onLine((line) => pintarLinea(line?.words ?? []));
lyrics.onWord((w) => encender(w)); // 80 ms antes de que suene
// después de saltar en la canción
lyrics.seek(sonic.audibleTime); SonicPerfv1.2.0
Lo que hace que una web musical no se coma la batería: tope de cuadros por segundo, carga diferida y pausa automática cuando la pestaña no se ve.
- Esta animación arranca recién cuando aparece en pantalla.
- Cambia el tope de FPS y mira el costo real.
- Cambia de pestaña: la música se pausa y vuelve sola.
npm i sonicperfimport SonicPerf from 'sonicperf';
const throttler = SonicPerf.createThrottler({ targetFPS: 30 });
const loader = SonicPerf.createLazyLoader();
loader.loadOnVisible('#perf-canvas', () => throttler.start(dibujar));
fpsButtons.onclick = (fps) => throttler.setFPS(fps);
const vis = SonicPerf.createVisibilityManager();
vis.autoPause(sonic); // pestaña oculta → pausa; al volver → sigue Hecho con Sonic Suite
Dos experiencias completas que usan estas librerías.
La Paz Sonora
Un día en La Paz en tres canciones: la ciudad en pixel art reacciona a cada stem, con letra sincronizada y efectos que siguen los drops.
las 6 librerías
lapazsong.codetec.app →Tributo a Michael Jackson
"Ben" (1972) convertido en un tributo interactivo que reacciona a cada pista de la canción.
SonicMotion · SonicWave · SonicFX · SonicScroll · SonicPerf · SonicLyrics
tributo.codetec.app →