mirror of
https://github.com/adoyle0/thaw.git
synced 2025-02-08 19:03:09 -05:00
feat: color_picker component
This commit is contained in:
parent
3c9a13aef2
commit
ed2501d2d2
2 changed files with 21 additions and 19 deletions
|
@ -70,7 +70,7 @@
|
||||||
|
|
||||||
.melt-color-picker-slider {
|
.melt-color-picker-slider {
|
||||||
height: 12px;
|
height: 12px;
|
||||||
padding-right: 12px;
|
padding: 0 6px;
|
||||||
background-image: linear-gradient(
|
background-image: linear-gradient(
|
||||||
90deg,
|
90deg,
|
||||||
red,
|
red,
|
||||||
|
|
|
@ -99,7 +99,7 @@ pub fn ColorPicker(#[prop(optional, into)] value: MaybeRwSignal<RGBA>) -> impl I
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
|
||||||
<Panel hue=hue.read_only() sv/>
|
<ColorPanel hue=hue.read_only() sv/>
|
||||||
<HueSlider hue/>
|
<HueSlider hue/>
|
||||||
</div>
|
</div>
|
||||||
</Teleport>
|
</Teleport>
|
||||||
|
@ -107,19 +107,19 @@ pub fn ColorPicker(#[prop(optional, into)] value: MaybeRwSignal<RGBA>) -> impl I
|
||||||
}
|
}
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
fn Panel(hue: ReadSignal<u16>, sv: RwSignal<(f64, f64)>) -> impl IntoView {
|
fn ColorPanel(hue: ReadSignal<u16>, sv: RwSignal<(f64, f64)>) -> impl IntoView {
|
||||||
let panel_ref = create_node_ref::<html::Div>();
|
let panel_ref = create_node_ref::<html::Div>();
|
||||||
let mouse = store_value(Vec::<WindowListenerHandle>::new());
|
let mouse = store_value(Vec::<WindowListenerHandle>::new());
|
||||||
|
|
||||||
let on_mouse_down = move |_| {
|
let on_mouse_down = move |ev| {
|
||||||
let on_mouse_move = window_event_listener(ev::mousemove, move |ev| {
|
let cb = move |ev: ev::MouseEvent| {
|
||||||
if let Some(panel) = panel_ref.get_untracked() {
|
if let Some(panel) = panel_ref.get_untracked() {
|
||||||
let rect = panel.get_bounding_client_rect();
|
let rect = panel.get_bounding_client_rect();
|
||||||
let ev_x = f64::from(ev.x());
|
let ev_x = f64::from(ev.x());
|
||||||
let ev_y = f64::from(ev.y());
|
let ev_y = f64::from(ev.y());
|
||||||
|
|
||||||
let v = (rect.bottom() - ev_y) / rect.height();
|
let v = (rect.bottom() - ev_y) / rect.height();
|
||||||
let s = (ev_x - rect.x()) / rect.width();
|
let s = (ev_x - rect.left()) / rect.width();
|
||||||
|
|
||||||
let v = if v > 1.0 {
|
let v = if v > 1.0 {
|
||||||
1.0
|
1.0
|
||||||
|
@ -138,7 +138,9 @@ fn Panel(hue: ReadSignal<u16>, sv: RwSignal<(f64, f64)>) -> impl IntoView {
|
||||||
|
|
||||||
sv.set((s, v))
|
sv.set((s, v))
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
cb(ev);
|
||||||
|
let on_mouse_move = window_event_listener(ev::mousemove, cb);
|
||||||
let on_mouse_up = window_event_listener(ev::mouseup, move |_| {
|
let on_mouse_up = window_event_listener(ev::mouseup, move |_| {
|
||||||
mouse.update_value(|value| {
|
mouse.update_value(|value| {
|
||||||
for handle in value.drain(..).into_iter() {
|
for handle in value.drain(..).into_iter() {
|
||||||
|
@ -153,7 +155,7 @@ fn Panel(hue: ReadSignal<u16>, sv: RwSignal<(f64, f64)>) -> impl IntoView {
|
||||||
};
|
};
|
||||||
|
|
||||||
view! {
|
view! {
|
||||||
<div class="melt-color-picker-popover__panel" ref=panel_ref>
|
<div class="melt-color-picker-popover__panel" ref=panel_ref on:mousedown=on_mouse_down>
|
||||||
<div
|
<div
|
||||||
class="melt-color-picker-popover__layer"
|
class="melt-color-picker-popover__layer"
|
||||||
style:background-image=move || {
|
style:background-image=move || {
|
||||||
|
@ -164,12 +166,10 @@ fn Panel(hue: ReadSignal<u16>, sv: RwSignal<(f64, f64)>) -> impl IntoView {
|
||||||
<div class="melt-color-picker-popover__layer--shadowed"></div>
|
<div class="melt-color-picker-popover__layer--shadowed"></div>
|
||||||
<div
|
<div
|
||||||
class="melt-color-picker-popover__handle"
|
class="melt-color-picker-popover__handle"
|
||||||
on:mousedown=on_mouse_down
|
|
||||||
style=move || {
|
style=move || {
|
||||||
format!(
|
format!(
|
||||||
"left: calc({}% - 6px); bottom: calc({}% - 6px)",
|
"left: calc({}% - 6px); bottom: calc({}% - 6px)", sv.get().0 * 100.0, sv
|
||||||
sv.get().0 * 100.0,
|
.get().1 * 100.0,
|
||||||
sv.get().1 * 100.0,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
@ -183,12 +183,12 @@ fn HueSlider(hue: RwSignal<u16>) -> impl IntoView {
|
||||||
let rail_ref = create_node_ref::<html::Div>();
|
let rail_ref = create_node_ref::<html::Div>();
|
||||||
let mouse = store_value(Vec::<WindowListenerHandle>::new());
|
let mouse = store_value(Vec::<WindowListenerHandle>::new());
|
||||||
|
|
||||||
let on_mouse_down = move |_| {
|
let on_mouse_down = move |ev| {
|
||||||
let on_mouse_move = window_event_listener(ev::mousemove, move |ev| {
|
let cb = move |ev: ev::MouseEvent| {
|
||||||
if let Some(rail) = rail_ref.get_untracked() {
|
if let Some(rail) = rail_ref.get_untracked() {
|
||||||
let rect = rail.get_bounding_client_rect();
|
let rect = rail.get_bounding_client_rect();
|
||||||
let ev_x = f64::from(ev.x());
|
let ev_x = f64::from(ev.x());
|
||||||
let value = (ev_x - rect.x()) / (rect.width() - 12.0) * 360.0;
|
let value = (ev_x - rect.left() - 6.0) / (rect.width() - 12.0) * 359.0;
|
||||||
let value = if value < 0.0 {
|
let value = if value < 0.0 {
|
||||||
0
|
0
|
||||||
} else if value > 359.0 {
|
} else if value > 359.0 {
|
||||||
|
@ -198,7 +198,10 @@ fn HueSlider(hue: RwSignal<u16>) -> impl IntoView {
|
||||||
};
|
};
|
||||||
hue.set(value);
|
hue.set(value);
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
cb(ev);
|
||||||
|
|
||||||
|
let on_mouse_move = window_event_listener(ev::mousemove, cb);
|
||||||
let on_mouse_up = window_event_listener(ev::mouseup, move |_| {
|
let on_mouse_up = window_event_listener(ev::mouseup, move |_| {
|
||||||
mouse.update_value(|value| {
|
mouse.update_value(|value| {
|
||||||
for handle in value.drain(..).into_iter() {
|
for handle in value.drain(..).into_iter() {
|
||||||
|
@ -212,11 +215,10 @@ fn HueSlider(hue: RwSignal<u16>) -> impl IntoView {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
view! {
|
view! {
|
||||||
<div class="melt-color-picker-slider" ref=rail_ref>
|
<div class="melt-color-picker-slider" ref=rail_ref on:mousedown=on_mouse_down>
|
||||||
<div
|
<div
|
||||||
class="melt-color-picker-slider__handle"
|
class="melt-color-picker-slider__handle"
|
||||||
on:mousedown=on_mouse_down
|
style=move || format!("left: calc({}% - 6px)", f32::from(hue.get()) / 359.0 * 100.0)
|
||||||
style=move || format!("left: {}%", f32::from(hue.get()) / 359.0 * 100.0)
|
|
||||||
></div>
|
></div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue