From 8b54dfb08c168314d34ebcf5b8776f31d786cf56 Mon Sep 17 00:00:00 2001 From: alanpoon Date: Tue, 19 Nov 2024 16:12:40 +0800 Subject: [PATCH 01/11] fix stop_animation --- src/home/room_screen.rs | 2 ++ src/shared/typing_animation.rs | 12 +++++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/home/room_screen.rs b/src/home/room_screen.rs index 9346ddad..d870291c 100644 --- a/src/home/room_screen.rs +++ b/src/home/room_screen.rs @@ -1585,6 +1585,8 @@ impl RoomScreen { } else { // Animate out the typing notice view (sliding it out towards the bottom). self.animator_play(cx, id!(typing_notice_animator.hide)); + let typing_animation = self.view.typing_animation(id!(typing_animation)); + typing_animation.stop_animation(); } if num_updates > 0 { diff --git a/src/shared/typing_animation.rs b/src/shared/typing_animation.rs index df23bc4a..944e094f 100644 --- a/src/shared/typing_animation.rs +++ b/src/shared/typing_animation.rs @@ -86,7 +86,7 @@ pub struct TypingAnimation { #[animator] animator: Animator, #[live(0.65)] animation_duration: f64, - #[rust] timer: Timer, + #[rust] timer: Option, #[rust] current_animated_dot: CurrentAnimatedDot, } @@ -109,8 +109,10 @@ impl CurrentAnimatedDot { impl Widget for TypingAnimation { fn handle_event(&mut self, cx: &mut Cx, event: &Event, scope: &mut Scope) { - if self.timer.is_event(event).is_some() { - self.update_animation(cx); + if let Some(timer) = self.timer { + if timer.is_event(event).is_some() { + self.update_animation(cx); + } } if self.animator_handle_event(cx, event).must_redraw() { self.redraw(cx); @@ -143,7 +145,7 @@ impl TypingAnimation { } }; - self.timer = cx.start_timeout(self.animation_duration * 0.5); + self.timer = Some(cx.start_timeout(self.animation_duration * 0.5)); } } @@ -156,7 +158,7 @@ impl TypingAnimationRef { pub fn stop_animation(&self) { if let Some(mut inner) = self.borrow_mut() { - inner.timer = Timer::default(); + inner.timer = None; } } } From 70a11fde7ec556a8a69c048222d1ff7583af88a4 Mon Sep 17 00:00:00 2001 From: alanpoon Date: Thu, 21 Nov 2024 17:19:16 +0800 Subject: [PATCH 02/11] added stop_timer --- src/home/room_screen.rs | 2 +- src/shared/typing_animation.rs | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/home/room_screen.rs b/src/home/room_screen.rs index d870291c..daced3ef 100644 --- a/src/home/room_screen.rs +++ b/src/home/room_screen.rs @@ -1586,7 +1586,7 @@ impl RoomScreen { // Animate out the typing notice view (sliding it out towards the bottom). self.animator_play(cx, id!(typing_notice_animator.hide)); let typing_animation = self.view.typing_animation(id!(typing_animation)); - typing_animation.stop_animation(); + typing_animation.stop_animation(cx); } if num_updates > 0 { diff --git a/src/shared/typing_animation.rs b/src/shared/typing_animation.rs index 944e094f..cf05380f 100644 --- a/src/shared/typing_animation.rs +++ b/src/shared/typing_animation.rs @@ -156,8 +156,11 @@ impl TypingAnimationRef { } } - pub fn stop_animation(&self) { + pub fn stop_animation(&self, cx: &mut Cx) { if let Some(mut inner) = self.borrow_mut() { + if let Some(timer) = inner.timer.take() { + cx.stop_timer(timer); + } inner.timer = None; } } From 7249787bb2bfac5f6210c6294f268a53ce70a2c1 Mon Sep 17 00:00:00 2001 From: alanpoon Date: Fri, 22 Nov 2024 11:29:29 +0800 Subject: [PATCH 03/11] typing animation changed to shader --- src/home/room_screen.rs | 2 +- src/shared/typing_animation.rs | 168 +++++++++------------------------ 2 files changed, 45 insertions(+), 125 deletions(-) diff --git a/src/home/room_screen.rs b/src/home/room_screen.rs index daced3ef..d870291c 100644 --- a/src/home/room_screen.rs +++ b/src/home/room_screen.rs @@ -1586,7 +1586,7 @@ impl RoomScreen { // Animate out the typing notice view (sliding it out towards the bottom). self.animator_play(cx, id!(typing_notice_animator.hide)); let typing_animation = self.view.typing_animation(id!(typing_animation)); - typing_animation.stop_animation(cx); + typing_animation.stop_animation(); } if num_updates > 0 { diff --git a/src/shared/typing_animation.rs b/src/shared/typing_animation.rs index cf05380f..4452fae2 100644 --- a/src/shared/typing_animation.rs +++ b/src/shared/typing_animation.rs @@ -3,78 +3,40 @@ use makepad_widgets::*; live_design! { import makepad_widgets::base::*; import makepad_widgets::theme_desktop_dark::*; - import crate::shared::styles::*; + import makepad_draw::shader::std::*; ANIMATION_DURATION = 0.65 - // 1. Set the width and height to the same value. - // 2. Set the radius to half of the width/height. - EllipsisDot = { - width: 3 - height: 3 - draw_bg: { - radius: 1.5 - color: (TYPING_NOTICE_TEXT_COLOR) - } - } - TypingAnimation = {{TypingAnimation}} { - width: Fit, - height: Fit, - + width: 24, + height: 15, flow: Down, - align: {x: 0.0, y: 0.5}, - - content = { - width: Fit, - height: Fit, - spacing: 2, - circle1 = {} - circle2 = {} - circle3 = {} - } - - animator: { - circle1 = { - default: down, - down = { - redraw: true, - from: {all: Forward {duration: (ANIMATION_DURATION * 0.5)}} - apply: {content = { circle1 = { margin: {top: 10.0} }}} - } - up = { - redraw: true, - from: {all: Forward {duration: (ANIMATION_DURATION * 0.5)}} - apply: {content = { circle1 = { margin: {top: 3.0} }}} - } - } - - circle2 = { - default: down, - down = { - redraw: true, - from: {all: Forward {duration: (ANIMATION_DURATION * 0.5)}} - apply: {content = { circle2 = { margin: {top: 10.0} }}} - } - up = { - redraw: true, - from: {all: Forward {duration: (ANIMATION_DURATION * 0.5)}} - apply: {content = { circle2 = { margin: {top: 3.0} }}} - } - } - - circle3 = { - default: down, - down = { - redraw: true, - from: {all: Forward {duration: (ANIMATION_DURATION * 0.5)}} - apply: {content = { circle3 = { margin: {top: 10.0} }}} - } - up = { - redraw: true, - from: {all: Forward {duration: (ANIMATION_DURATION * 0.5)}} - apply: {content = { circle3 = { margin: {top: 3.0} }}} - } + show_bg: true, + draw_bg: { + uniform freq: 5.0 + fn pixel(self) -> vec4 { + let sdf = Sdf2d::viewport(self.pos * self.rect_size); + let color = vec4(0.0, 0.0, 0.0, 1.0); + // // Create three circle SDFs + sdf.circle( + self.rect_size.x * 0.25, + self.rect_size.y * 0.3 * sin(self.time * self.freq) + self.rect_size.y * 0.4, + 1.6 + ); + sdf.fill(color); + sdf.circle( + self.rect_size.x * 0.5, + self.rect_size.y * 0.3 * sin(self.time * self.freq + 180.0) + self.rect_size.y * 0.4, + 1.6 + ); + sdf.fill(color); + sdf.circle( + self.rect_size.x * 0.75, + self.rect_size.y * 0.3 * sin(self.time * self.freq) + self.rect_size.y * 0.4, + 1.6 + ); + sdf.fill(color); + return sdf.result; } } } @@ -83,39 +45,20 @@ live_design! { #[derive(Live, LiveHook, Widget)] pub struct TypingAnimation { #[deref] view: View, - #[animator] animator: Animator, - - #[live(0.65)] animation_duration: f64, - #[rust] timer: Option, - #[rust] current_animated_dot: CurrentAnimatedDot, -} - -#[derive(Copy, Clone, Default)] -enum CurrentAnimatedDot { - #[default] - Dot1, - Dot2, - Dot3, -} -impl CurrentAnimatedDot { - fn next(&self) -> Self { - match self { - Self::Dot1 => Self::Dot2, - Self::Dot2 => Self::Dot3, - Self::Dot3 => Self::Dot1, - } - } + #[live] time: f32, + #[rust] next_frame: NextFrame, + #[rust] is_play: bool, } impl Widget for TypingAnimation { fn handle_event(&mut self, cx: &mut Cx, event: &Event, scope: &mut Scope) { - if let Some(timer) = self.timer { - if timer.is_event(event).is_some() { - self.update_animation(cx); - } - } - if self.animator_handle_event(cx, event).must_redraw() { + if let Some(ne) = self.next_frame.is_event(event) { + self.time = (ne.frame % 360) as f32; self.redraw(cx); + if !self.is_play { + return + } + self.next_frame = cx.new_next_frame(); } self.view.handle_event(cx, event, scope); @@ -126,42 +69,19 @@ impl Widget for TypingAnimation { } } -impl TypingAnimation { - pub fn update_animation(&mut self, cx: &mut Cx) { - self.current_animated_dot = self.current_animated_dot.next(); - - match self.current_animated_dot { - CurrentAnimatedDot::Dot1 => { - self.animator_play(cx, id!(circle1.up)); - self.animator_play(cx, id!(circle3.down)); - } - CurrentAnimatedDot::Dot2 => { - self.animator_play(cx, id!(circle1.down)); - self.animator_play(cx, id!(circle2.up)); - } - CurrentAnimatedDot::Dot3 => { - self.animator_play(cx, id!(circle2.down)); - self.animator_play(cx, id!(circle3.up)); - } - }; - - self.timer = Some(cx.start_timeout(self.animation_duration * 0.5)); - } -} impl TypingAnimationRef { + /// Starts animation of the bouncing dots. pub fn animate(&self, cx: &mut Cx) { if let Some(mut inner) = self.borrow_mut() { - inner.update_animation(cx); + inner.is_play = true; + inner.next_frame = cx.new_next_frame(); } } - - pub fn stop_animation(&self, cx: &mut Cx) { + /// Stops animation of the bouncing dots. + pub fn stop_animation(&self) { if let Some(mut inner) = self.borrow_mut() { - if let Some(timer) = inner.timer.take() { - cx.stop_timer(timer); - } - inner.timer = None; + inner.is_play = false; } } } From 5463e6669fc3f48f7efb981920c9d748b23ae7f0 Mon Sep 17 00:00:00 2001 From: alanpoon Date: Fri, 22 Nov 2024 14:13:01 +0800 Subject: [PATCH 04/11] typing_animation to wave --- src/shared/typing_animation.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shared/typing_animation.rs b/src/shared/typing_animation.rs index 4452fae2..a4bb6b98 100644 --- a/src/shared/typing_animation.rs +++ b/src/shared/typing_animation.rs @@ -26,13 +26,13 @@ live_design! { sdf.fill(color); sdf.circle( self.rect_size.x * 0.5, - self.rect_size.y * 0.3 * sin(self.time * self.freq + 180.0) + self.rect_size.y * 0.4, + self.rect_size.y * 0.3 * sin(self.time * self.freq + 90.0) + self.rect_size.y * 0.4, 1.6 ); sdf.fill(color); sdf.circle( self.rect_size.x * 0.75, - self.rect_size.y * 0.3 * sin(self.time * self.freq) + self.rect_size.y * 0.4, + self.rect_size.y * 0.3 * sin(self.time * self.freq + 180.0) + self.rect_size.y * 0.4, 1.6 ); sdf.fill(color); From 156b4e8cf40bddc0eaaaedbec790faf94cf08aca Mon Sep 17 00:00:00 2001 From: alanpoon Date: Fri, 22 Nov 2024 17:00:47 +0800 Subject: [PATCH 05/11] improve animation doc --- src/shared/typing_animation.rs | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/shared/typing_animation.rs b/src/shared/typing_animation.rs index a4bb6b98..e43d7a4a 100644 --- a/src/shared/typing_animation.rs +++ b/src/shared/typing_animation.rs @@ -5,35 +5,37 @@ live_design! { import makepad_widgets::theme_desktop_dark::*; import makepad_draw::shader::std::*; - ANIMATION_DURATION = 0.65 - TypingAnimation = {{TypingAnimation}} { width: 24, height: 15, flow: Down, show_bg: true, draw_bg: { - uniform freq: 5.0 + uniform freq: 5.0, + uniform phase_offset: 90.0, + uniform dot_radius: 1.6, fn pixel(self) -> vec4 { let sdf = Sdf2d::viewport(self.pos * self.rect_size); let color = vec4(0.0, 0.0, 0.0, 1.0); - // // Create three circle SDFs + let amplitude = self.rect_size.y * 0.3; + let center_y = self.rect_size.y * 0.4; + // Create three circle SDFs sdf.circle( self.rect_size.x * 0.25, - self.rect_size.y * 0.3 * sin(self.time * self.freq) + self.rect_size.y * 0.4, - 1.6 + amplitude * sin(self.time * self.freq) + center_y, + self.dot_radius ); sdf.fill(color); sdf.circle( self.rect_size.x * 0.5, - self.rect_size.y * 0.3 * sin(self.time * self.freq + 90.0) + self.rect_size.y * 0.4, - 1.6 + amplitude * sin(self.time * self.freq + self.phase_offset) + center_y, + self.dot_radius ); sdf.fill(color); sdf.circle( self.rect_size.x * 0.75, - self.rect_size.y * 0.3 * sin(self.time * self.freq + 180.0) + self.rect_size.y * 0.4, - 1.6 + amplitude * sin(self.time * self.freq + self.phase_offset * 2) + center_y, + self.dot_radius ); sdf.fill(color); return sdf.result; @@ -49,11 +51,11 @@ pub struct TypingAnimation { #[rust] next_frame: NextFrame, #[rust] is_play: bool, } - impl Widget for TypingAnimation { fn handle_event(&mut self, cx: &mut Cx, event: &Event, scope: &mut Scope) { if let Some(ne) = self.next_frame.is_event(event) { - self.time = (ne.frame % 360) as f32; + self.time += ne.time as f32; + self.time = (self.time.round() as u32 % 360) as f32; self.redraw(cx); if !self.is_play { return From 7a8feb217eadd59c4b865477e59fde939f297f48 Mon Sep 17 00:00:00 2001 From: alanpoon Date: Fri, 22 Nov 2024 17:02:27 +0800 Subject: [PATCH 06/11] Added documentation --- src/shared/typing_animation.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/shared/typing_animation.rs b/src/shared/typing_animation.rs index e43d7a4a..a119b828 100644 --- a/src/shared/typing_animation.rs +++ b/src/shared/typing_animation.rs @@ -11,9 +11,9 @@ live_design! { flow: Down, show_bg: true, draw_bg: { - uniform freq: 5.0, - uniform phase_offset: 90.0, - uniform dot_radius: 1.6, + uniform freq: 5.0, // Animation frequency + uniform phase_offset: 90.0, // Phase difference + uniform dot_radius: 1.6, // Dot radius fn pixel(self) -> vec4 { let sdf = Sdf2d::viewport(self.pos * self.rect_size); let color = vec4(0.0, 0.0, 0.0, 1.0); From 15be0837436425eae83c89610fee7eba39b7c331 Mon Sep 17 00:00:00 2001 From: alanpoon Date: Tue, 26 Nov 2024 12:00:48 +0800 Subject: [PATCH 07/11] Dotted animation to the right --- src/shared/typing_animation.rs | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/shared/typing_animation.rs b/src/shared/typing_animation.rs index a119b828..43e5ef6b 100644 --- a/src/shared/typing_animation.rs +++ b/src/shared/typing_animation.rs @@ -7,34 +7,44 @@ live_design! { TypingAnimation = {{TypingAnimation}} { width: 24, - height: 15, + height: 20, flow: Down, show_bg: true, draw_bg: { - uniform freq: 5.0, // Animation frequency - uniform phase_offset: 90.0, // Phase difference + uniform freq: 3.0, // Animation frequency uniform dot_radius: 1.6, // Dot radius fn pixel(self) -> vec4 { let sdf = Sdf2d::viewport(self.pos * self.rect_size); let color = vec4(0.0, 0.0, 0.0, 1.0); let amplitude = self.rect_size.y * 0.3; - let center_y = self.rect_size.y * 0.4; + let center_y = self.rect_size.y * 0.5; + // Creates dotting animation to right using Sine function + let phi = sin(self.time * self.freq); // Create three circle SDFs + if phi < 0.02 { + return sdf.result; + } sdf.circle( self.rect_size.x * 0.25, - amplitude * sin(self.time * self.freq) + center_y, + center_y, self.dot_radius ); sdf.fill(color); + if phi < 0.4 { + return sdf.result; + } sdf.circle( self.rect_size.x * 0.5, - amplitude * sin(self.time * self.freq + self.phase_offset) + center_y, + center_y, self.dot_radius ); sdf.fill(color); + if phi < 0.75 { + return sdf.result; + } sdf.circle( self.rect_size.x * 0.75, - amplitude * sin(self.time * self.freq + self.phase_offset * 2) + center_y, + center_y, self.dot_radius ); sdf.fill(color); From fab6af86c735a489deb3074e5212159a4b86a9a8 Mon Sep 17 00:00:00 2001 From: alanpoon Date: Tue, 26 Nov 2024 13:39:48 +0800 Subject: [PATCH 08/11] remove amplitude --- src/shared/typing_animation.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/shared/typing_animation.rs b/src/shared/typing_animation.rs index 43e5ef6b..4ceec686 100644 --- a/src/shared/typing_animation.rs +++ b/src/shared/typing_animation.rs @@ -16,7 +16,6 @@ live_design! { fn pixel(self) -> vec4 { let sdf = Sdf2d::viewport(self.pos * self.rect_size); let color = vec4(0.0, 0.0, 0.0, 1.0); - let amplitude = self.rect_size.y * 0.3; let center_y = self.rect_size.y * 0.5; // Creates dotting animation to right using Sine function let phi = sin(self.time * self.freq); From 3638a1cf323d7ba1a62901b9ea2d56c9baa33461 Mon Sep 17 00:00:00 2001 From: alanpoon Date: Tue, 26 Nov 2024 16:29:51 +0800 Subject: [PATCH 09/11] hole_moving typing animation --- src/shared/typing_animation.rs | 58 +++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 26 deletions(-) diff --git a/src/shared/typing_animation.rs b/src/shared/typing_animation.rs index 4ceec686..c248e427 100644 --- a/src/shared/typing_animation.rs +++ b/src/shared/typing_animation.rs @@ -13,40 +13,46 @@ live_design! { draw_bg: { uniform freq: 3.0, // Animation frequency uniform dot_radius: 1.6, // Dot radius + uniform phase_diff: 45.0, // Phase difference between dots + uniform hole_direction: -1.0 // Hole direction: negative is towards right fn pixel(self) -> vec4 { let sdf = Sdf2d::viewport(self.pos * self.rect_size); let color = vec4(0.0, 0.0, 0.0, 1.0); - let center_y = self.rect_size.y * 0.5; + let center_y = self.rect_size.y * 0.7; // Creates dotting animation to right using Sine function - let phi = sin(self.time * self.freq); + let phi1 = abs(sin( self.time * self.freq)); + let phi2 = abs(sin( self.time * self.freq + self.hole_direction * self.phase_diff)); + let phi3 = abs(sin( self.time * self.freq + 2 * self.hole_direction * self.phase_diff)); // Create three circle SDFs - if phi < 0.02 { - return sdf.result; + // The threshold slightly greater than sin(phase_diff) + // For example sin(45) will make two out of three dots appear at any time, + // hence forming hole moving towards right + if phi1 < sin(self.phase_diff) + 0.1 { + sdf.circle( + self.rect_size.x * 0.25, + center_y, + self.dot_radius + ); + sdf.fill(color); } - sdf.circle( - self.rect_size.x * 0.25, - center_y, - self.dot_radius - ); - sdf.fill(color); - if phi < 0.4 { - return sdf.result; + + if phi2 < sin(self.phase_diff) + 0.1 { + sdf.circle( + self.rect_size.x * 0.5, + center_y, + self.dot_radius + ); + sdf.fill(color); } - sdf.circle( - self.rect_size.x * 0.5, - center_y, - self.dot_radius - ); - sdf.fill(color); - if phi < 0.75 { - return sdf.result; + + if phi3 < sin(self.phase_diff) + 0.1 { + sdf.circle( + self.rect_size.x * 0.75, + center_y, + self.dot_radius + ); + sdf.fill(color); } - sdf.circle( - self.rect_size.x * 0.75, - center_y, - self.dot_radius - ); - sdf.fill(color); return sdf.result; } } From 123dd2e9a297e769db41b769c016b1f140b96771 Mon Sep 17 00:00:00 2001 From: alanpoon Date: Tue, 26 Nov 2024 21:05:11 +0800 Subject: [PATCH 10/11] lower typing animation speed --- src/shared/typing_animation.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/typing_animation.rs b/src/shared/typing_animation.rs index c248e427..01a7df35 100644 --- a/src/shared/typing_animation.rs +++ b/src/shared/typing_animation.rs @@ -11,7 +11,7 @@ live_design! { flow: Down, show_bg: true, draw_bg: { - uniform freq: 3.0, // Animation frequency + uniform freq: 2.0, // Animation frequency uniform dot_radius: 1.6, // Dot radius uniform phase_diff: 45.0, // Phase difference between dots uniform hole_direction: -1.0 // Hole direction: negative is towards right From c2ab4eecd69577e7527505507315061a317945db Mon Sep 17 00:00:00 2001 From: Kevin Boos Date: Tue, 26 Nov 2024 11:46:36 -0800 Subject: [PATCH 11/11] Restore previous animation, tweak it to fit better. Use proper text color. --- src/home/room_screen.rs | 12 +++++-- src/shared/typing_animation.rs | 65 +++++++++++++--------------------- 2 files changed, 34 insertions(+), 43 deletions(-) diff --git a/src/home/room_screen.rs b/src/home/room_screen.rs index 77ad9c48..304a481c 100644 --- a/src/home/room_screen.rs +++ b/src/home/room_screen.rs @@ -793,15 +793,21 @@ live_design! { typing_label =