Correccion del autor sobre la primera version: «la redaccion esta mal,
empieza como si la gente supiera ya que es lo que has pasado, la redaccion
tiene que ser didactica para un nuevo desarrollador». Tenia razon — estaban
escritas como notas de version para quien vivio el rediseño: se abrian
presumiendo el vocabulario y presumian de cuantas reglas se habian borrado,
que es mi historia, no documentacion.
Reescritas desde cero, en ese orden: primero la escena («guardas un
documento y oyes un repique»), luego el vocabulario construido pieza a
pieza (familia, verbo, intent) y solo entonces la maquinaria. Cada
concepto se explica antes de usar su palabra.
/uix/docs/sound como suena una interfaz — el modelo, con la
resolucion en vivo (familia + verbo + intent)
/uix/docs/sound/catalogo cada sonido que existe, audible, con la razon
de por que suena asi y que significa cada eje
/uix/docs/sound/packs traer tu propia voz: sintesis, wav, mp3,
registrar nombres nuevos, cambiar en caliente
/uix/docs/sound/gestos por que un arrastre suena por repeticion, con
un simulador de tres velocidades para oirlo
DERIVADAS DEL CODIGO: los sonidos, familias, intents y verbos salen de
`SEMA_MAP` y del resolver real. Solo la prosa esta escrita a mano, asi que
añadir una entrada al catalogo la hace aparecer con sus medidas.
Lo historico no desaparece, cambia de sitio: donde aporta —por que los
sonidos son tan distintos entre si, que se gana y que se pierde con el
trinquete— va al final de su seccion como razon, nunca como apertura.
VERIFICADO: las cuatro responden 200 en SSR con sus secciones · check sin
errores nuevos en las paginas.
⚠️ Sigo sin poder mirarlas: el panel del navegador no compone en esta
sesion, asi que la composicion visual queda pendiente de tu ojo.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
alpha-0.1-dir-prefs
parent
86fa9a1b77
commit
05d422ef4a
@ -0,0 +1,213 @@
|
||||
<script lang="ts">
|
||||
/**
|
||||
* `/uix/docs/sound/catalogo` — every entry of the default pack, audible,
|
||||
* with the reason it sounds the way it does.
|
||||
*
|
||||
* The values are DERIVED from `SEMA_MAP.sounds`; only the prose is authored
|
||||
* here, so adding an entry makes it appear with its measurements.
|
||||
*/
|
||||
import { getActiveUix } from '$active-uix';
|
||||
import { SEMA_MAP } from '$uix/sema';
|
||||
|
||||
const uix = getActiveUix();
|
||||
const NAMES = Object.keys(SEMA_MAP.sounds);
|
||||
let stage = $state<HTMLElement | null>(null);
|
||||
|
||||
const WHY: Record<string, { role: string; why: string }> = {
|
||||
touch: {
|
||||
role: 'algo se ha tocado',
|
||||
why: 'Lo más corto que dice el sistema. Brillante e inmediato: confirma que el dedo llegó y se aparta enseguida, porque es lo que más veces vas a oír.'
|
||||
},
|
||||
step: {
|
||||
role: 'un paso de un gesto',
|
||||
why: 'Se repite mientras arrastras, así que tiene que ser diminuto: cualquier cosa más larga se emborronaría al repetirse cada 70 ms.'
|
||||
},
|
||||
tick: {
|
||||
role: 'algo ha quedado hecho',
|
||||
why: 'Un golpe en registro medio, no un clic. Es el sonido de guardar, confirmar, seleccionar — muy frecuente, así que no puede pesar.'
|
||||
},
|
||||
open: {
|
||||
role: 'algo aparece',
|
||||
why: 'Sube. Un contorno ascendente se lee como llegada sin necesidad de subir el volumen.'
|
||||
},
|
||||
close: {
|
||||
role: 'algo se va',
|
||||
why: 'Baja, y es más grave que su apertura. Abrir y cerrar tienen que oírse como una pareja.'
|
||||
},
|
||||
slide: {
|
||||
role: 'el marco cambia',
|
||||
why: 'Un arco grave y lateral: pestañas, pasos de un asistente, navegación. No es algo que aparece, es algo que se desplaza.'
|
||||
},
|
||||
alert: {
|
||||
role: 'el sistema habla solo',
|
||||
why: 'El único que suena sin que hayas hecho nada. Por eso es el más brillante y el más largo de las bases: tiene que ganarte la atención.'
|
||||
},
|
||||
air: {
|
||||
role: 'coges algo',
|
||||
why: 'El primero de los tres sonidos de arrastre. Aire que se levanta cuando agarras.'
|
||||
},
|
||||
settle: {
|
||||
role: 'lo sueltas',
|
||||
why: 'Cae y se posa. Desciende justo donde `air` subía, para que el par agarrar/soltar se reconozca.'
|
||||
},
|
||||
snap: {
|
||||
role: 'encaja en su sitio',
|
||||
why: 'Corto, agudo y en arco. El clic de algo que entra donde debía.'
|
||||
},
|
||||
'tick.fulfill': {
|
||||
role: 'salió bien',
|
||||
why: 'Brillante, ascendente y se le permite durar más. Es el único momento en que el sistema puede celebrar algo.'
|
||||
},
|
||||
'tick.risk': {
|
||||
role: 'ojo con esto',
|
||||
why: 'Registro medio y áspero. La aspereza no es adorno: es lo que hace que el oído lo marque como advertencia y no como confirmación.'
|
||||
},
|
||||
'tick.threat': {
|
||||
role: 'esto va en serio',
|
||||
why: 'Grave, muy áspero y descendente. No es el sonido normal «con más aspereza»: es otro sonido, para que no quepa duda.'
|
||||
},
|
||||
'tick.loss': {
|
||||
role: 'ya no está',
|
||||
why: 'Una caída oscura pero SIN aspereza — porque perder algo no es lo mismo que estar en peligro, y no deben sonar parecido.'
|
||||
},
|
||||
'alert.risk': {
|
||||
role: 'aviso del sistema',
|
||||
why: 'Como el aviso normal pero áspero y más grave, para que no se confunda con una notificación cualquiera.'
|
||||
},
|
||||
'alert.threat': {
|
||||
role: 'error del sistema',
|
||||
why: 'El más grave, el más áspero y el más largo del catálogo. Es el techo: si algo suena así, es lo peor que el sistema tiene que decir.'
|
||||
}
|
||||
};
|
||||
|
||||
function play(name: string) {
|
||||
if (!stage) return;
|
||||
void uix.events?.emit({
|
||||
name: 'probe',
|
||||
family: 'commit' as never,
|
||||
target: stage,
|
||||
overrides: { sound: name }
|
||||
});
|
||||
}
|
||||
|
||||
const AXES = ['pitch', 'centroid', 'duration', 'contour', 'roughness', 'gain'] as const;
|
||||
</script>
|
||||
|
||||
<div data-uix-canvas-inner>
|
||||
<div data-uix-eyebrow>Sema · el sonido</div>
|
||||
<h1 data-uix-page-title>Todos los sonidos que existen.</h1>
|
||||
<p data-uix-page-lede>
|
||||
Estos son los sonidos que un componente puede pedir por su nombre. No hay más, y esa es la
|
||||
gracia: un conjunto pequeño y cerrado significa que puedes aprendértelo, y que dos partes
|
||||
distintas de la aplicación no acaban sonando parecido por accidente. Púlsalos para oírlos
|
||||
(necesitas <em>Sound</em> encendido en la barra superior).
|
||||
</p>
|
||||
<div data-uix-page-meta>
|
||||
<span data-uix-meta-pill><span data-uix-meta-key>sonidos</span>{NAMES.length}</span>
|
||||
<span data-uix-meta-pill><span data-uix-meta-key>ficheros de audio</span>ninguno</span>
|
||||
</div>
|
||||
|
||||
<div bind:this={stage} data-uix-sound-stage aria-hidden="true"></div>
|
||||
|
||||
<section data-uix-section>
|
||||
<h2 data-uix-section-title>Dos clases de entrada</h2>
|
||||
<p data-uix-section-desc>
|
||||
Las <strong>bases</strong> son el sonido de un tipo de suceso: tocar, confirmar, abrir. Las
|
||||
<strong>versiones</strong>
|
||||
llevan un sufijo con un intent (<code>tick.threat</code>) y son lo que suena cuando ese suceso
|
||||
ocurre con esa carga. Si un suceso tiene un intent para el que no hay versión, suena la base —
|
||||
nunca falla, sólo dice menos.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section data-uix-section>
|
||||
<h2 data-uix-section-title>Bases</h2>
|
||||
{#each NAMES.filter((n) => !n.includes('.')) as name}
|
||||
{@const s = SEMA_MAP.sounds[name] as Record<string, unknown>}
|
||||
{@const why = WHY[name]}
|
||||
<div data-uix-sound-entry>
|
||||
<div data-uix-sound-entry-head>
|
||||
<button type="button" data-uix-sound-chip onclick={() => play(name)}>
|
||||
<span data-uix-sound-chip-name>{name}</span>
|
||||
<span data-uix-sound-chip-play>▶</span>
|
||||
</button>
|
||||
<span data-uix-sound-entry-role>{why?.role ?? ''}</span>
|
||||
</div>
|
||||
<p data-uix-sound-entry-why>{why?.why ?? ''}</p>
|
||||
<div data-uix-sound-axes>
|
||||
{#each AXES as axis}
|
||||
<span data-uix-sound-axis
|
||||
><span data-uix-sound-axis-key>{axis}</span>{String(s[axis])}</span
|
||||
>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
</section>
|
||||
|
||||
<section data-uix-section>
|
||||
<h2 data-uix-section-title>Versiones por intent</h2>
|
||||
{#each NAMES.filter((n) => n.includes('.')) as name}
|
||||
{@const s = SEMA_MAP.sounds[name] as Record<string, unknown>}
|
||||
{@const why = WHY[name]}
|
||||
<div data-uix-sound-entry>
|
||||
<div data-uix-sound-entry-head>
|
||||
<button type="button" data-uix-sound-chip onclick={() => play(name)}>
|
||||
<span data-uix-sound-chip-name>{name}</span>
|
||||
<span data-uix-sound-chip-play>▶</span>
|
||||
</button>
|
||||
<span data-uix-sound-entry-role>{why?.role ?? ''}</span>
|
||||
</div>
|
||||
<p data-uix-sound-entry-why>{why?.why ?? ''}</p>
|
||||
<div data-uix-sound-axes>
|
||||
{#each AXES as axis}
|
||||
<span data-uix-sound-axis
|
||||
><span data-uix-sound-axis-key>{axis}</span>{String(s[axis])}</span
|
||||
>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
</section>
|
||||
|
||||
<section data-uix-section>
|
||||
<h2 data-uix-section-title>Qué significan esos números</h2>
|
||||
<p data-uix-section-desc>
|
||||
Cada sonido se sintetiza a partir de seis valores. Los ves aquí para entender el diseño, pero <strong
|
||||
>no vas a escribirlos nunca</strong
|
||||
>: viven en el catálogo y en ningún otro sitio.
|
||||
</p>
|
||||
<ul data-uix-prose-list>
|
||||
<li><code>pitch</code> — la altura, en hercios. Grave abajo, agudo arriba.</li>
|
||||
<li>
|
||||
<code>centroid</code> — el <em>brillo</em>. Técnicamente es dónde corta un filtro: cuanto
|
||||
más alto, más armónicos pasan y más «cristalino» suena.
|
||||
</li>
|
||||
<li><code>duration</code> — cuánto dura, en milisegundos.</li>
|
||||
<li>
|
||||
<code>contour</code> — hacia dónde va la altura mientras suena: plano, subiendo, bajando o en
|
||||
arco.
|
||||
</li>
|
||||
<li>
|
||||
<code>roughness</code> — la aspereza. A partir de 0,2 el sonido empieza a «raspar», que es lo
|
||||
que distingue un aviso de una confirmación.
|
||||
</li>
|
||||
<li><code>gain</code> — el volumen.</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section data-uix-section>
|
||||
<h2 data-uix-section-title>Por qué son tan distintos entre sí</h2>
|
||||
<p data-uix-section-desc>
|
||||
No es casualidad: hay una prueba automática que <strong>rechaza</strong> el catálogo si dos
|
||||
sonidos se parecen demasiado. Para convivir, dos entradas tienen que separarse en al menos
|
||||
<strong>dos</strong> de esos ejes con margen suficiente para oírlo — una quinta de altura, un tercio
|
||||
de brillo, la mitad otra vez de duración, otro contorno, el doble de volumen o 0,2 de aspereza.
|
||||
</p>
|
||||
<p data-uix-section-desc>
|
||||
Suena excesivo hasta que ocurre lo contrario. Un conjunto de sonidos que sólo se diferencian
|
||||
en el volumen no es un vocabulario: es el mismo sonido repetido, y quien usa la aplicación no
|
||||
distingue nada.
|
||||
</p>
|
||||
</section>
|
||||
</div>
|
||||
@ -0,0 +1,114 @@
|
||||
<script lang="ts">
|
||||
/**
|
||||
* `/uix/docs/sound/gestos` — why a continuous gesture sounds by repetition.
|
||||
*/
|
||||
import { getActiveUix } from '$active-uix';
|
||||
|
||||
const uix = getActiveUix();
|
||||
let stage = $state<HTMLElement | null>(null);
|
||||
let rate = $state(80);
|
||||
|
||||
/** Fire `step` N times at the chosen interval — the ratchet, on demand. */
|
||||
async function demo() {
|
||||
if (!stage) return;
|
||||
for (let i = 0; i < 12; i++) {
|
||||
void uix.events?.emit({ name: 'handle-drag', family: 'handle' as never, target: stage });
|
||||
await new Promise((r) => setTimeout(r, rate));
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div data-uix-canvas-inner>
|
||||
<div data-uix-eyebrow>Sema · el sonido</div>
|
||||
<h1 data-uix-page-title>Los gestos suenan como una rueda dentada.</h1>
|
||||
<p data-uix-page-lede>
|
||||
Arrastrar un deslizador o un panel no es un suceso: es <strong>muchos</strong>, uno detrás de
|
||||
otro mientras mueves el dedo. Eso cambia por completo cómo debe sonar, y la respuesta del
|
||||
sistema es la misma que la de una rueda física: un pequeño clic por paso.
|
||||
</p>
|
||||
|
||||
<div bind:this={stage} data-uix-sound-stage aria-hidden="true"></div>
|
||||
|
||||
<section data-uix-section>
|
||||
<h2 data-uix-section-title>El problema de un gesto</h2>
|
||||
<p data-uix-section-desc>
|
||||
Un botón suena una vez y ya está. Un arrastre, en cambio, dura: mientras mueves, el componente
|
||||
va contando lo que pasa, varias veces por segundo. Si cada uno de esos avisos sonara como un
|
||||
botón, tendrías una ametralladora en el oído.
|
||||
</p>
|
||||
<p data-uix-section-desc>
|
||||
La tentación es calcular: hacer que el tono suba con la posición y el volumen con la
|
||||
velocidad. Suena razonable escrito, pero produce un zumbido que se desliza y del que es
|
||||
difícil sacar información — y obliga a meter matemáticas dentro de un componente, que es justo
|
||||
lo que este sistema evita en todas partes.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section data-uix-section>
|
||||
<h2 data-uix-section-title>La respuesta: un clic diminuto, repetido</h2>
|
||||
<p data-uix-section-desc>
|
||||
El componente ya emite a su propio ritmo mientras arrastras. Basta con que cada emisión toque
|
||||
un sonido muy corto —<code>step</code>, 18 ms— y la información sale sola:
|
||||
<strong>cuanto más rápido mueves, más rápido suena</strong>. La dinámica del gesto es su
|
||||
ritmo, no su volumen.
|
||||
</p>
|
||||
<p data-uix-section-desc>
|
||||
Es exactamente lo que hace la rueda de un ratón o el selector de un móvil, y funciona por el
|
||||
mismo motivo: el oído es muy bueno midiendo cadencia.
|
||||
</p>
|
||||
|
||||
<div data-uix-controls>
|
||||
<label data-uix-control>
|
||||
<span data-uix-control-label>velocidad del gesto</span>
|
||||
<select bind:value={rate}>
|
||||
<option value={140}>lento — 140 ms entre pasos</option>
|
||||
<option value={80}>normal — 80 ms</option>
|
||||
<option value={40}>rápido — 40 ms</option>
|
||||
</select>
|
||||
</label>
|
||||
<button type="button" data-uix-sound-chip onclick={demo}>
|
||||
<span data-uix-sound-chip-name>simular arrastre</span>
|
||||
<span data-uix-sound-chip-play>▶</span>
|
||||
</button>
|
||||
</div>
|
||||
<p data-uix-section-desc>
|
||||
Prueba las tres velocidades seguidas: es el mismo sonido las tres veces, y aun así reconoces
|
||||
cuál es rápido.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section data-uix-section>
|
||||
<h2 data-uix-section-title>Una excepción que hay que conocer</h2>
|
||||
<p data-uix-section-desc>
|
||||
El sistema baja el volumen de un sonido que se repite mucho seguido: es una defensa contra la
|
||||
fatiga, para que veinte notificaciones iguales no te martilleen.
|
||||
</p>
|
||||
<p data-uix-section-desc>
|
||||
Con los gestos eso sería un desastre — la repetición <em>es</em> el mensaje, y esa defensa
|
||||
apagaría la rueda en el primer arrastre. Por eso la familia
|
||||
<code>handle</code> está <strong>exenta</strong>: sus emisiones se supone que son muchas y
|
||||
regulares, y no significan insistencia.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section data-uix-section>
|
||||
<h2 data-uix-section-title>Qué se gana y qué se pierde</h2>
|
||||
<ul data-uix-prose-list>
|
||||
<li>
|
||||
<strong>Se gana</strong> que un componente no calcule nada: nombra
|
||||
<code>step</code> y ya está, igual que cualquier otro sonido del sistema.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Se gana</strong> que funcione con ficheros: si tu pack pone un
|
||||
<code>.mp3</code> en <code>step</code>, la rueda sigue funcionando igual, cosa que con tono
|
||||
calculado era imposible.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Se pierde</strong> la relación entre posición y altura: antes, arrastrar hacia el
|
||||
final subía el tono. Ahora la velocidad se oye en el ritmo, pero
|
||||
<em>dónde estás</em> no se oye. Es una decisión consciente; si algún día hace falta, se recupera
|
||||
con pasos cuantizados y no con matemáticas dentro del componente.
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
</div>
|
||||
@ -0,0 +1,164 @@
|
||||
<script lang="ts">
|
||||
/**
|
||||
* `/uix/docs/sound/packs` — bringing your own sounds.
|
||||
*
|
||||
* Didactic order: what a pack IS, then swapping one, then adding a name
|
||||
* that does not exist, then the physics of samples. No history.
|
||||
*/
|
||||
import { SEMA_MAP } from '$uix/sema';
|
||||
const COUNT = Object.keys(SEMA_MAP.sounds).length;
|
||||
</script>
|
||||
|
||||
<div data-uix-canvas-inner>
|
||||
<div data-uix-eyebrow>Sema · el sonido</div>
|
||||
<h1 data-uix-page-title>Traer tus propios sonidos.</h1>
|
||||
<p data-uix-page-lede>
|
||||
Los componentes piden sonidos por su nombre: <code>tick</code>, <code>open</code>,
|
||||
<code>alert</code>. Lo que suena cada nombre lo decide una pieza aparte, un
|
||||
<strong>sound pack</strong>. Cambiando el pack cambia la voz de toda la aplicación — sin tocar
|
||||
un solo componente.
|
||||
</p>
|
||||
|
||||
<section data-uix-section>
|
||||
<h2 data-uix-section-title>La idea: nombres por un lado, sonidos por otro</h2>
|
||||
<p data-uix-section-desc>
|
||||
Piénsalo como una lista de palabras y un diccionario. La lista de palabras es fija: son los {COUNT}
|
||||
nombres que un componente puede pronunciar, y no se inventan sobre la marcha. El diccionario —el
|
||||
pack— dice a qué suena cada palabra, y ése sí lo puedes cambiar entero.
|
||||
</p>
|
||||
<pre data-uix-code><code
|
||||
>{`// Lo que dice un componente. Nunca cambia.
|
||||
sound: 'tick'
|
||||
|
||||
// Lo que dice el pack. Puedes reemplazarlo.
|
||||
tick: { pitch: 850, centroid: 3200, duration: 70, contour: 'flat', gain: 0.08 }
|
||||
tick: sample('/sonidos/mi-tick.mp3', reservaSintetica) // ← o esto`}</code
|
||||
></pre>
|
||||
<p data-uix-section-desc>
|
||||
Al componente le da <strong>igual</strong> cuál de las dos sea. Esa indiferencia es justo lo que
|
||||
hace posible cambiar la voz sin tocar nada más.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section data-uix-section>
|
||||
<h2 data-uix-section-title>El pack que viene de serie no trae ficheros</h2>
|
||||
<p data-uix-section-desc>
|
||||
Los {COUNT} sonidos por defecto están <strong>sintetizados</strong>: se generan en el
|
||||
navegador con osciladores. Eso significa que suenan sin descargar nada, sin esperas la primera
|
||||
vez, y sin que un despliegue mal copiado deje la aplicación muda.
|
||||
</p>
|
||||
<p data-uix-section-desc>
|
||||
Si prefieres ficheros, los pones tú. Los <code>.wav</code> que hay en el repositorio son sólo un
|
||||
ejemplo de cómo se hace.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section data-uix-section>
|
||||
<h2 data-uix-section-title>Usar ficheros de audio</h2>
|
||||
<pre data-uix-code><code
|
||||
>{`sample('/sonidos/tick.mp3', {
|
||||
// La reserva: lo que suena si el fichero no se puede cargar o decodificar.
|
||||
// Ponla siempre — sin ella, un 404 deja ese sonido mudo para siempre.
|
||||
pitch: 850, centroid: 3200, roughness: 0, attack: 2,
|
||||
decay: 60, duration: 70, contour: 'flat', gain: 0.08
|
||||
})`}</code
|
||||
></pre>
|
||||
<p data-uix-section-desc>
|
||||
Valen <strong>wav, mp3, ogg y aac</strong> — el navegador los decodifica todos. Puedes mezclar libremente:
|
||||
unos nombres sintetizados y otros con fichero, en el mismo pack.
|
||||
</p>
|
||||
<p data-uix-section-desc>
|
||||
<strong>Un límite que conviene conocer antes de diseñar.</strong> De un fichero sólo se puede
|
||||
controlar el volumen: no se le puede cambiar el tono ni la velocidad. Así que si quieres que
|
||||
un mismo suceso suene distinto según su carga —una confirmación normal frente a una peligrosa—
|
||||
necesitas <strong>un fichero por cada caso</strong>
|
||||
(<code>tick.mp3</code> y <code>tick.threat.mp3</code>), no uno solo modificado. Con sonidos
|
||||
sintetizados el problema no existe, porque cada versión se diseña entera.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section data-uix-section>
|
||||
<h2 data-uix-section-title>Añadir un sonido que no está en la lista</h2>
|
||||
<p data-uix-section-desc>
|
||||
La lista de nombres está cerrada para que nadie improvise, pero <strong
|
||||
>no está cerrada a que crezca</strong
|
||||
>. Si tu producto necesita un sonido propio, lo registras una vez y a partir de ahí se nombra
|
||||
como cualquier otro.
|
||||
</p>
|
||||
<pre data-uix-code><code
|
||||
>{`// 1 · Declara que el nombre existe (una vez, en tu producto)
|
||||
declare module '$uix/sema' {
|
||||
interface SemaSoundNames { laser: true }
|
||||
}
|
||||
|
||||
// 2 · Di a qué suena
|
||||
createActiveUix({
|
||||
events: { sounds: { laser: sample('/sonidos/laser.mp3', reserva) } }
|
||||
})
|
||||
|
||||
// 3 · Úsalo donde quieras
|
||||
{ selector: onProvider({ eventName: 'contact-activate' }), sound: 'laser' }`}</code
|
||||
></pre>
|
||||
<p data-uix-section-desc>
|
||||
Si además registras <code>'laser.threat'</code>, la regla normal lo encontrará sola cuando el
|
||||
suceso lleve ese intent. Y como el nombre está declarado en los tipos, una errata (<code
|
||||
>'lasser'</code
|
||||
>) no compila.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section data-uix-section>
|
||||
<h2 data-uix-section-title>Cambiar la voz en caliente</h2>
|
||||
<p data-uix-section-desc>
|
||||
Un pack no es sólo algo que se elige al arrancar: se puede cambiar mientras la aplicación
|
||||
corre, y deshacer.
|
||||
</p>
|
||||
<pre data-uix-code><code
|
||||
>{`// El sonido es un eje del tema, junto al color y los demás
|
||||
eidos.applyTheme({ color: '#3b5bdb', sound: { tick: { gain: 0.05 } } });
|
||||
eidos.clearTheme(); // vuelve a lo de origen
|
||||
|
||||
// O sólo el sonido
|
||||
uix.events.applySounds({ tick: { gain: 0.05 } });
|
||||
uix.events.clearMap();`}</code
|
||||
></pre>
|
||||
<p data-uix-section-desc>
|
||||
Fíjate en qué se puede cambiar y qué no: puedes cambiar <em>a qué suena</em> un nombre, pero
|
||||
no <em>qué nombres existen</em>. Un tema ajusta la voz; no puede inventar una palabra que
|
||||
ningún componente sabría pronunciar.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section data-uix-section>
|
||||
<h2 data-uix-section-title>Quién puede hacer qué</h2>
|
||||
<div data-uix-sound-table>
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>si eres…</th><th>puedes</th><th>cómo</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row"><span data-uix-sound-layer>el producto</span></th>
|
||||
<td>añadir nombres nuevos</td>
|
||||
<td>declararlo + registrar su sonido</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><span data-uix-sound-layer>un tema</span></th>
|
||||
<td>cambiar a qué suenan</td>
|
||||
<td><code>applySounds()</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><span data-uix-sound-layer>un componente</span></th>
|
||||
<td>elegir cuál usa</td>
|
||||
<td><code>sound: 'tick'</code> o <code>SILENT</code></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<p data-uix-section-desc>
|
||||
Y algo que <strong>nadie</strong> puede, en ninguna de las tres posiciones: escribir un parámetro
|
||||
suelto. No hay forma de decir «este botón, 200 Hz más agudo». Los números viven en el pack, y sólo
|
||||
ahí.
|
||||
</p>
|
||||
</section>
|
||||
</div>
|
||||
Loading…
Reference in new issue