Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

xilem_web: Add Rotate and Scale (CSS) transform views #621

Merged
merged 8 commits into from
Oct 10, 2024
77 changes: 64 additions & 13 deletions xilem_web/src/interfaces.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use crate::{
attribute::{Attr, WithAttributes},
class::{AsClassIter, Class, WithClasses},
events,
style::{IntoStyles, Style, WithStyle},
style::{IntoStyles, Rotate, Scale, ScaleValue, Style, WithStyle},
DomNode, DomView, IntoAttributeValue, OptionalAction, Pointer, PointerMsg,
};
use wasm_bindgen::JsCast;
Expand Down Expand Up @@ -146,6 +146,59 @@ pub trait Element<State, Action = ()>:
Attr::new(self, Cow::from("id"), value.into_attr_value())
}

/// Set a style attribute
fn style(self, style: impl IntoStyles) -> Style<Self, State, Action>
where
<Self::DomNode as DomNode>::Props: WithStyle,
{
let mut styles = vec![];
style.into_styles(&mut styles);
Style::new(self, styles)
}

/// Add a `rotate(<radians>rad)` [transform-function](https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function) to the current CSS `transform`
/// # Examples
///
/// ```
/// use xilem_web::{style as s, interfaces::Element, svg::kurbo::Rect};
///
/// # fn component() -> impl Element<()> {
/// Rect::from_origin_size((0.0, 10.0), (20.0, 30.0))
/// .style(s("transform", "translate(10px, 0)")) // can be combined with untyped `transform`
/// .rotate(std::f64::consts::PI / 4.0)
/// // results in the following html:
/// // <rect width="20" height="30" x="0.0" y="10.0" style="transform: translate(10px, 0) rotate(0.78539rad);"></rect>
/// # }
/// ```
fn rotate(self, radians: f64) -> Rotate<Self, State, Action>
where
<Self::DomNode as DomNode>::Props: WithStyle,
{
Rotate::new(self, radians)
}

/// Add a `scale(<scale>)` [transform-function](https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function) to the current CSS `transform`
/// # Examples
///
/// ```
/// use xilem_web::{style as s, interfaces::Element, svg::kurbo::Circle};
///
/// # fn component() -> impl Element<()> {
/// Circle::new((10.0, 20.0), 30.0)
/// .style(s("transform", "translate(10px, 0)")) // can be combined with untyped `transform`
/// .scale(1.5)
/// .scale((1.5, 2.0))
/// // results in the following html:
/// // <circle r="30" cy="20" cx="10" style="transform: translate(10px, 0) scale(1.5) scale(1.5, 2);"></circle>
/// # }
/// ```
fn scale(self, scale: impl Into<ScaleValue>) -> Scale<Self, State, Action>
where
<Self::DomNode as DomNode>::Props: WithStyle,
{
Scale::new(self, scale)
}

// event list from
// https://html.spec.whatwg.org/multipage/webappapis.html#idl-definitions
//
Expand Down Expand Up @@ -498,16 +551,19 @@ where
{
}

// pub trait StyleExt {
// }

// /// Keep this shared code in sync between `HtmlElement` and `SvgElement`
// macro_rules! style_impls {
// () => {};
// }

// #[cfg(feature = "HtmlElement")]
pub trait HtmlElement<State, Action = ()>:
Element<State, Action, DomNode: DomNode<Props: WithStyle> + AsRef<web_sys::HtmlElement>>
{
/// Set a style attribute
fn style(self, style: impl IntoStyles) -> Style<Self, State, Action> {
let mut styles = vec![];
style.into_styles(&mut styles);
Style::new(self, styles)
}
// style_impls!();
}

// #[cfg(feature = "HtmlElement")]
Expand Down Expand Up @@ -1479,12 +1535,7 @@ where
pub trait SvgElement<State, Action = ()>:
Element<State, Action, DomNode: DomNode<Props: WithStyle> + AsRef<web_sys::SvgElement>>
{
/// Set a style attribute
fn style(self, style: impl IntoStyles) -> Style<Self, State, Action> {
let mut styles = vec![];
style.into_styles(&mut styles);
Style::new(self, styles)
}
// style_impls!();
}

// #[cfg(feature = "SvgElement")]
Expand Down
36 changes: 36 additions & 0 deletions xilem_web/src/one_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,14 @@ impl WithStyle for Noop {
fn mark_end_of_style_modifier(&mut self) {
unreachable!()
}

fn get_style(&self, _name: &str) -> Option<&CowStr> {
unreachable!()
}

fn was_updated(&self, _name: &str) -> bool {
unreachable!()
}
}

impl<T> AsRef<T> for Noop {
Expand Down Expand Up @@ -425,6 +433,34 @@ impl<
OneOf::I(e) => e.mark_end_of_style_modifier(),
}
}

fn get_style(&self, name: &str) -> Option<&CowStr> {
match self {
OneOf::A(e) => e.get_style(name),
OneOf::B(e) => e.get_style(name),
OneOf::C(e) => e.get_style(name),
OneOf::D(e) => e.get_style(name),
OneOf::E(e) => e.get_style(name),
OneOf::F(e) => e.get_style(name),
OneOf::G(e) => e.get_style(name),
OneOf::H(e) => e.get_style(name),
OneOf::I(e) => e.get_style(name),
}
}

fn was_updated(&self, name: &str) -> bool {
match self {
OneOf::A(e) => e.was_updated(name),
OneOf::B(e) => e.was_updated(name),
OneOf::C(e) => e.was_updated(name),
OneOf::D(e) => e.was_updated(name),
OneOf::E(e) => e.was_updated(name),
OneOf::F(e) => e.was_updated(name),
OneOf::G(e) => e.was_updated(name),
OneOf::H(e) => e.was_updated(name),
OneOf::I(e) => e.was_updated(name),
}
}
}

impl<N1, N2, N3, N4, N5, N6, N7, N8, N9> DomNode for OneOf<N1, N2, N3, N4, N5, N6, N7, N8, N9>
Expand Down
Loading