Timeline: keyframes without a dark outline (#284)
Each half of a keyframe glyph had a 1 px near-black border, so keys that overlap read as a tangle of borders. Keys are now flat, as in After Effects: each half is filled and edged in the key's own colour (the hairline closes the seam between the halves), so overlapping keys read as one shape. The Light theme's keyframe grey is darker so unselected keys still stand out on its light time graph without the border. Test: keyframes_are_drawn_without_a_dark_outline (icons). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
59c55e8a26
commit
04ccf6f906
|
|
@ -641,13 +641,24 @@ pub fn keyframe(
|
|||
left: effectcraft_engine::keyframe::KeyHalf,
|
||||
right: effectcraft_engine::keyframe::KeyHalf,
|
||||
fill: Color32,
|
||||
outline: Color32,
|
||||
) {
|
||||
painter.extend(keyframe_shapes(center, size, left, right, fill));
|
||||
}
|
||||
|
||||
/// The halves of a [`keyframe`] glyph. Flat, without a dark outline (as in After Effects), so
|
||||
/// keys that overlap read as one shape instead of a tangle of borders (#284); the hairline in
|
||||
/// the fill colour closes the seam between the halves.
|
||||
fn keyframe_shapes(
|
||||
center: Pos2,
|
||||
size: f32,
|
||||
left: effectcraft_engine::keyframe::KeyHalf,
|
||||
right: effectcraft_engine::keyframe::KeyHalf,
|
||||
fill: Color32,
|
||||
) -> Vec<egui::Shape> {
|
||||
use effectcraft_engine::keyframe::KeyHalf as H;
|
||||
let r = size / 2.0;
|
||||
let half = |pts: Vec<Pos2>| {
|
||||
painter.add(PathShape::convex_polygon(pts, fill, Stroke::new(1.0, outline)));
|
||||
};
|
||||
let mut out = Vec::with_capacity(2);
|
||||
let mut half = |pts: Vec<Pos2>| out.push(PathShape::convex_polygon(pts, fill, Stroke::new(0.5, fill)).into());
|
||||
let c = center;
|
||||
for (side, h) in [(-1.0f32, left), (1.0, right)] {
|
||||
match h {
|
||||
|
|
@ -678,4 +689,26 @@ pub fn keyframe(
|
|||
}
|
||||
}
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use effectcraft_engine::keyframe::KeyHalf as H;
|
||||
|
||||
/// #284: keyframes have no dark border (overlapping keys looked messy): each half is filled
|
||||
/// and edged in the key's own colour.
|
||||
#[test]
|
||||
fn keyframes_are_drawn_without_a_dark_outline() {
|
||||
let fill = egui::Color32::from_gray(0xc0);
|
||||
for (l, r) in [(H::Linear, H::Linear), (H::Bezier, H::Hold), (H::Auto, H::Linear)] {
|
||||
let shapes = super::keyframe_shapes(egui::pos2(10.0, 10.0), 11.0, l, r, fill);
|
||||
assert_eq!(shapes.len(), 2);
|
||||
for s in shapes {
|
||||
let egui::Shape::Path(p) = s else { panic!("a path: {s:?}") };
|
||||
assert_eq!(p.fill, fill);
|
||||
assert!(p.stroke.width <= 0.5 && p.stroke.color == egui::epaint::ColorMode::Solid(fill), "{:?}", p.stroke);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2255,7 +2255,7 @@ pub fn show(app: &mut EffectcraftApp, ui: &mut egui::Ui, rect: Rect) {
|
|||
// Roving keys: a small dot (their time follows their neighbours).
|
||||
gp.circle_filled(c, 2.5, kcol);
|
||||
} else {
|
||||
icons::keyframe(&gp, c, 11.0, icon.left, icon.right, kcol, Color32::from_black_alpha(200));
|
||||
icons::keyframe(&gp, c, 11.0, icon.left, icon.right, kcol);
|
||||
}
|
||||
let kr = Rect::from_center_size(c, vec2(12.0, 14.0));
|
||||
let kresp = ui.interact(kr, egui::Id::new(("key", uid, k.time.0)), Sense::click_and_drag());
|
||||
|
|
|
|||
|
|
@ -187,6 +187,8 @@ impl Tokens {
|
|||
tl_ruler_bg: Color32::from_rgb(0xe2, 0xe2, 0xe2),
|
||||
tl_ruler_text: Color32::from_rgb(0x50, 0x50, 0x50),
|
||||
pasteboard: Color32::from_rgb(0xa8, 0xa8, 0xa8),
|
||||
// Keyframes have no outline: dark enough to stand out on the light time graph.
|
||||
keyframe: Color32::from_rgb(0x6c, 0x6c, 0x6c),
|
||||
..dark
|
||||
},
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue