Glassmorphism Generator — Go 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 Go implementation — the same logic the interactive tool runs, in a shareable, citable form.
// Package glassmorphism is the Go twin of CosmoDev's src/lib/glassmorphism.ts
// (dual source: the web lib is TypeScript, the CLI lib is Go — kept in
// lock-step). It builds a frosted-glass CSS declaration block from
// blur/opacity/tint/radius/border-opacity. Pure + deterministic, never panics.
// The table-driven tests in glassmorphism-generator_test.go share vectors with
// src/lib/glassmorphism.test.ts so the two implementations are held to the
// same contract.
package glassmorphism
import (
"math"
"regexp"
"strconv"
"strings"
)
// GlassConfig mirrors the GlassConfig interface in src/lib/glassmorphism.ts.
// Numeric fields are float64 so the Go zero value (0) is exactly the TS
// nullish-coalescing default (blur ?? 0, opacity ?? 0, radius ?? 0,
// borderOpacity ?? 0). Saturation is *int so the zero value (nil) means the
// TS default of 180 (saturation ?? 180) while an explicit pointer — including
// to 0 — is used verbatim. An empty or unparseable Tint falls back to white
// (#ffffff), matching the TS nullish fallback.
type GlassConfig struct {
Blur float64
Opacity float64
Tint string
Radius float64
BorderOpacity float64
Saturation *int // nil → 180 (default); non-nil used verbatim
}
// RGB is the {r, g, b} triple — the Go form of hexToRgb's non-null return.
type RGB struct {
R, G, B int
}
// GlassCss mirrors the GlassCss interface in src/lib/glassmorphism.ts.
type GlassCss struct {
Background string
BackdropFilter string
WebkitBackdropFilter string
Border string
BorderRadius string
BoxShadow string
FullCss string
}
var (
hex3 = regexp.MustCompile(`^[0-9a-fA-F]{3}$`)
hex6 = regexp.MustCompile(`^[0-9a-fA-F]{6}$`)
)
// HexToRgb is the Go twin of hexToRgb() in src/lib/glassmorphism.ts. It parses
// a 3- or 6-digit hex color (with or without a leading '#', surrounding
// whitespace trimmed) into an RGB triple. The bool is false for any input that
// is not a valid 3/6-digit hex — the Go equivalent of the TS null return.
func HexToRgb(hex string) (RGB, bool) {
h := strings.TrimPrefix(strings.TrimSpace(hex), "#")
if hex3.MatchString(h) {
r, _ := strconv.ParseInt(string([]byte{h[0], h[0]}), 16, 0)
g, _ := strconv.ParseInt(string([]byte{h[1], h[1]}), 16, 0)
b, _ := strconv.ParseInt(string([]byte{h[2], h[2]}), 16, 0)
return RGB{int(r), int(g), int(b)}, true
}
if hex6.MatchString(h) {
r, _ := strconv.ParseInt(h[0:2], 16, 0)
g, _ := strconv.ParseInt(h[2:4], 16, 0)
b, _ := strconv.ParseInt(h[4:6], 16, 0)
return RGB{int(r), int(g), int(b)}, true
}
return RGB{}, false
}
// Rgba is the Go twin of rgba() in src/lib/glassmorphism.ts. It formats an
// rgba() color string, clamping alpha to [0, 1] and rounding both the channels
// (to integers) and the alpha (to two decimals) like the TS lib.
func Rgba(r, g, b, a float64) string {
clamped := math.Max(0, math.Min(1, a))
alpha := math.Round(clamped*100) / 100
return "rgba(" + ftoi(r) + ", " + ftoi(g) + ", " + ftoi(b) + ", " + fnum(alpha) + ")"
}
// BuildGlassmorphism is the Go twin of buildGlassmorphism() in
// src/lib/glassmorphism.ts. It builds a full frosted-glass CSS declaration
// block from the config, applying the same clamps and defaults as the TS lib.
func BuildGlassmorphism(config GlassConfig) GlassCss {
blur := math.Max(0, config.Blur)
opacity := clamp01(config.Opacity)
radius := math.Max(0, config.Radius)
borderOpacity := clamp01(config.BorderOpacity)
saturation := 180
if config.Saturation != nil {
saturation = *config.Saturation
}
rgb, ok := HexToRgb(config.Tint)
if !ok {
rgb = RGB{255, 255, 255}
}
background := Rgba(float64(rgb.R), float64(rgb.G), float64(rgb.B), opacity)
backdropFilter := "blur(" + fnum(blur) + "px) saturate(" + strconv.Itoa(saturation) + "%)"
border := "1px solid rgba(255, 255, 255, " + fnum(math.Round(borderOpacity*100)/100) + ")"
borderRadius := fnum(radius) + "px"
boxShadow := "0 8px 32px 0 rgba(31, 38, 135, 0.37)"
fullCss := strings.Join([]string{
"background: " + background + ";",
"-webkit-backdrop-filter: " + backdropFilter + ";",
"backdrop-filter: " + backdropFilter + ";",
"border-radius: " + borderRadius + ";",
"border: " + border + ";",
"box-shadow: " + boxShadow + ";",
}, "\n")
return GlassCss{
Background: background,
BackdropFilter: backdropFilter,
WebkitBackdropFilter: backdropFilter,
Border: border,
BorderRadius: borderRadius,
BoxShadow: boxShadow,
FullCss: fullCss,
}
}
// clamp01 clamps v to [0, 1], mirroring Math.max(0, Math.min(1, v)).
func clamp01(v float64) float64 { return math.Max(0, math.Min(1, v)) }
// ftoi formats a channel value as an integer (Math.round-equivalent).
func ftoi(v float64) string {
return strconv.FormatFloat(math.Round(v), 'f', -1, 64)
}
// fnum formats a number the way a JS template literal coerces it — the
// shortest decimal that round-trips ("0.5", "0.57", "1", "0", "12", "10").
func fnum(v float64) string {
return strconv.FormatFloat(v, 'f', -1, 64)
}
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 →