From 89b1f10b6e68c0290bc2cf5964ad4c2e15f36288 Mon Sep 17 00:00:00 2001 From: Adrien Date: Thu, 21 Mar 2024 21:05:04 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Add=20Pyramid=20icon?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/icons.rs | 116 +++++++++++++++++++++++++++++++++++++- src/components/icons.scss | 5 ++ 2 files changed, 120 insertions(+), 1 deletion(-) diff --git a/src/components/icons.rs b/src/components/icons.rs index 52f6a0d..98e1097 100644 --- a/src/components/icons.rs +++ b/src/components/icons.rs @@ -1,9 +1,13 @@ use dioxus::prelude::*; use dioxus_free_icons::icons::md_navigation_icons::MdArrowDropDown; -use dioxus_free_icons::Icon; +use dioxus_free_icons::{Icon, IconShape}; turf::style_sheet!("src/components/icons.scss"); +include!(concat!(env!("OUT_DIR"), "/style_vars.rs")); + +use style::{COLOR_PRIMARY_100, COLOR_TERNARY_100}; + pub fn DownArrowIcon(cx: Scope) -> Element { cx.render(rsx! { style { STYLE_SHEET }, @@ -14,3 +18,113 @@ pub fn DownArrowIcon(cx: Scope) -> Element { } }) } + +const _PYRAMID_OFFSET_X: f64 = 1.0; +const _PYRAMID_OFFSET_Y: f64 = 2.0; +const _PYRAMID_STROKE_WIDTH: f64 = 2.0; + +const _PYRAMID_DIST_FROM_CENTRAL_X: f64 = 65.0; +const _PYRAMID_DIST_FROM_CENTRAL_E1_Y: f64 = 83.0; + +const _PYRAMID_EDGES_E1_X: f64 = _PYRAMID_DIST_FROM_CENTRAL_X + _PYRAMID_OFFSET_X; +const _PYRAMID_EDGES_E1_Y: f64 = _PYRAMID_OFFSET_Y; + +const _PYRAMID_LEFT_EDGE_E2_X: f64 = _PYRAMID_OFFSET_X; +const _PYRAMID_LEFT_EDGE_E2_Y: f64 = _PYRAMID_DIST_FROM_CENTRAL_E1_Y + _PYRAMID_OFFSET_Y; + +const _PYRAMID_CENTRAL_EDGE_E2_X: f64 = _PYRAMID_DIST_FROM_CENTRAL_X + _PYRAMID_OFFSET_X; +const _PYRAMID_CENTRAL_EDGE_E2_Y: f64 = 100.0 + _PYRAMID_OFFSET_Y; +const _PYRAMID_CENTRAL_EDGE_Y_LEN: f64 = _PYRAMID_CENTRAL_EDGE_E2_Y - _PYRAMID_EDGES_E1_Y; + +const _PYRAMID_RIGHT_EDGE_E2_X: f64 = 130.0 + _PYRAMID_OFFSET_X; +const _PYRAMID_RIGHT_EDGE_E2_Y: f64 = _PYRAMID_LEFT_EDGE_E2_Y; + +struct PyramidShape<'a> { + color: &'a str, + ratio: f64, + progress_color: &'a str, +} + +impl<'a> IconShape for PyramidShape<'a> { + fn view_box(&self) -> String { + let height = _PYRAMID_CENTRAL_EDGE_E2_Y + _PYRAMID_STROKE_WIDTH; + let width = _PYRAMID_RIGHT_EDGE_E2_X + _PYRAMID_STROKE_WIDTH; + format!("0 0 {width} {height}") + } + + fn xmlns(&self) -> String { + String::from("http://www.w3.org/2000/svg") + } + + fn child_elements(&self) -> LazyNodes { + let inverted_ratio = 1.0 - self.ratio; + + let central_edge_ratio_e2_y = + _PYRAMID_CENTRAL_EDGE_Y_LEN * inverted_ratio + _PYRAMID_OFFSET_Y; + + let left_edge_ratio_e1_x = _PYRAMID_OFFSET_X + (_PYRAMID_DIST_FROM_CENTRAL_X * self.ratio); + let right_edge_ratio_e1_x = _PYRAMID_OFFSET_X + + _PYRAMID_EDGES_E1_X + + (_PYRAMID_DIST_FROM_CENTRAL_X * inverted_ratio); + let no_central_edge_ratio_e1_y = + _PYRAMID_OFFSET_Y + (_PYRAMID_DIST_FROM_CENTRAL_E1_Y * inverted_ratio); + + rsx! { + g { + stroke: "#fff", + "stroke-linejoin": "round", + "stroke-width": _PYRAMID_STROKE_WIDTH, + fill: "#{self.progress_color}", + + path { + fill: "#{self.color}", + d: "\ + M {_PYRAMID_EDGES_E1_X} {_PYRAMID_EDGES_E1_Y} \ + L {_PYRAMID_RIGHT_EDGE_E2_X} {_PYRAMID_RIGHT_EDGE_E2_Y} \ + L {_PYRAMID_EDGES_E1_X} {_PYRAMID_CENTRAL_EDGE_E2_Y} \ + M {_PYRAMID_EDGES_E1_X} {_PYRAMID_EDGES_E1_Y} \ + L {_PYRAMID_LEFT_EDGE_E2_X} {_PYRAMID_LEFT_EDGE_E2_Y} \ + L {_PYRAMID_EDGES_E1_X} {_PYRAMID_CENTRAL_EDGE_E2_Y} \ + M {_PYRAMID_EDGES_E1_X} {_PYRAMID_EDGES_E1_Y} \ + V {_PYRAMID_CENTRAL_EDGE_Y_LEN}", + }, + path { + d: "\ + M {_PYRAMID_CENTRAL_EDGE_E2_X} {_PYRAMID_CENTRAL_EDGE_E2_Y} \ + V {central_edge_ratio_e2_y} \ + L {left_edge_ratio_e1_x} {no_central_edge_ratio_e1_y} \ + L {_PYRAMID_LEFT_EDGE_E2_X} {_PYRAMID_LEFT_EDGE_E2_Y} Z", + }, + path { + d: "\ + M {_PYRAMID_CENTRAL_EDGE_E2_X} {_PYRAMID_CENTRAL_EDGE_E2_Y} \ + V {central_edge_ratio_e2_y} \ + L {right_edge_ratio_e1_x} {no_central_edge_ratio_e1_y} \ + L {_PYRAMID_RIGHT_EDGE_E2_X} {_PYRAMID_RIGHT_EDGE_E2_Y} Z", + } + } + } + } +} + +#[derive(Props)] +pub struct PyramidProps<'a> { + #[props(default = 0.5)] + color: Option<&'a str>, + ratio: f64, + progress_color: Option<&'a str>, +} + +pub fn Pyramid<'a>(cx: Scope<'a, PyramidProps<'a>>) -> Element<'a> { + let progress_color = cx.props.progress_color.unwrap_or(COLOR_PRIMARY_100); + let color = cx.props.color.unwrap_or(COLOR_TERNARY_100); + + cx.render(rsx! { + style { STYLE_SHEET }, + + Icon { + class: ClassName::PYRAMID_ICON, + icon: PyramidShape { ratio: cx.props.ratio, color: color, progress_color: progress_color }, + } + }) +} diff --git a/src/components/icons.scss b/src/components/icons.scss index 19e1d0c..494370c 100644 --- a/src/components/icons.scss +++ b/src/components/icons.scss @@ -5,3 +5,8 @@ fill: white; } } + +.pyramid-icon { + height: 100%; + width: 100%; +}