From 4d85ce274fd4f8863b2aba8be31ea1b9e9305629 Mon Sep 17 00:00:00 2001 From: "S. Yakupov" Date: Wed, 2 Aug 2023 08:35:27 +0300 Subject: [PATCH] feat: add NG `Svg` --- dist/index.html | 4 +++ examples/logo-ng.svg-rs | 1 + examples/ng_svg.rs | 40 ++++++++++++++-------------- src/ng.rs | 3 +++ src/ng/svg.rs | 59 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 87 insertions(+), 20 deletions(-) create mode 100644 examples/logo-ng.svg-rs create mode 100644 src/ng/svg.rs diff --git a/dist/index.html b/dist/index.html index d993b97..ea7404a 100644 --- a/dist/index.html +++ b/dist/index.html @@ -71,6 +71,10 @@

⚠️ Work in progress!

Blur (source) +
  • + SVG + (source) +
  • diff --git a/examples/logo-ng.svg-rs b/examples/logo-ng.svg-rs new file mode 100644 index 0000000..6294b3d --- /dev/null +++ b/examples/logo-ng.svg-rs @@ -0,0 +1 @@ +view! { cx, } diff --git a/examples/ng_svg.rs b/examples/ng_svg.rs index 08b0d20..cf78c1e 100644 --- a/examples/ng_svg.rs +++ b/examples/ng_svg.rs @@ -1,24 +1,24 @@ -use lerni::{ - properties::{Align, VAlign}, - widgets::*, -}; -use wasm_bindgen::prelude::wasm_bindgen; -use yew::prelude::*; +use leptos::*; +use lerni::ng::*; -#[function_component] -pub fn SvgExample() -> Html { - html! { - +#[component] +pub fn SvgExample(cx: Scope) -> impl IntoView { + view! { cx, + - { include!("logo.svg-rs") } - { include!("logo.svg-rs") } - { include!("logo.svg-rs") } - { include!("logo.svg-rs") } - { include!("logo.svg-rs") } - { include!("logo.svg-rs") } - { include!("logo.svg-rs") } - { include!("logo.svg-rs") } - { include!("logo.svg-rs") } + {include!("logo-ng.svg-rs")} + {include!("logo-ng.svg-rs")} + + {include!("logo-ng.svg-rs")} + + {include!("logo-ng.svg-rs")} + {include!("logo-ng.svg-rs")} + {include!("logo-ng.svg-rs")} + { include!("logo-ng.svg-rs")} + {include!("logo-ng.svg-rs")} + + {include!("logo-ng.svg-rs")} + } @@ -26,5 +26,5 @@ pub fn SvgExample() -> Html { #[wasm_bindgen(start)] pub fn main() { - lerni::start::(); + lerni::ng::start(SvgExample); } diff --git a/src/ng.rs b/src/ng.rs index 9fb8bae..3c93fb7 100644 --- a/src/ng.rs +++ b/src/ng.rs @@ -32,6 +32,9 @@ pub use slide::Slide; mod slideshow; pub use slideshow::SlideShow; +mod svg; +pub use svg::Svg; + use leptos::*; /// Additional information provided to all slides. diff --git a/src/ng/svg.rs b/src/ng/svg.rs new file mode 100644 index 0000000..4958f8c --- /dev/null +++ b/src/ng/svg.rs @@ -0,0 +1,59 @@ +use leptos::*; + +use crate::ng::{use_frame, Align, VAlign}; + +/// SVG widget. +#[component] +pub fn Svg( + cx: Scope, + width: i32, + height: i32, + #[prop(default = Align::Center)] align: Align, + #[prop(default = VAlign::Middle)] valign: VAlign, + #[prop(default = 1.0)] scale: f32, + #[prop(optional)] flip_x: bool, + #[prop(optional)] flip_y: bool, + children: Children, +) -> impl IntoView { + let f = use_frame(cx); + + let scale = if matches!(align, Align::Fill) || matches!(valign, VAlign::Fill) { + let sx = f.width as f32 / width as f32; + let sy = f.height as f32 / height as f32; + sx.min(sy) + } else { + scale + }; + + let width = (scale * width as f32).round() as i32; + let height = (scale * height as f32).round() as i32; + + let mut x = match align { + Align::Left => f.x, + Align::Center | Align::Fill => f.x + (f.width - width) / 2, + Align::Right => f.x + f.width - width, + }; + let mut y = match valign { + VAlign::Top => f.y, + VAlign::Middle | VAlign::Fill => f.y + (f.height - height) / 2, + VAlign::Bottom => f.y + f.height - height, + }; + + let mut sx = scale; + let mut sy = scale; + + if flip_x { + sx = -sx; + x += width; + } + if flip_y { + sy = -sy; + y += height; + } + + view! { cx, + + {children(cx)} + + } +}