Glassmorphism Generator — Rust source
Create frosted-glass CSS - backdrop-blur, translucent background, subtle border, and soft shadow - with a copy-ready snippet and live preview.
This is the Rust implementation — the same logic the interactive tool runs, in a shareable, citable form.
// Pure glassmorphism CSS builder — deterministic, no DOM.
//
// Language: Rust
// CosmoDev polyglot showcase port of the `glassmorphism-generator` tool.
// Ported from src/lib/glassmorphism.ts — display source, part of CosmoDev's
// polyglot tool pages.
//
// Builds a frosted-glass CSS block from blur / opacity / tint / radius /
// border_opacity (+ optional saturation). Hex tints (#rgb / #rrggbb) are
// validated by hand with is_ascii_hexdigit (no regex crate — stdlib only);
// opacity is clamped to [0,1]; the alpha channel is rounded with
// (x*100).round()/100 and rendered via {} (shortest repr, matching JS
// template literals), so the output matches the live TypeScript lib
// byte-for-byte. Pure stdlib.
//
// Parity note: f64::round() rounds half away from zero — identical to JS
// Math.round for the non-negative alphas produced here (alpha is clamped
// to [0,1] before rounding).
/// Configuration for one glassmorphism declaration block.
pub struct GlassConfig {
pub blur: f64,
pub opacity: f64,
pub tint: String,
pub radius: f64,
pub border_opacity: f64,
pub saturation: Option<f64>, // None => 180.0 (lib default)
}
/// The rendered glassmorphism block plus its full CSS text.
pub struct GlassCss {
pub background: String,
pub backdrop_filter: String,
pub webkit_backdrop_filter: String,
pub border: String,
pub border_radius: String,
pub box_shadow: String,
pub full_css: String,
}
/// True when every byte is an ASCII hex digit (0-9, a-f, A-F).
fn is_hex(s: &str) -> bool {
!s.is_empty() && s.bytes().all(|c| c.is_ascii_hexdigit())
}
/// Parse 1-2 hex digits into an integer (base 16); 0 on failure.
fn parse_hex(s: &str) -> i64 {
i64::from_str_radix(s, 16).unwrap_or(0)
}
/// Parse #rgb or #rrggbb into (r, g, b); None on a bad color.
/// A 3-char hex expands each digit (e.g. "abc" -> "aabbcc"), like CSS.
/// Exactly one leading '#' is stripped, matching the lib's /^#/ replace.
pub fn hex_to_rgb(hex: &str) -> Option<(i64, i64, i64)> {
let h = hex.trim();
let h = h.strip_prefix('#').unwrap_or(h);
if h.len() == 3 && is_hex(h) {
let expand = |i: usize| parse_hex(&h[i..i + 1].repeat(2));
Some((expand(0), expand(1), expand(2)))
} else if h.len() == 6 && is_hex(h) {
Some((parse_hex(&h[0..2]), parse_hex(&h[2..4]), parse_hex(&h[4..6])))
} else {
None
}
}
/// Format rgba(), clamping + 2-decimal-rounding the alpha.
pub fn rgba(r: i64, g: i64, b: i64, a: f64) -> String {
let c = a.max(0.0).min(1.0);
format!("rgba({}, {}, {}, {})", r, g, b, (c * 100.0).round() / 100.0)
}
/// Build the full glassmorphism CSS for a config.
pub fn build_glassmorphism(cfg: &GlassConfig) -> GlassCss {
let blur = cfg.blur.max(0.0);
let opacity = cfg.opacity.max(0.0).min(1.0);
let radius = cfg.radius.max(0.0);
let border_opacity = cfg.border_opacity.max(0.0).min(1.0);
let saturation = cfg.saturation.unwrap_or(180.0);
let (r, g, b) = hex_to_rgb(&cfg.tint).unwrap_or((255, 255, 255));
let background = rgba(r, g, b, opacity);
let backdrop_filter = format!("blur({}px) saturate({}%)", blur, saturation);
let border = format!("1px solid {}", rgba(255, 255, 255, border_opacity));
let border_radius = format!("{}px", radius);
let box_shadow = "0 8px 32px 0 rgba(31, 38, 135, 0.37)".to_string();
let full_css = format!(
"background: {};\n\
-webkit-backdrop-filter: {};\n\
backdrop-filter: {};\n\
border-radius: {};\n\
border: {};\n\
box-shadow: {};",
background, backdrop_filter, backdrop_filter, border_radius, border, box_shadow
);
GlassCss {
background,
backdrop_filter: backdrop_filter.clone(),
webkit_backdrop_filter: backdrop_filter,
border,
border_radius,
box_shadow,
full_css,
}
}
fn main() {
let cfg = GlassConfig {
blur: 10.0,
opacity: 0.3,
tint: "#ffffff".to_string(),
radius: 12.0,
border_opacity: 0.2,
saturation: None,
};
println!("{}", build_glassmorphism(&cfg).full_css);
}
Also available in 13 other languages
Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →