# Project 1: crystal visualizer in WASM [back to index](https://hackmd.io/hz9-b8TdTNSY4sLyKBuVCQ) - project repo: https://github.com/rs4rse/vizcrystal note: The content below was generated from chatgpt-5 by just providing the goal (crystal visualizer) and tech-stacks (bevy, cif, wasm), we do vibe coding from scratch. The proposal may need to be adapted along the vibe coding. (like `cifparser` which not existed but David has some prototype crate where we can use the modules here. Otherwise see project3 and go with xyz files.) ## Core Goal Build a web-based crystal structure visualizer in **Rust** using **Bevy** compiled to **WebAssembly (WASM)**. The app should load a valid **CIF (Crystallographic Information File)** and render the 3D crystal structure, supporting mouse-based interaction (zoom, rotate, pan). Publish to npm. ## tech stacks - wasm - rust - use typescript where if possible since in rust we deal with types anyway. - wasm-bindgen https://wasm-bindgen.github.io/ - wasmbuild deno glue code https://github.com/denoland/wasmbuild --- ## **Phase 1: Setup** * Set up a **Bevy project** targeting WASM. * Use `wasm-bindgen` or `wasm-pack` to compile. * Serve via `trunk` or `wasm-server-runner`. * Confirm that a simple rotating cube renders correctly in browser. --- ## **Phase 2: CIF Parsing** * Add a Rust crate or implement a small parser for CIF files. * Option A: Use [cifparser](https://crates.io/crates/cifparser). * Option B: Write a minimal parser for atomic positions, cell dimensions, and symmetry. * Extract: * **Lattice vectors** * **Atom positions** and **species** * Store data in a struct, e.g.: ```rust struct Crystal { lattice: [[f32; 3]; 3], atoms: Vec<Atom>, } struct Atom { element: String, position: [f32; 3], } ``` --- ## **Phase 3: Visualization in Bevy** * Render atoms as spheres (or colored meshes). * Render bonds as cylinders (optional at first). * Color atoms by element type (basic mapping: H=white, C=black, O=red, etc.). * Add unit cell edges (wireframe cube). --- ## **Phase 4: Camera & Interaction** * Add **mouse controls**: * **Rotate**: Click & drag. * **Zoom**: Scroll wheel. * **Pan**: Right-click drag or middle button. * Use `bevy_mod_picking` or implement a custom orbital camera system. --- ## **Phase 5: Web Integration** * Create an **HTML file** with a file upload button (`<input type="file">`). * Use **JavaScript + wasm-bindgen** to pass uploaded CIF file content to Rust. * When a file is loaded: * Parse CIF → Render in scene. * Ensure browser app works offline (bundle with Trunk). --- ## **Phase 6: Extensions (Optional / Bonus)** * **Multiple CIFs**: Dropdown to switch between different crystals. * **Supercell builder**: Duplicate unit cell `n x n x n`. * **Labels**: Show element symbols next to atoms. * **Bond detection**: Compute bonds dynamically using distance cutoff. --- ## **Deliverables** 1. WASM + Bevy app running in browser. 2. Working CIF file parser. 3. Interactive crystal visualization (zoom/rotate). 4. Extended functionality (optional): * Bonds, labels, supercell. --- ## **Tech Hints** * Bevy WASM: ```bash cargo install trunk trunk serve --open ``` * For parsing files from HTML: * Use `web-sys` or `gloo-file` to read uploaded files. * For interactivity: * Bevy’s `Transform` + mouse input events. * For bonds: * Distance cutoff \~1.2 × (r1 + r2) where r = covalent radii.