dioxus_flow/
background.rs1use dioxus::prelude::*;
5
6use crate::state::FlowCore;
7
8#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)]
9pub enum BackgroundVariant {
10 #[default]
11 Dots,
12 Lines,
13 Cross,
14}
15
16#[component]
19pub fn Background(
20 #[props(default)] variant: BackgroundVariant,
21 #[props(default = 24.0)]
23 gap: f64,
24 #[props(default = 1.0)]
26 size: f64,
27 class: Option<String>,
28) -> Element {
29 let core = use_context::<FlowCore>();
30 let vp = *core.viewport.read();
31 let scaled = (gap * vp.zoom).max(1.0);
32 let x = vp.x.rem_euclid(scaled);
33 let y = vp.y.rem_euclid(scaled);
34 let pattern_id = format!("df-bg-{}", core.iid);
35 let class = format!(
36 "df-background{}",
37 class
38 .as_deref()
39 .map(|c| format!(" {c}"))
40 .unwrap_or_default()
41 );
42
43 rsx! {
44 svg { class,
45 defs {
46 pattern {
47 id: "{pattern_id}",
48 x,
49 y,
50 width: scaled,
51 height: scaled,
52 "patternUnits": "userSpaceOnUse",
53 match variant {
54 BackgroundVariant::Dots => rsx! {
55 circle {
56 class: "df-background-dot",
57 cx: scaled / 2.0,
58 cy: scaled / 2.0,
59 r: (size * vp.zoom).max(0.4),
60 }
61 },
62 BackgroundVariant::Lines => rsx! {
63 path {
64 class: "df-background-line",
65 d: "M {scaled} 0 H 0 V {scaled}",
66 fill: "none",
67 stroke_width: (size * vp.zoom).max(0.3),
68 }
69 },
70 BackgroundVariant::Cross => rsx! {
71 path {
72 class: "df-background-line",
73 d: {
74 let c = scaled / 2.0;
75 let arm = (3.0 * vp.zoom).max(1.5);
76 format!(
77 "M {} {c} H {} M {c} {} V {}",
78 c - arm,
79 c + arm,
80 c - arm,
81 c + arm,
82 )
83 },
84 fill: "none",
85 stroke_width: (size * vp.zoom).max(0.3),
86 }
87 },
88 }
89 }
90 }
91 rect {
92 width: "100%",
93 height: "100%",
94 fill: "url(#{pattern_id})",
95 }
96 }
97 }
98}