86fb6ae20b
El render agnóstico ya no es un esqueleto — porta al WASM la mayoría de los detalles visuales que tenía solo el canvas gpui nativo: - palette.rs: Palette dark/light replicando AstroPalette del theme nativo, pero en Rgba (no Hsla de gpui). Métodos planet/aspect/sign para resolver color por id simbólico, + house_ring con hue-shift. - CompositionOpts extendido: palette, dial_3d, draw_ascensional_cross, show_coord_labels, show_minor_aspects. Defaults razonables. - compose_wheel ahora dibuja: background panel, dial 3D bevel (4 strokes concéntricos con alpha decreciente), subdivisiones cada 10° con sign boundaries reforzados, signos con color elemental, casas topocéntricas + geocéntricas en sus rings canónicos, cuerpos con spread anti-solapamiento + clusters + disco coloreado por planeta, coord labels "DD°MM'♈" en natal, aspectos con width inversa al orbe + filtrado opcional de minors, cruz ascensional dashed + pills ASC/MC/DESC/IC. - cosmobiologia-web: nuevo render_model_to_svg_themed(dark: bool) para que el cliente JS elija palette según preferencia del UA. Tests del módulo math siguen verdes (10/10). Smoke test del server: /api/sky.svg ahora emite 22 circles, 77 lines, 52 texts con paleta real (vs ~6 circles, 24 lines, 36 texts del esqueleto previo). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
100 lines
3.5 KiB
Rust
100 lines
3.5 KiB
Rust
//! `cosmobiologia-web` — cdylib WASM que renderiza la rueda
|
|
//! astrológica desde el browser, sin round-trip al server por cada
|
|
//! interacción.
|
|
//!
|
|
//! ## Flujo
|
|
//!
|
|
//! 1. El cliente JS hace `await fetch('/api/sky')` o
|
|
//! `/api/charts/:id/render?...` y recibe un `RenderModel` JSON.
|
|
//! 2. JS llama `render_model_to_svg(json)` (exportado desde WASM) que
|
|
//! deserializa + corre `cosmobiologia_render::compose_wheel` +
|
|
//! serializa SVG.
|
|
//! 3. JS hace `wheelContainer.innerHTML = svg`.
|
|
//!
|
|
//! ## Build
|
|
//!
|
|
//! ```bash
|
|
//! cargo install wasm-pack # una vez
|
|
//! cd crates/modules/cosmobiologia/cosmobiologia-web
|
|
//! wasm-pack build --target web --out-dir ../../../../apps/cosmobiologia-server/static/wasm
|
|
//! ```
|
|
//!
|
|
//! Esto produce un módulo ES6 (`cosmobiologia_web.js` +
|
|
//! `cosmobiologia_web_bg.wasm`) que el `index.html` del server
|
|
//! importa con `import init, { render_model_to_svg } from
|
|
//! '/static/wasm/cosmobiologia_web.js';`.
|
|
|
|
#![forbid(unsafe_code)]
|
|
#![warn(rust_2018_idioms)]
|
|
|
|
// La API pública SOLO se expone con `wasm-bindgen` en target
|
|
// wasm32. En nativo (rlib) el crate compila para validar la
|
|
// signature pero no exporta nada — los tests del render ya viven
|
|
// en `cosmobiologia-render::math`.
|
|
#[cfg(target_arch = "wasm32")]
|
|
mod wasm {
|
|
use cosmobiologia_render::{
|
|
compose_wheel, draw_commands_to_svg, CompositionOpts, Palette, RenderModel,
|
|
};
|
|
use wasm_bindgen::prelude::*;
|
|
|
|
/// Renderea un `RenderModel` (JSON string) como SVG. El JSON sale
|
|
/// de `/api/sky` o `/api/charts/:id/render` del server.
|
|
///
|
|
/// `size` es el lado del cuadrado contenedor en px (default 600).
|
|
/// `rot_offset_deg` permite rotar la vista (jog-dial / preview).
|
|
#[wasm_bindgen]
|
|
pub fn render_model_to_svg(
|
|
json: &str,
|
|
size: f32,
|
|
rot_offset_deg: f32,
|
|
) -> Result<String, JsValue> {
|
|
render_with_opts(json, size, rot_offset_deg, true)
|
|
}
|
|
|
|
/// Variante con palette explícita (dark = `true` por default, light
|
|
/// = `false`). El JS pasa el modo según preferencia/tema del UA.
|
|
#[wasm_bindgen]
|
|
pub fn render_model_to_svg_themed(
|
|
json: &str,
|
|
size: f32,
|
|
rot_offset_deg: f32,
|
|
dark: bool,
|
|
) -> Result<String, JsValue> {
|
|
render_with_opts(json, size, rot_offset_deg, dark)
|
|
}
|
|
|
|
fn render_with_opts(
|
|
json: &str,
|
|
size: f32,
|
|
rot_offset_deg: f32,
|
|
dark: bool,
|
|
) -> Result<String, JsValue> {
|
|
let model: RenderModel = serde_json::from_str(json)
|
|
.map_err(|e| JsValue::from_str(&format!("parse RenderModel: {}", e)))?;
|
|
let opts = CompositionOpts {
|
|
size: if size > 0.0 { size } else { 600.0 },
|
|
rot_offset_deg,
|
|
palette: if dark { Palette::dark() } else { Palette::light() },
|
|
..Default::default()
|
|
};
|
|
let cmds = compose_wheel(&model, &opts);
|
|
Ok(draw_commands_to_svg(&cmds, opts.size))
|
|
}
|
|
|
|
/// Hook de inicialización opcional — wasm_pack lo invoca al
|
|
/// cargar el módulo. Útil para instalar un panic hook hacia
|
|
/// `console.error`. Por ahora no-op.
|
|
#[wasm_bindgen(start)]
|
|
pub fn main_js() {}
|
|
}
|
|
|
|
#[cfg(not(target_arch = "wasm32"))]
|
|
pub fn _native_marker() {
|
|
// Sin target wasm32, el crate solo expone el render como
|
|
// transitivo. Esta función vive para que `cargo check -p
|
|
// cosmobiologia-web` valide la compilación nativa sin
|
|
// wasm-bindgen — útil en CI y en desarrollo desktop.
|
|
let _ = std::any::type_name::<cosmobiologia_render::RenderModel>();
|
|
}
|