Glassmorphism Generator — C++ 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 C++ implementation — the same logic the interactive tool runs, in a shareable, citable form.
// =============================================================================
// glassmorphism-generator.cpp — CosmoDev polyglot showcase port of the
// `glassmorphism-generator` tool
// -----------------------------------------------------------------------------
// Language : C++ (C++17, standard library only)
// Source: ported from src/lib/glassmorphism.ts (the canonical, live
// TypeScript lib); mirrors
// src/tool-sources/glassmorphism-generator/{python.py,rust.rs}
// License : display source — part of CosmoDev's polyglot tool pages
// (dev.cosmolabs.org). Shown verbatim alongside the JS/TS/Go/Rust/
// Python ports and the other language ports.
// -----------------------------------------------------------------------------
// Builds a frosted-glass CSS block from blur / opacity / tint / radius /
// border_opacity (+ optional saturation). Hex tints (#rgb / #rrggbb) are
// validated by hand with std::isxdigit (no <regex> — stdlib only); opacity
// is clamped to [0,1]; the alpha channel is rounded with
// floor(x*100 + 0.5)/100 — JS Math.round (half-up) semantics — and numbers
// are rendered via std::to_chars with no format argument, the shortest
// round-tripping decimal (10.0 -> "10", 0.3 -> "0.3"), which is exactly how
// JavaScript template literals render them. The output therefore matches the
// live TypeScript lib byte-for-byte.
// =============================================================================
#include <algorithm>
#include <cctype>
#include <charconv>
#include <cmath>
#include <iostream>
#include <optional>
#include <string>
#include <string_view>
#include <tuple>
namespace glassmorphism {
/// Configuration for one glassmorphism declaration block.
struct GlassConfig {
double blur = 0.0;
double opacity = 0.0;
std::string tint = "#ffffff";
double radius = 0.0;
double border_opacity = 0.0;
std::optional<double> saturation; // nullopt => 180.0 (lib default)
};
/// The rendered glassmorphism block plus its full CSS text.
struct GlassCss {
std::string background;
std::string backdrop_filter;
std::string webkit_backdrop_filter;
std::string border;
std::string border_radius;
std::string box_shadow;
std::string full_css;
};
/// Render a double the way JavaScript's template literal does — shortest
/// round-tripping decimal, no trailing ".0" on whole numbers. std::to_chars
/// with no format argument is precisely that: 10.0 -> "10", 0.3 -> "0.3".
inline std::string format_number(double x)
{
char buf[32];
auto res = std::to_chars(buf, buf + sizeof buf, x);
return std::string(buf, res.ptr);
}
/// True when every character of `s` is an ASCII hex digit (0-9, a-f, A-F).
inline bool is_hex_run(std::string_view s)
{
return !s.empty() && std::all_of(s.begin(), s.end(), [](char c) {
unsigned char u = static_cast<unsigned char>(c);
return std::isxdigit(u) != 0;
});
}
/// Parse a run of ASCII hex digits into its integer value (base 16).
inline int parse_hex(std::string_view s)
{
int v = 0;
for (char c : s) {
unsigned char u = static_cast<unsigned char>(c);
int d = std::isdigit(u) != 0 ? u - '0'
: std::tolower(u) - 'a' + 10;
v = v * 16 + d;
}
return v;
}
/// Parse #rgb or #rrggbb into (r, g, b); std::nullopt 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.
inline std::optional<std::tuple<int, int, int>> hex_to_rgb(std::string_view hex)
{
// Trim ASCII whitespace first — the set JS String.prototype.trim() strips.
constexpr const char* kWs = " \t\n\r\f\v";
if (hex.find_first_not_of(kWs) == std::string_view::npos) {
return std::nullopt;
}
auto s = hex.substr(hex.find_first_not_of(kWs),
hex.find_last_not_of(kWs) - hex.find_first_not_of(kWs) + 1);
if (!s.empty() && s.front() == '#') {
s.remove_prefix(1);
}
if (s.size() == 3 && is_hex_run(s)) {
// "a" -> 0xaa — each digit doubles into a pair, like CSS.
auto expand = [&](size_t i) { return parse_hex(s.substr(i, 1)) * 16 + parse_hex(s.substr(i, 1)); };
return std::tuple(expand(0), expand(1), expand(2));
}
if (s.size() == 6 && is_hex_run(s)) {
return std::tuple(parse_hex(s.substr(0, 2)), parse_hex(s.substr(2, 2)),
parse_hex(s.substr(4, 2)));
}
return std::nullopt;
}
/// Format rgba(), clamping + 2-decimal-rounding the alpha with JS Math.round
/// (half-up) semantics: floor(x*100 + 0.5)/100.
inline std::string rgba(int r, int g, int b, double a)
{
double c = std::min(std::max(a, 0.0), 1.0);
return "rgba(" + std::to_string(r) + ", " + std::to_string(g) + ", " +
std::to_string(b) + ", " +
format_number(std::floor(c * 100.0 + 0.5) / 100.0) + ")";
}
/// Build the full glassmorphism CSS for a config.
inline GlassCss build(const GlassConfig& cfg)
{
const double blur = std::max(cfg.blur, 0.0);
const double opacity = std::min(std::max(cfg.opacity, 0.0), 1.0);
const double radius = std::max(cfg.radius, 0.0);
const double border_opacity = std::min(std::max(cfg.border_opacity, 0.0), 1.0);
const double saturation = cfg.saturation.value_or(180.0);
auto [r, g, b] = hex_to_rgb(cfg.tint).value_or(std::make_tuple(255, 255, 255));
GlassCss css;
css.background = rgba(r, g, b, opacity);
css.backdrop_filter = "blur(" + format_number(blur) + "px) saturate(" +
format_number(saturation) + "%)";
css.border = "1px solid " + rgba(255, 255, 255, border_opacity);
css.border_radius = format_number(radius) + "px";
css.box_shadow = "0 8px 32px 0 rgba(31, 38, 135, 0.37)";
// Both prefixed and unprefixed backdrop-filter carry the same value.
css.webkit_backdrop_filter = css.backdrop_filter;
css.full_css = "background: " + css.background + ";\n"
"-webkit-backdrop-filter: " + css.backdrop_filter + ";\n"
"backdrop-filter: " + css.backdrop_filter + ";\n"
"border-radius: " + css.border_radius + ";\n"
"border: " + css.border + ";\n"
"box-shadow: " + css.box_shadow + ";";
return css;
}
} // namespace glassmorphism
int main()
{
glassmorphism::GlassConfig cfg;
cfg.blur = 10.0;
cfg.opacity = 0.3;
cfg.tint = "#ffffff";
cfg.radius = 12.0;
cfg.border_opacity = 0.2;
std::cout << glassmorphism::build(cfg).full_css << '\n';
return 0;
}
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 →