From 8295f835b569e8468dca2cc15a21fb51b2839c5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20Vald=C3=A9s?= Date: Thu, 20 Feb 2020 21:50:51 +0100 Subject: [PATCH] Fixed a few bugs, implemented cursor VFX on state change --- src/renderer/cursor_renderer.rs | 72 +++++++++++++++++++++++++++------ 1 file changed, 59 insertions(+), 13 deletions(-) diff --git a/src/renderer/cursor_renderer.rs b/src/renderer/cursor_renderer.rs index b483b4c..18aa751 100644 --- a/src/renderer/cursor_renderer.rs +++ b/src/renderer/cursor_renderer.rs @@ -1,6 +1,6 @@ use std::time::{Duration, Instant}; -use skulpin::skia_safe::{Canvas, Paint, Path, Point}; +use skulpin::skia_safe::{BlendMode, Canvas, Color, Paint, Path, Point, Rect}; use crate::settings::SETTINGS; use crate::renderer::animation_utils::*; @@ -9,9 +9,8 @@ use crate::editor::{EDITOR, Colors, Cursor, CursorShape}; use crate::redraw_scheduler::REDRAW_SCHEDULER; - const BASE_ANIMATION_LENGTH_SECONDS: f32 = 0.06; -const CURSOR_TRAIL_SIZE: f32 = 0.6; +const CURSOR_TRAIL_SIZE: f32 = 0.9; const COMMAND_LINE_DELAY_FRAMES: u64 = 5; const DEFAULT_CELL_PERCENTAGE: f32 = 1.0 / 8.0; @@ -151,10 +150,10 @@ impl Corner { d }; - let direction_alignment = corner_direction.dot(self.relative_position); + let direction_alignment = -corner_direction.dot(self.relative_position); // TODO -- Fix math below so this doesn't have to be negated self.current_position = - ease_point(ease_linear, self.start_position, corner_destination, self.t); + ease_point(ease_out_quad, self.start_position, corner_destination, self.t); if self.t == 1.0 { // We are at destination, move t out of 0-1 range to stop the animation @@ -168,12 +167,52 @@ impl Corner { } } +// TODO -- Split into own file, make it a trait to have several impls +// TODO -- Rename this impl as SonicBoom +pub struct CursorVFX { + t: f32, + center_position: Point, +} + +impl CursorVFX { + fn update(&mut self, dt: f32) -> bool { + self.t = (self.t + dt * 5.0).min(1.0); // TODO - speed config + return self.t < 1.0 + } + + fn reset(&mut self, position: Point) { + self.t = 0.0; + self.center_position = position; + } + + fn render(&self, _paint: &mut Paint, canvas: &mut Canvas, cursor: &Cursor, colors: &Colors) { + if self.t == 1.0 { + return; + } + let mut paint = Paint::new(skulpin::skia_safe::colors::WHITE, None); + paint.set_blend_mode(BlendMode::SrcOver); + + let base_color : Color = cursor.background(&colors).to_color(); + let alpha = ((1.0 - self.t) * 255.0) as u8; + let color = Color::from_argb(alpha, base_color.r(), base_color.g(), base_color.b()); + paint.set_color(color); + + let size = 40.0; // TODO -- Compute from font size + let radius = self.t * size; + let hr = radius * 0.5; + let rect = Rect::from_xywh(self.center_position.x - hr, self.center_position.y - hr, radius, radius); + + canvas.draw_oval(&rect, &paint); + } +} + pub struct CursorRenderer { pub corners: Vec, pub previous_position: (u64, u64), pub command_line_delay: u64, blink_status: BlinkStatus, previous_cursor_shape: Option, + cursor_vfx: CursorVFX, } impl CursorRenderer { @@ -184,19 +223,13 @@ impl CursorRenderer { command_line_delay: 0, blink_status: BlinkStatus::new(), previous_cursor_shape: None, + cursor_vfx: CursorVFX{t: 0.0, center_position: Point{x:0.0, y:0.0}}, }; renderer.set_cursor_shape(&CursorShape::Block, DEFAULT_CELL_PERCENTAGE); renderer } fn set_cursor_shape(&mut self, cursor_shape: &CursorShape, cell_percentage: f32) { - let new_cursor = Some(cursor_shape.clone()); - if self.previous_cursor_shape == new_cursor { - return; - } - - self.previous_cursor_shape = new_cursor; - self.corners = self.corners .clone() .into_iter().enumerate() @@ -229,6 +262,8 @@ impl CursorRenderer { canvas: &mut Canvas) { let render = self.blink_status.update_status(&cursor); + paint.set_anti_alias(true); + self.previous_position = { let editor = EDITOR.lock(); let (_, grid_y) = cursor.position; @@ -246,6 +281,7 @@ impl CursorRenderer { cursor.position } }; + let (grid_x, grid_y) = self.previous_position; @@ -270,7 +306,14 @@ impl CursorRenderer { let destination: Point = (grid_x as f32 * font_width, grid_y as f32 * font_height).into(); let center_destination = destination + font_dimensions * 0.5; - self.set_cursor_shape(&cursor.shape, cursor.cell_percentage.unwrap_or(DEFAULT_CELL_PERCENTAGE)); + let new_cursor = Some(cursor.shape.clone()); + + if self.previous_cursor_shape != new_cursor { + self.previous_cursor_shape = new_cursor; + self.set_cursor_shape(&cursor.shape, cursor.cell_percentage.unwrap_or(DEFAULT_CELL_PERCENTAGE)); + + self.cursor_vfx.reset(center_destination); + } let dt = 1.0 / (SETTINGS.get("refresh_rate").read_u16() as f32); @@ -280,6 +323,8 @@ impl CursorRenderer { let corner_animating = corner.update(font_dimensions, center_destination, dt); animating |= corner_animating; } + let vfx_animating = self.cursor_vfx.update(dt); + animating |= vfx_animating; } if animating || self.command_line_delay != 0 { @@ -310,6 +355,7 @@ impl CursorRenderer { canvas.draw_text_blob(&blob, destination, &paint); } canvas.restore(); + self.cursor_vfx.render(paint, canvas, &cursor, &default_colors); } } }