Animation on button click

This commit is contained in:
cool-mist 2025-05-11 19:00:52 +05:30
parent 8b71bce89c
commit 1dfe56ac50
2 changed files with 83 additions and 33 deletions

View File

@ -100,7 +100,7 @@ impl Game {
let mut button_action = None; let mut button_action = None;
for btn in &mut self.btns { for btn in &mut self.btns {
btn.handle_input(); btn.handle_input();
if btn.is_pressed { if btn.is_clicked() {
button_action = Some(btn.action); button_action = Some(btn.action);
} }
} }
@ -431,7 +431,6 @@ impl Game {
self.board = self.original_board.clone(); self.board = self.original_board.clone();
self.reset_squares(); self.reset_squares();
for btn in &mut self.btns { for btn in &mut self.btns {
btn.reset();
if let ButtonAction::Next = btn.action { if let ButtonAction::Next = btn.action {
btn.is_active = false; btn.is_active = false;
} }

View File

@ -2,10 +2,12 @@ use macroquad::prelude::*;
pub struct Button { pub struct Button {
pub text: String, pub text: String,
pub is_pressed: bool,
pub is_active: bool, pub is_active: bool,
pub action: ButtonAction, pub action: ButtonAction,
is_down: bool,
is_clicked: bool,
rect: Rect, rect: Rect,
shadow_width: f32,
} }
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
@ -19,13 +21,24 @@ impl Button {
let rect = Rect::new(x, y, width, height); let rect = Rect::new(x, y, width, height);
Self { Self {
text: text.to_string(), text: text.to_string(),
is_pressed: false, is_down: false,
is_clicked: false,
is_active: true, is_active: true,
rect, rect,
action, action,
shadow_width: 5.0,
} }
} }
pub fn is_clicked(&mut self) -> bool {
if self.is_clicked {
self.is_clicked = false;
return true;
}
false
}
pub fn draw(&self) { pub fn draw(&self) {
self.draw_button(); self.draw_button();
self.draw_label(); self.draw_label();
@ -33,81 +46,119 @@ impl Button {
fn draw_button(&self) { fn draw_button(&self) {
let bg_color = Color::from_rgba(190, 190, 190, 255); let bg_color = Color::from_rgba(190, 190, 190, 255);
draw_rectangle(self.rect.x, self.rect.y, self.rect.w, self.rect.h, bg_color); let button_draw_offset = self.get_button_draw_offset();
draw_rectangle(
self.rect.x + button_draw_offset,
self.rect.y + button_draw_offset,
self.rect.w,
self.rect.h,
bg_color,
);
self.draw_shadow();
}
fn draw_shadow(&self) {
if !self.is_active {
return;
}
if self.is_down {
return;
}
let color = Color::from_rgba(0, 0, 0, 100); let color = Color::from_rgba(0, 0, 0, 100);
let width = 5.0;
draw_rectangle( draw_rectangle(
self.rect.x + self.rect.w, self.rect.x + self.rect.w,
self.rect.y + width, self.rect.y + self.shadow_width,
width, self.shadow_width,
self.rect.h, self.rect.h,
color, color,
); );
draw_rectangle( draw_rectangle(
self.rect.x + width, self.rect.x + self.shadow_width,
self.rect.y + self.rect.h, self.rect.y + self.rect.h,
self.rect.w - width, self.rect.w - self.shadow_width,
width, self.shadow_width,
color, color,
); );
draw_triangle( draw_triangle(
vec2(self.rect.x + self.rect.w, self.rect.y), vec2(self.rect.x + self.rect.w, self.rect.y),
vec2(self.rect.x + self.rect.w + width, self.rect.y + width), vec2(
vec2(self.rect.x + self.rect.w, self.rect.y + width), self.rect.x + self.rect.w + self.shadow_width,
self.rect.y + self.shadow_width,
),
vec2(self.rect.x + self.rect.w, self.rect.y + self.shadow_width),
color, color,
); );
draw_triangle( draw_triangle(
vec2(self.rect.x, self.rect.y + self.rect.h), vec2(self.rect.x, self.rect.y + self.rect.h),
vec2(self.rect.x + width, self.rect.y + self.rect.h + width), vec2(
vec2(self.rect.x + width, self.rect.y + self.rect.h), self.rect.x + self.shadow_width,
self.rect.y + self.rect.h + self.shadow_width,
),
vec2(self.rect.x + self.shadow_width, self.rect.y + self.rect.h),
color, color,
); );
} }
fn draw_label(&self) { fn draw_label(&self) {
let font_color = if self.is_active { let font_color = match self.is_active {
Color::from_rgba(0, 0, 0, 255) true => Color::from_rgba(0, 0, 0, 255),
} else { false => Color::from_rgba(100, 100, 100, 255)
Color::from_rgba(100, 0, 0, 255)
}; };
let font_size = (0.5 * self.rect.h) as u16; let font_size = (0.5 * self.rect.h) as u16;
let dims = measure_text(&self.text, None, font_size, 1.0); let dims = measure_text(&self.text, None, font_size, 1.0);
let button_draw_offset = self.get_button_draw_offset();
draw_text( draw_text(
&self.text, &self.text,
self.rect.x + (self.rect.w - dims.width) * 0.5, self.rect.x + (self.rect.w - dims.width) * 0.5 + button_draw_offset,
self.rect.y + (self.rect.h - dims.height) * 0.5 + dims.offset_y, self.rect.y + (self.rect.h - dims.height) * 0.5 + dims.offset_y + button_draw_offset,
font_size as f32, font_size as f32,
font_color, font_color,
); );
} }
pub fn reset(&mut self) { fn get_button_draw_offset(&self) -> f32 {
self.is_pressed = false; let button_pressed_correction = match self.is_down {
self.is_active = true; true => self.shadow_width,
false => match self.is_active {
true => 0.0,
false => self.shadow_width,
},
};
button_pressed_correction
} }
pub fn handle_input(&mut self) { pub fn handle_input(&mut self) {
if !self.is_active { if !self.is_active {
return; self.is_down = false;
}
if !is_mouse_button_released(MouseButton::Left) {
self.is_pressed = false;
return; return;
} }
let (mx, my) = mouse_position(); let (mx, my) = mouse_position();
let c = Circle::new(mx, my, 0.0); let c = Circle::new(mx, my, 0.0);
if is_mouse_button_pressed(MouseButton::Left) {
if c.overlaps_rect(&self.rect) { if c.overlaps_rect(&self.rect) {
self.is_pressed = true; self.is_down = true;
return;
}
}
if is_mouse_button_released(MouseButton::Left) {
if c.overlaps_rect(&self.rect) {
self.is_clicked = true;
self.is_down = false;
return; return;
} }
self.is_pressed = false; self.is_down = false;
}
} }
} }