Animated transforms on hover
This commit is contained in:
@@ -1,9 +1,9 @@
|
|||||||
use glam::FloatExt;
|
use glam::{FloatExt, Vec2};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
event::WidgetCallback,
|
event::WidgetCallback,
|
||||||
layout::{WidgetID, WidgetMap},
|
layout::{WidgetID, WidgetMap, WidgetNodeMap},
|
||||||
widget::WidgetObj,
|
widget::{WidgetData, WidgetObj},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub enum AnimationEasing {
|
pub enum AnimationEasing {
|
||||||
@@ -36,8 +36,10 @@ impl AnimationEasing {
|
|||||||
|
|
||||||
pub struct CallbackData<'a> {
|
pub struct CallbackData<'a> {
|
||||||
pub obj: &'a mut dyn WidgetObj,
|
pub obj: &'a mut dyn WidgetObj,
|
||||||
|
pub data: &'a mut WidgetData,
|
||||||
pub widgets: &'a WidgetMap,
|
pub widgets: &'a WidgetMap,
|
||||||
pub widget_id: WidgetID,
|
pub widget_id: WidgetID,
|
||||||
|
pub widget_size: Vec2,
|
||||||
pub pos: f32, // 0.0 (start of animation) - 1.0 (end of animation)
|
pub pos: f32, // 0.0 (start of animation) - 1.0 (end of animation)
|
||||||
pub needs_redraw: bool,
|
pub needs_redraw: bool,
|
||||||
pub dirty_nodes: &'a mut Vec<taffy::NodeId>,
|
pub dirty_nodes: &'a mut Vec<taffy::NodeId>,
|
||||||
@@ -110,20 +112,32 @@ impl Animation {
|
|||||||
|
|
||||||
fn call(
|
fn call(
|
||||||
&self,
|
&self,
|
||||||
widgets: &WidgetMap,
|
widget_map: &WidgetMap,
|
||||||
|
widget_node_map: &WidgetNodeMap,
|
||||||
|
tree: &taffy::tree::TaffyTree<WidgetID>,
|
||||||
dirty_nodes: &mut Vec<taffy::NodeId>,
|
dirty_nodes: &mut Vec<taffy::NodeId>,
|
||||||
pos: f32,
|
pos: f32,
|
||||||
) -> CallResult {
|
) -> CallResult {
|
||||||
let mut res = CallResult::default();
|
let mut res = CallResult::default();
|
||||||
|
|
||||||
if let Some(widget) = widgets.get(self.target_widget).cloned() {
|
let Some(widget) = widget_map.get(self.target_widget).cloned() else {
|
||||||
|
return res; // failed
|
||||||
|
};
|
||||||
|
|
||||||
|
let widget_node = widget_node_map.get(self.target_widget);
|
||||||
|
let layout = tree.layout(widget_node).unwrap(); // should always succeed
|
||||||
|
|
||||||
let mut widget = widget.lock().unwrap();
|
let mut widget = widget.lock().unwrap();
|
||||||
|
|
||||||
|
let (data, obj) = widget.get_data_obj_mut();
|
||||||
|
|
||||||
let data = &mut CallbackData {
|
let data = &mut CallbackData {
|
||||||
widget_id: self.target_widget,
|
widget_id: self.target_widget,
|
||||||
dirty_nodes,
|
dirty_nodes,
|
||||||
widgets,
|
widgets: widget_map,
|
||||||
obj: widget.obj.as_mut(),
|
widget_size: Vec2::new(layout.size.width, layout.size.height),
|
||||||
|
obj,
|
||||||
|
data,
|
||||||
pos,
|
pos,
|
||||||
needs_redraw: false,
|
needs_redraw: false,
|
||||||
};
|
};
|
||||||
@@ -133,7 +147,6 @@ impl Animation {
|
|||||||
if data.needs_redraw {
|
if data.needs_redraw {
|
||||||
res.needs_redraw = true;
|
res.needs_redraw = true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
@@ -147,7 +160,9 @@ pub struct Animations {
|
|||||||
impl Animations {
|
impl Animations {
|
||||||
pub fn tick(
|
pub fn tick(
|
||||||
&mut self,
|
&mut self,
|
||||||
widgets: &WidgetMap,
|
widget_map: &WidgetMap,
|
||||||
|
widget_node_map: &WidgetNodeMap,
|
||||||
|
tree: &taffy::tree::TaffyTree<WidgetID>,
|
||||||
dirty_nodes: &mut Vec<taffy::NodeId>,
|
dirty_nodes: &mut Vec<taffy::NodeId>,
|
||||||
needs_redraw: &mut bool,
|
needs_redraw: &mut bool,
|
||||||
) {
|
) {
|
||||||
@@ -163,7 +178,7 @@ impl Animations {
|
|||||||
anim.pos_prev = anim.pos;
|
anim.pos_prev = anim.pos;
|
||||||
anim.pos = pos;
|
anim.pos = pos;
|
||||||
|
|
||||||
let res = anim.call(widgets, dirty_nodes, 1.0);
|
let res = anim.call(widget_map, widget_node_map, tree, dirty_nodes, 1.0);
|
||||||
|
|
||||||
if anim.last_tick || res.needs_redraw {
|
if anim.last_tick || res.needs_redraw {
|
||||||
*needs_redraw = true;
|
*needs_redraw = true;
|
||||||
@@ -179,14 +194,16 @@ impl Animations {
|
|||||||
|
|
||||||
pub fn process(
|
pub fn process(
|
||||||
&mut self,
|
&mut self,
|
||||||
widgets: &WidgetMap,
|
widget_map: &WidgetMap,
|
||||||
|
widget_node_map: &WidgetNodeMap,
|
||||||
|
tree: &taffy::tree::TaffyTree<WidgetID>,
|
||||||
dirty_nodes: &mut Vec<taffy::NodeId>,
|
dirty_nodes: &mut Vec<taffy::NodeId>,
|
||||||
alpha: f32,
|
alpha: f32,
|
||||||
needs_redraw: &mut bool,
|
needs_redraw: &mut bool,
|
||||||
) {
|
) {
|
||||||
for anim in &mut self.running_animations {
|
for anim in &mut self.running_animations {
|
||||||
let pos = anim.pos_prev.lerp(anim.pos, alpha);
|
let pos = anim.pos_prev.lerp(anim.pos, alpha);
|
||||||
let res = anim.call(widgets, dirty_nodes, pos);
|
let res = anim.call(widget_map, widget_node_map, tree, dirty_nodes, pos);
|
||||||
|
|
||||||
if res.needs_redraw {
|
if res.needs_redraw {
|
||||||
*needs_redraw = true;
|
*needs_redraw = true;
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ pub fn construct(
|
|||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let mut widget = layout.widget_states.get(rect_id).unwrap().lock().unwrap();
|
let mut widget = layout.widget_map.get(rect_id).unwrap().lock().unwrap();
|
||||||
|
|
||||||
let button = Arc::new(Button {
|
let button = Arc::new(Button {
|
||||||
body: rect_id,
|
body: rect_id,
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ fn draw_children(
|
|||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
let Some(widget) = layout.widget_states.get(widget_id) else {
|
let Some(widget) = layout.widget_map.get(widget_id) else {
|
||||||
debug_assert!(false);
|
debug_assert!(false);
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
@@ -172,7 +172,7 @@ pub fn draw(layout: &Layout) -> anyhow::Result<Vec<RenderPrimitive>> {
|
|||||||
let mut transform_stack = TransformStack::new();
|
let mut transform_stack = TransformStack::new();
|
||||||
let model = glam::Mat4::IDENTITY;
|
let model = glam::Mat4::IDENTITY;
|
||||||
|
|
||||||
let Some(root_widget) = layout.widget_states.get(layout.root_widget) else {
|
let Some(root_widget) = layout.widget_map.get(layout.root_widget) else {
|
||||||
panic!();
|
panic!();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,18 @@ use taffy::{TaffyTree, TraversePartialTree};
|
|||||||
pub type WidgetID = slotmap::DefaultKey;
|
pub type WidgetID = slotmap::DefaultKey;
|
||||||
pub type BoxWidget = Arc<Mutex<WidgetState>>;
|
pub type BoxWidget = Arc<Mutex<WidgetState>>;
|
||||||
pub type WidgetMap = HopSlotMap<slotmap::DefaultKey, BoxWidget>;
|
pub type WidgetMap = HopSlotMap<slotmap::DefaultKey, BoxWidget>;
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct WidgetNodeMap(pub HashMap<WidgetID, taffy::NodeId>);
|
||||||
|
|
||||||
|
impl WidgetNodeMap {
|
||||||
|
pub fn get(&self, widget_id: WidgetID) -> taffy::NodeId {
|
||||||
|
let Some(node) = self.0.get(&widget_id).cloned() else {
|
||||||
|
// this shouldn't happen!
|
||||||
|
panic!("node_map is corrupted");
|
||||||
|
};
|
||||||
|
node
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct PushEventState<'a> {
|
struct PushEventState<'a> {
|
||||||
pub animations: &'a mut Vec<animation::Animation>,
|
pub animations: &'a mut Vec<animation::Animation>,
|
||||||
@@ -31,8 +43,8 @@ pub struct Layout {
|
|||||||
|
|
||||||
pub assets: Box<dyn AssetProvider>,
|
pub assets: Box<dyn AssetProvider>,
|
||||||
|
|
||||||
pub widget_states: WidgetMap,
|
pub widget_map: WidgetMap,
|
||||||
pub widget_node_map: HashMap<WidgetID, taffy::NodeId>,
|
pub widget_node_map: WidgetNodeMap,
|
||||||
|
|
||||||
pub root_widget: WidgetID,
|
pub root_widget: WidgetID,
|
||||||
pub root_node: taffy::NodeId,
|
pub root_node: taffy::NodeId,
|
||||||
@@ -48,47 +60,40 @@ pub struct Layout {
|
|||||||
|
|
||||||
fn add_child_internal(
|
fn add_child_internal(
|
||||||
tree: &mut taffy::TaffyTree<WidgetID>,
|
tree: &mut taffy::TaffyTree<WidgetID>,
|
||||||
widget_node_map: &mut HashMap<WidgetID, taffy::NodeId>,
|
widget_map: &mut WidgetMap,
|
||||||
vec: &mut WidgetMap,
|
widget_node_map: &mut WidgetNodeMap,
|
||||||
parent_node: Option<taffy::NodeId>,
|
parent_node: Option<taffy::NodeId>,
|
||||||
widget: WidgetState,
|
widget: WidgetState,
|
||||||
style: taffy::Style,
|
style: taffy::Style,
|
||||||
) -> anyhow::Result<(WidgetID, taffy::NodeId)> {
|
) -> anyhow::Result<(WidgetID, taffy::NodeId)> {
|
||||||
#[allow(clippy::arc_with_non_send_sync)]
|
#[allow(clippy::arc_with_non_send_sync)]
|
||||||
let child_id = vec.insert(Arc::new(Mutex::new(widget)));
|
let child_id = widget_map.insert(Arc::new(Mutex::new(widget)));
|
||||||
let child_node = tree.new_leaf_with_context(style, child_id)?;
|
let child_node = tree.new_leaf_with_context(style, child_id)?;
|
||||||
|
|
||||||
if let Some(parent_node) = parent_node {
|
if let Some(parent_node) = parent_node {
|
||||||
tree.add_child(parent_node, child_node)?;
|
tree.add_child(parent_node, child_node)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
widget_node_map.insert(child_id, child_node);
|
widget_node_map.0.insert(child_id, child_node);
|
||||||
|
|
||||||
Ok((child_id, child_node))
|
Ok((child_id, child_node))
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Layout {
|
impl Layout {
|
||||||
pub fn get_node(&self, widget_id: WidgetID) -> anyhow::Result<taffy::NodeId> {
|
|
||||||
let Some(node) = self.widget_node_map.get(&widget_id).cloned() else {
|
|
||||||
anyhow::bail!("invalid parent widget");
|
|
||||||
};
|
|
||||||
Ok(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add_child(
|
pub fn add_child(
|
||||||
&mut self,
|
&mut self,
|
||||||
parent_widget_id: WidgetID,
|
parent_widget_id: WidgetID,
|
||||||
widget: WidgetState,
|
widget: WidgetState,
|
||||||
style: taffy::Style,
|
style: taffy::Style,
|
||||||
) -> anyhow::Result<(WidgetID, taffy::NodeId)> {
|
) -> anyhow::Result<(WidgetID, taffy::NodeId)> {
|
||||||
let parent_node = self.get_node(parent_widget_id)?;
|
let parent_node = self.widget_node_map.get(parent_widget_id);
|
||||||
|
|
||||||
self.needs_redraw = true;
|
self.needs_redraw = true;
|
||||||
|
|
||||||
add_child_internal(
|
add_child_internal(
|
||||||
&mut self.tree,
|
&mut self.tree,
|
||||||
|
&mut self.widget_map,
|
||||||
&mut self.widget_node_map,
|
&mut self.widget_node_map,
|
||||||
&mut self.widget_states,
|
|
||||||
Some(parent_node),
|
Some(parent_node),
|
||||||
widget,
|
widget,
|
||||||
style,
|
style,
|
||||||
@@ -123,7 +128,7 @@ impl Layout {
|
|||||||
|
|
||||||
let style = self.tree.style(node_id)?;
|
let style = self.tree.style(node_id)?;
|
||||||
|
|
||||||
let Some(widget) = self.widget_states.get(widget_id) else {
|
let Some(widget) = self.widget_map.get(widget_id) else {
|
||||||
debug_assert!(false);
|
debug_assert!(false);
|
||||||
anyhow::bail!("invalid widget");
|
anyhow::bail!("invalid widget");
|
||||||
};
|
};
|
||||||
@@ -146,7 +151,7 @@ impl Layout {
|
|||||||
event,
|
event,
|
||||||
&mut EventParams {
|
&mut EventParams {
|
||||||
transform_stack: state.transform_stack,
|
transform_stack: state.transform_stack,
|
||||||
widgets: &self.widget_states,
|
widgets: &self.widget_map,
|
||||||
tree: &self.tree,
|
tree: &self.tree,
|
||||||
animations: state.animations,
|
animations: state.animations,
|
||||||
needs_redraw: &mut state.needs_redraw,
|
needs_redraw: &mut state.needs_redraw,
|
||||||
@@ -235,13 +240,13 @@ impl Layout {
|
|||||||
|
|
||||||
pub fn new(assets: Box<dyn AssetProvider>) -> anyhow::Result<Self> {
|
pub fn new(assets: Box<dyn AssetProvider>) -> anyhow::Result<Self> {
|
||||||
let mut tree = TaffyTree::new();
|
let mut tree = TaffyTree::new();
|
||||||
let mut widget_node_map = HashMap::new();
|
let mut widget_node_map = WidgetNodeMap::default();
|
||||||
let mut widget_states = HopSlotMap::new();
|
let mut widget_map = HopSlotMap::new();
|
||||||
|
|
||||||
let (root_widget, root_node) = add_child_internal(
|
let (root_widget, root_node) = add_child_internal(
|
||||||
&mut tree,
|
&mut tree,
|
||||||
|
&mut widget_map,
|
||||||
&mut widget_node_map,
|
&mut widget_node_map,
|
||||||
&mut widget_states,
|
|
||||||
None, // no parent
|
None, // no parent
|
||||||
Div::create()?,
|
Div::create()?,
|
||||||
taffy::Style {
|
taffy::Style {
|
||||||
@@ -257,7 +262,7 @@ impl Layout {
|
|||||||
root_node,
|
root_node,
|
||||||
root_widget,
|
root_widget,
|
||||||
widget_node_map,
|
widget_node_map,
|
||||||
widget_states,
|
widget_map,
|
||||||
needs_redraw: true,
|
needs_redraw: true,
|
||||||
haptics_triggered: false,
|
haptics_triggered: false,
|
||||||
animations: Animations::default(),
|
animations: Animations::default(),
|
||||||
@@ -269,7 +274,9 @@ impl Layout {
|
|||||||
let mut dirty_nodes = Vec::new();
|
let mut dirty_nodes = Vec::new();
|
||||||
|
|
||||||
self.animations.process(
|
self.animations.process(
|
||||||
&self.widget_states,
|
&self.widget_map,
|
||||||
|
&self.widget_node_map,
|
||||||
|
&self.tree,
|
||||||
&mut dirty_nodes,
|
&mut dirty_nodes,
|
||||||
timestep_alpha,
|
timestep_alpha,
|
||||||
&mut self.needs_redraw,
|
&mut self.needs_redraw,
|
||||||
@@ -301,7 +308,7 @@ impl Layout {
|
|||||||
match node_context {
|
match node_context {
|
||||||
None => taffy::Size::ZERO,
|
None => taffy::Size::ZERO,
|
||||||
Some(h) => {
|
Some(h) => {
|
||||||
if let Some(w) = self.widget_states.get(*h) {
|
if let Some(w) = self.widget_map.get(*h) {
|
||||||
w.lock()
|
w.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.obj
|
.obj
|
||||||
@@ -330,7 +337,9 @@ impl Layout {
|
|||||||
let mut dirty_nodes = Vec::new();
|
let mut dirty_nodes = Vec::new();
|
||||||
|
|
||||||
self.animations.tick(
|
self.animations.tick(
|
||||||
&self.widget_states,
|
&self.widget_map,
|
||||||
|
&self.widget_node_map,
|
||||||
|
&self.tree,
|
||||||
&mut dirty_nodes,
|
&mut dirty_nodes,
|
||||||
&mut self.needs_redraw,
|
&mut self.needs_redraw,
|
||||||
);
|
);
|
||||||
@@ -344,7 +353,7 @@ impl Layout {
|
|||||||
|
|
||||||
// helper function
|
// helper function
|
||||||
pub fn add_event_listener(&self, widget_id: WidgetID, listener: EventListener) {
|
pub fn add_event_listener(&self, widget_id: WidgetID, listener: EventListener) {
|
||||||
let Some(widget) = self.widget_states.get(widget_id) else {
|
let Some(widget) = self.widget_map.get(widget_id) else {
|
||||||
debug_assert!(false);
|
debug_assert!(false);
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
use glam::{Mat4, Vec2, Vec3};
|
||||||
use vulkano::buffer::BufferContents;
|
use vulkano::buffer::BufferContents;
|
||||||
|
|
||||||
// binary compatible mat4 which could be transparently used by vulkano BufferContents
|
// binary compatible mat4 which could be transparently used by vulkano BufferContents
|
||||||
@@ -6,13 +7,20 @@ use vulkano::buffer::BufferContents;
|
|||||||
pub struct WMat4(pub [f32; 16]);
|
pub struct WMat4(pub [f32; 16]);
|
||||||
|
|
||||||
impl WMat4 {
|
impl WMat4 {
|
||||||
pub fn from_glam(mat: &glam::Mat4) -> WMat4 {
|
pub fn from_glam(mat: &Mat4) -> WMat4 {
|
||||||
WMat4(*mat.as_ref())
|
WMat4(*mat.as_ref())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for WMat4 {
|
impl Default for WMat4 {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self(*glam::Mat4::IDENTITY.as_ref())
|
Self(*Mat4::IDENTITY.as_ref())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// works just like CSS transform-origin 50% 50%
|
||||||
|
pub fn centered_matrix(box_size: Vec2, input: &Mat4) -> Mat4 {
|
||||||
|
Mat4::from_translation(Vec3::new(box_size.x / 2.0, box_size.y / 2.0, 0.0))
|
||||||
|
* *input
|
||||||
|
* Mat4::from_translation(Vec3::new(-box_size.x / 2.0, -box_size.y / 2.0, 0.0))
|
||||||
|
}
|
||||||
|
|||||||
@@ -74,6 +74,12 @@ pub struct WidgetState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl WidgetState {
|
impl WidgetState {
|
||||||
|
pub fn get_data_obj_mut(&mut self) -> (&mut WidgetData, &mut dyn WidgetObj) {
|
||||||
|
let data = &mut self.data;
|
||||||
|
let obj = self.obj.as_mut();
|
||||||
|
(data, obj)
|
||||||
|
}
|
||||||
|
|
||||||
fn new(obj: Box<dyn WidgetObj>) -> anyhow::Result<WidgetState> {
|
fn new(obj: Box<dyn WidgetObj>) -> anyhow::Result<WidgetState> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
data: WidgetData {
|
data: WidgetData {
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
use std::{cell::RefCell, collections::HashMap, rc::Rc};
|
use std::{cell::RefCell, collections::HashMap, rc::Rc};
|
||||||
|
|
||||||
use glam::{Affine2, vec2, vec3a};
|
use glam::{Affine2, Mat4, Vec2, Vec3, vec2, vec3a};
|
||||||
use wgui::{
|
use wgui::{
|
||||||
animation::{Animation, AnimationEasing},
|
animation::{Animation, AnimationEasing},
|
||||||
drawing::Color,
|
drawing::Color,
|
||||||
event::{self, EventListener},
|
event::{self, EventListener},
|
||||||
|
renderer_vk::util,
|
||||||
taffy::{self, prelude::length},
|
taffy::{self, prelude::length},
|
||||||
widget::{
|
widget::{
|
||||||
div::Div,
|
div::Div,
|
||||||
@@ -161,7 +162,7 @@ where
|
|||||||
let key_state = {
|
let key_state = {
|
||||||
let widget = panel
|
let widget = panel
|
||||||
.layout
|
.layout
|
||||||
.widget_states
|
.widget_map
|
||||||
.get(*widget_id)
|
.get(*widget_id)
|
||||||
.unwrap() // want panic
|
.unwrap() // want panic
|
||||||
.lock()
|
.lock()
|
||||||
@@ -277,6 +278,28 @@ where
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const BUTTON_HOVER_SCALE: f32 = 0.1;
|
||||||
|
|
||||||
|
fn get_anim_transform(pos: f32, widget_size: Vec2) -> Mat4 {
|
||||||
|
util::centered_matrix(
|
||||||
|
widget_size,
|
||||||
|
&Mat4::from_scale(Vec3::splat(BUTTON_HOVER_SCALE.mul_add(pos, 1.0))),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_anim_color(key_state: &KeyState, rect: &mut Rectangle, pos: f32) {
|
||||||
|
let br1 = pos * 0.25;
|
||||||
|
let br2 = pos * 0.15;
|
||||||
|
|
||||||
|
rect.params.color.r = key_state.color.r + br1;
|
||||||
|
rect.params.color.g = key_state.color.g + br1;
|
||||||
|
rect.params.color.b = key_state.color.b + br1;
|
||||||
|
|
||||||
|
rect.params.color2.r = key_state.color2.r + br2;
|
||||||
|
rect.params.color2.g = key_state.color2.g + br2;
|
||||||
|
rect.params.color2.b = key_state.color2.b + br2;
|
||||||
|
}
|
||||||
|
|
||||||
fn on_enter_anim(
|
fn on_enter_anim(
|
||||||
key_state: Rc<KeyState>,
|
key_state: Rc<KeyState>,
|
||||||
_keyboard_state: Rc<RefCell<KeyboardState>>,
|
_keyboard_state: Rc<RefCell<KeyboardState>>,
|
||||||
@@ -284,14 +307,12 @@ fn on_enter_anim(
|
|||||||
) {
|
) {
|
||||||
data.animations.push(Animation::new(
|
data.animations.push(Animation::new(
|
||||||
data.widget_id,
|
data.widget_id,
|
||||||
5,
|
10,
|
||||||
AnimationEasing::OutQuad,
|
AnimationEasing::OutBack,
|
||||||
Box::new(move |data| {
|
Box::new(move |data| {
|
||||||
let rect = data.obj.get_as_mut::<Rectangle>();
|
let rect = data.obj.get_as_mut::<Rectangle>();
|
||||||
let brightness = data.pos * 0.5;
|
set_anim_color(&key_state, rect, data.pos);
|
||||||
rect.params.color.r = key_state.color.r + brightness;
|
data.data.transform = get_anim_transform(data.pos, data.widget_size);
|
||||||
rect.params.color.g = key_state.color.g + brightness;
|
|
||||||
rect.params.color.b = key_state.color.b + brightness;
|
|
||||||
data.needs_redraw = true;
|
data.needs_redraw = true;
|
||||||
}),
|
}),
|
||||||
));
|
));
|
||||||
@@ -304,14 +325,12 @@ fn on_leave_anim(
|
|||||||
) {
|
) {
|
||||||
data.animations.push(Animation::new(
|
data.animations.push(Animation::new(
|
||||||
data.widget_id,
|
data.widget_id,
|
||||||
5,
|
15,
|
||||||
AnimationEasing::OutQuad,
|
AnimationEasing::OutQuad,
|
||||||
Box::new(move |data| {
|
Box::new(move |data| {
|
||||||
let rect = data.obj.get_as_mut::<Rectangle>();
|
let rect = data.obj.get_as_mut::<Rectangle>();
|
||||||
let brightness = (1.0 - data.pos) * 0.5;
|
set_anim_color(&key_state, rect, 1.0 - data.pos);
|
||||||
rect.params.color.r = key_state.color.r + brightness;
|
data.data.transform = get_anim_transform(1.0 - data.pos, data.widget_size);
|
||||||
rect.params.color.g = key_state.color.g + brightness;
|
|
||||||
rect.params.color.b = key_state.color.b + brightness;
|
|
||||||
data.needs_redraw = true;
|
data.needs_redraw = true;
|
||||||
}),
|
}),
|
||||||
));
|
));
|
||||||
|
|||||||
Reference in New Issue
Block a user