epaint/shadow.rs
1use super::{Color32, Margin, Rect, RectShape, Rounding, Vec2};
2
3/// The color and fuzziness of a fuzzy shape.
4///
5/// Can be used for a rectangular shadow with a soft penumbra.
6///
7/// Very similar to a box-shadow in CSS.
8#[derive(Clone, Copy, Debug, Default, PartialEq)]
9#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
10pub struct Shadow {
11 /// Move the shadow by this much.
12 ///
13 /// For instance, a value of `[1.0, 2.0]` will move the shadow 1 point to the right and 2 points down,
14 /// causing a drop-shadow effect.
15 pub offset: Vec2,
16
17 /// The width of the blur, i.e. the width of the fuzzy penumbra.
18 ///
19 /// A value of 0.0 means a sharp shadow.
20 pub blur: f32,
21
22 /// Expand the shadow in all directions by this much.
23 pub spread: f32,
24
25 /// Color of the opaque center of the shadow.
26 pub color: Color32,
27}
28
29impl Shadow {
30 /// No shadow at all.
31 pub const NONE: Self = Self {
32 offset: Vec2::ZERO,
33 blur: 0.0,
34 spread: 0.0,
35 color: Color32::TRANSPARENT,
36 };
37
38 /// The argument is the rectangle of the shadow caster.
39 pub fn as_shape(&self, rect: Rect, rounding: impl Into<Rounding>) -> RectShape {
40 // tessellator.clip_rect = clip_rect; // TODO(emilk): culling
41
42 let Self {
43 offset,
44 blur,
45 spread,
46 color,
47 } = *self;
48
49 let rect = rect.translate(offset).expand(spread);
50 let rounding = rounding.into() + Rounding::same(spread.abs());
51
52 RectShape::filled(rect, rounding, color).with_blur_width(blur)
53 }
54
55 /// How much larger than the parent rect are we in each direction?
56 pub fn margin(&self) -> Margin {
57 let Self {
58 offset,
59 blur,
60 spread,
61 color: _,
62 } = *self;
63 Margin {
64 left: spread + 0.5 * blur - offset.x,
65 right: spread + 0.5 * blur + offset.x,
66 top: spread + 0.5 * blur - offset.y,
67 bottom: spread + 0.5 * blur + offset.y,
68 }
69 }
70}