Apply paint opacity to CSS gradient stops in code export (#1750)

Found while testing crates/engine/src/dev/codegen/css.rs:121 (css_decls, the PaintKind::Gradient arm calling css_gradient at :255)

Co-authored-by: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
NetterSilver
2026-10-31 10:37:18 -04:00
committed by GitHub
co-authored by Claude Haiku 5.5
parent 45e5a25370
commit 9a7e5d1a16
2 changed files with 20 additions and 3 deletions
+12
View File
@@ -494,6 +494,18 @@ mod tests {
f
}
#[test]
fn css_gradient_folds_in_paint_opacity() {
let mut s = Session::new();
let f = id_of(&s.execute("frame.create", &json!({"x": 0, "y": 0, "width": 200, "height": 100})).unwrap()["id"]).unwrap();
let mut p = figcraft_color::Paint::gradient(figcraft_color::Gradient::default_for(figcraft_color::GradientKind::Linear, Color::BLACK));
p.opacity = 0.5;
s.doc_mut().unwrap().get_mut(f).unwrap().fills = vec![p];
let css = code_for(s.doc().unwrap(), f, CodeLang::Css);
assert!(css.contains("rgba(0, 0, 0, 0.50) 0%"), "{css}");
assert!(!css.contains("#000000 0%"), "{css}");
}
#[test]
fn swiftui_and_compose_for_an_auto_layout_card() {
let mut s = Session::new();
+8 -3
View File
@@ -120,7 +120,7 @@ pub(crate) fn css_decls(doc: &Document, n: &Node, t: &mut Tokens, hug: (bool, bo
// A variable binds the first paint's colour.
put(key, if i == 0 { tok(doc, n, &["fill"], c, t) } else { c });
}
PaintKind::Gradient(g) => put("background", css_gradient(g, n.width, n.height)),
PaintKind::Gradient(g) => put("background", css_gradient(g, n.width, n.height, p.opacity)),
PaintKind::Image(_) => put("background", "url(image.png) center / cover".into()),
PaintKind::Pattern(_) => put("background", "url(pattern.png) repeat".into()),
}
@@ -307,8 +307,13 @@ fn decoration_decls(s: &figcraft_doc::TextStyle, put: &mut impl FnMut(&str, Stri
/// A gradient fill on a `w`×`h` box as a CSS background: linear along its handles' direction
/// (CSS angles: 0deg up, 90deg right), radial with its handles' radii, angular as a conic
/// gradient from its start direction.
fn css_gradient(g: &figcraft_color::Gradient, w: f64, h: f64) -> String {
let stops = g.sorted_stops().iter().map(|s| format!("{} {}%", s.color.to_css(), (s.position * 100.0).round())).collect::<Vec<_>>().join(", ");
fn css_gradient(g: &figcraft_color::Gradient, w: f64, h: f64, opacity: f32) -> String {
let stops = g
.sorted_stops()
.iter()
.map(|s| format!("{} {}%", s.color.with_alpha(s.color.a * opacity).to_css(), (s.position * 100.0).round()))
.collect::<Vec<_>>()
.join(", ");
let (dx, dy) = ((g.to.0 - g.from.0) * w, (g.to.1 - g.from.1) * h);
let angle = if dx == 0.0 && dy == 0.0 { 180.0 } else { dx.atan2(-dy).to_degrees().rem_euclid(360.0) };
let pct = |v: f64| format!("{}%", num(v * 100.0));