5e0fcae4b4
Renderer (gioser-canvas-web): - Spring shake (SpringDamper1, 7.5 Hz / ζ=0.13) aplicado como rotación Z en el MVP. impulse_click() inyecta velocidad alternada → vibración fuerte con ~5 ciclos decayendo en ~0.8s. - release_tilt() pone target del tilt en (0,0) → la chacana cae al frente con el rebote natural del spring sub-crítico. - world_scale_for_aspect(): en portrait (aspect<1) escala baja proporcional para que el aro exterior no se corte por los lados. Base 1.05, piso 0.45. - click_radius_css_px() expone radio del aro en CSS-pixels desde el centro del canvas; la app lo usa para hit-test del impulso. - set_client_size() separa CSS-pixels de device-pixels (DPR). - tilt_degrees() ahora retorna (pitch, yaw, roll) — el brand replica los 3. - 4 nuevos uniforms u_aire/fuego/tierra/agua_color para el shader de partículas. Shader (gioser-shaders/FS_CHACANA): - Función element_particles(tip, outward, color, kind) → 4 partículas por cardinal con personalidad: AIRE drift+sway, FUEGO rise+flicker (siempre hacia +Y), TIERRA cae, AGUA ondula descendiendo. Gauss + envelope sinusoidal en la vida. ~16 partículas total, costo modesto. App (gioser-web): - pointerdown en canvas → si distancia al centro < click_radius_css_px → impulse_click(). Touch y mouse vienen unificados por PointerEvent. - mouseleave en canvas → release_tilt(). Sin set_target, el spring se quedaría en la última posición — ahora vuelve al frente con rebote. - position_tips ahora clampea raw_x/raw_y a [margin, viewport - taskbar - margin] en CSS pixels. Los botones NUNCA salen del canvas ni cubren la taskbar incluso en aspect extremos o tilt máximo. - AppState + TaskbarState (RefCell): trackea drawers abiertos + activo. open_tab/switch_tab/close_tab/home aplican mutación + sync(). - sync() rebuild de taskbar-list innerHTML por cada cambio de estado, más swap de body classes + drawer .open classes. - Click delegation en taskbar-list — un listener para todas las cajitas. - Botón home con data-home en la barra (svg de casa) cierra todo y limpia el taskbar. - Escape también cierra el drawer activo. - update_tilt_css ahora setea --tilt-z también — brand title roll visible en el shake. CSS: - .drawer bottom: 52px (reserva taskbar). - .taskbar full ancho fixed bottom, glass + gold border, scrollable horiz para muchas cajitas. - .taskbar-item con --task-color por elemento (aire/fuego/tierra/agua), .active glow del color + inset border bottom. - .taskbar-home con svg de casa dorado, hover glow. - Responsive: taskbar 46px en mobile + ajustes. - .brand transform agrega rotateZ(--tilt-z) para que el título vibre con la chacana en click impulses. Workspace verde + 18 tests. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
133 lines
6.7 KiB
HTML
133 lines
6.7 KiB
HTML
<!doctype html>
|
||
<html lang="es">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||
<title>GioSer · En el centro, el ser</title>
|
||
<link rel="stylesheet" href="./styles.css">
|
||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Cinzel:wght@500;700&family=Inter:wght@300;500;600&family=JetBrains+Mono:wght@400;600&display=swap">
|
||
</head>
|
||
<body>
|
||
<canvas id="gioser-canvas" aria-hidden="true"></canvas>
|
||
|
||
<header id="brand" class="brand">
|
||
<h1 class="brand-title">Gio<span class="brand-dot">·</span>Ser</h1>
|
||
</header>
|
||
|
||
<main id="tips" aria-label="Cuatro elementos">
|
||
<a id="tip-aire" class="tip tip-aire" href="#aire" data-md="./md/aire.md" aria-label="Aire — Software e IA">
|
||
<svg viewBox="0 0 48 48" class="tip-glyph" aria-hidden="true">
|
||
<path d="M6 18 q 9 -12 18 0 t 18 0" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/>
|
||
<path d="M6 28 q 9 -12 18 0 t 18 0" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" opacity="0.75"/>
|
||
<path d="M6 38 q 9 -12 18 0 t 18 0" fill="none" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" opacity="0.45"/>
|
||
</svg>
|
||
<span class="tip-label">AIRE</span>
|
||
<span class="tip-sub">Software · IA</span>
|
||
</a>
|
||
|
||
<a id="tip-fuego" class="tip tip-fuego" href="#fuego" data-md="./md/fuego.md" aria-label="Fuego — Inspiración">
|
||
<svg viewBox="0 0 48 48" class="tip-glyph" aria-hidden="true">
|
||
<path d="M24 4 q -12 12 -6 24 q 3 -6 6 -6 q 1 10 6 12 q 10 -10 0 -22 q -4 6 -6 -8 z"
|
||
fill="none" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/>
|
||
<circle cx="24" cy="28" r="3" fill="currentColor" opacity="0.5"/>
|
||
</svg>
|
||
<span class="tip-label">FUEGO</span>
|
||
<span class="tip-sub">Inspiración</span>
|
||
</a>
|
||
|
||
<a id="tip-tierra" class="tip tip-tierra" href="#tierra" data-md="./md/tierra.md" aria-label="Tierra — Cuerpo">
|
||
<svg viewBox="0 0 48 48" class="tip-glyph" aria-hidden="true">
|
||
<path d="M4 36 l 12 -16 l 8 9 l 6 -12 l 14 19 z"
|
||
fill="none" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/>
|
||
<path d="M24 36 v 8 M19 38 l -4 5 M29 38 l 4 5 M24 44 v 2"
|
||
fill="none" stroke="currentColor" stroke-width="1.3" opacity="0.7"/>
|
||
</svg>
|
||
<span class="tip-label">TIERRA</span>
|
||
<span class="tip-sub">Cuerpo</span>
|
||
</a>
|
||
|
||
<a id="tip-agua" class="tip tip-agua" href="#agua" data-md="./md/agua.md" aria-label="Agua — Espiritualidad aplicada">
|
||
<svg viewBox="0 0 48 48" class="tip-glyph" aria-hidden="true">
|
||
<path d="M6 22 q 6 -10 12 0 t 12 0 t 12 0" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/>
|
||
<path d="M6 30 q 6 -10 12 0 t 12 0 t 12 0" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" opacity="0.75"/>
|
||
<path d="M6 38 q 6 -10 12 0 t 12 0 t 12 0" fill="none" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" opacity="0.5"/>
|
||
</svg>
|
||
<span class="tip-label">AGUA</span>
|
||
<span class="tip-sub">Espiritualidad</span>
|
||
</a>
|
||
</main>
|
||
|
||
<!-- DRAWERS: uno por elemento. Cada uno crece desde la posición del tip
|
||
clickeado (origin set via CSS vars desde WASM) hasta fullscreen. -->
|
||
<aside id="drawer-aire" class="drawer drawer-aire" data-element="aire" aria-hidden="true">
|
||
<button class="drawer-close" data-close-drawer aria-label="Cerrar Aire">×</button>
|
||
<div class="drawer-ambience" aria-hidden="true"></div>
|
||
<header class="drawer-head">
|
||
<span class="drawer-mark">aire</span>
|
||
<h2 class="drawer-title">Aire</h2>
|
||
<span class="drawer-tag">Software · IA · Aspiración</span>
|
||
</header>
|
||
<section class="drawer-content" id="drawer-aire-content"></section>
|
||
</aside>
|
||
|
||
<aside id="drawer-fuego" class="drawer drawer-fuego" data-element="fuego" aria-hidden="true">
|
||
<button class="drawer-close" data-close-drawer aria-label="Cerrar Fuego">×</button>
|
||
<div class="drawer-ambience" aria-hidden="true"></div>
|
||
<header class="drawer-head">
|
||
<span class="drawer-mark">fuego</span>
|
||
<h2 class="drawer-title">Fuego</h2>
|
||
<span class="drawer-tag">Inspiración</span>
|
||
</header>
|
||
<section class="drawer-content" id="drawer-fuego-content"></section>
|
||
</aside>
|
||
|
||
<aside id="drawer-tierra" class="drawer drawer-tierra" data-element="tierra" aria-hidden="true">
|
||
<button class="drawer-close" data-close-drawer aria-label="Cerrar Tierra">×</button>
|
||
<div class="drawer-ambience" aria-hidden="true"></div>
|
||
<header class="drawer-head">
|
||
<span class="drawer-mark">tierra</span>
|
||
<h2 class="drawer-title">Tierra</h2>
|
||
<span class="drawer-tag">Cuerpo</span>
|
||
</header>
|
||
<section class="drawer-content" id="drawer-tierra-content"></section>
|
||
</aside>
|
||
|
||
<aside id="drawer-agua" class="drawer drawer-agua" data-element="agua" aria-hidden="true">
|
||
<button class="drawer-close" data-close-drawer aria-label="Cerrar Agua">×</button>
|
||
<div class="drawer-ambience" aria-hidden="true"></div>
|
||
<header class="drawer-head">
|
||
<span class="drawer-mark">agua</span>
|
||
<h2 class="drawer-title">Agua</h2>
|
||
<span class="drawer-tag">Espiritualidad aplicada</span>
|
||
</header>
|
||
<section class="drawer-content" id="drawer-agua-content"></section>
|
||
</aside>
|
||
|
||
<!-- TASKBAR estilo Windows: home a la izquierda + cajitas dinámicas
|
||
de las vistas MD abiertas. Sincronizada por WASM. -->
|
||
<nav class="taskbar" aria-label="Vistas abiertas">
|
||
<button class="taskbar-home" data-home aria-label="Volver al home" type="button">
|
||
<svg viewBox="0 0 24 24" class="taskbar-home-glyph" aria-hidden="true">
|
||
<path d="M3 12 L12 3 L21 12" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linejoin="round" stroke-linecap="round"/>
|
||
<path d="M5 11 V20 H10 V14 H14 V20 H19 V11" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linejoin="round"/>
|
||
<circle cx="12" cy="17" r="0.8" fill="currentColor"/>
|
||
</svg>
|
||
</button>
|
||
<span class="taskbar-divider" aria-hidden="true"></span>
|
||
<ul class="taskbar-list" id="taskbar-list" role="presentation"></ul>
|
||
</nav>
|
||
|
||
<script type="module">
|
||
import init from "./pkg/gioser_web.js";
|
||
init().catch(err => {
|
||
console.error(err);
|
||
document.body.insertAdjacentHTML("beforeend",
|
||
'<pre style="color:#f59056;position:fixed;left:1rem;bottom:1rem;max-width:90vw;white-space:pre-wrap;font-family:monospace;z-index:9999">' +
|
||
String(err) + '</pre>');
|
||
});
|
||
</script>
|
||
</body>
|
||
</html>
|