Skip to content

Commit

Permalink
Add perfect cursors crate
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasmerlin committed Mar 11, 2024
1 parent 41b4b72 commit 9db6b26
Show file tree
Hide file tree
Showing 6 changed files with 404 additions and 18 deletions.
43 changes: 25 additions & 18 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions crates/perfect_cursors/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[package]
name = "perfect_cursors"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
web-time = "1"

[dev-dependencies]
eframe = "0.26.2"
3 changes: 3 additions & 0 deletions crates/perfect_cursors/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# perfect_cursors

Rust port of [perfect-cursors](https://github.com/steveruizok/perfect-cursors) from Steve Ruiz.
112 changes: 112 additions & 0 deletions crates/perfect_cursors/examples/perfect_cursors_egui.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
use std::time::{Duration, Instant};

use eframe::egui::{CentralPanel, Pos2, Vec2};
use eframe::{egui, NativeOptions};

use perfect_cursors::PerfectCursor;

struct CursorSim {
delay: Duration,
last_time: Instant,
cursor: PerfectCursor,
offset: Vec2,
next_point: Option<Pos2>,
received_point: Option<Pos2>,
last_point: Option<Pos2>,
}

pub fn main() -> eframe::Result<()> {
let mut cursors = vec![
CursorSim {
delay: Duration::from_millis(80),
last_time: Instant::now(),
cursor: PerfectCursor::new(),
offset: Vec2::new(60.0, 0.0),
next_point: None,
received_point: None,
last_point: None,
},
CursorSim {
delay: Duration::from_millis(160),
last_time: Instant::now(),
cursor: PerfectCursor::new(),
offset: Vec2::new(120.0, 0.0),
next_point: None,
received_point: None,
last_point: None,
},
CursorSim {
delay: Duration::from_millis(250),
last_time: Instant::now(),
cursor: PerfectCursor::new(),
offset: Vec2::new(180.0, 0.0),
next_point: None,
received_point: None,
last_point: None,
},
];

let mut show_update_events = false;
let mut use_perfect_cursors = true;

eframe::run_simple_native(
"Perfect Cursors Egui Example",
NativeOptions::default(),
move |ctx, _frame| {
CentralPanel::default().show(ctx, |ui| {
ui.horizontal(|ui| {
ui.checkbox(&mut show_update_events, "Show update events");
ui.checkbox(&mut use_perfect_cursors, "Use Perfect Cursors");
});

cursors.iter_mut().for_each(|cursor| {
if cursor.last_time.elapsed() > cursor.delay {
cursor.last_time = Instant::now();

if let Some(next) = cursor.next_point.take() {
if use_perfect_cursors {
cursor.cursor.add_point(next.into());
} else {
cursor.received_point = Some(next);
}
if show_update_events {
ui.painter().circle(
next + cursor.offset,
15.0,
egui::Color32::BLUE,
egui::Stroke::new(1.0, egui::Color32::WHITE),
);
}
}

if let Some(pos) = ui.input(|i| i.pointer.hover_pos()) {
if cursor.last_point != Some(pos) {
cursor.next_point = Some(pos);
}
cursor.last_point = Some(pos);
}
}
});

for cursor in &mut cursors {
let current_pos = if use_perfect_cursors {
cursor.cursor.tick().map(|p| p.into())
} else {
cursor.received_point
};

if let Some(pos) = current_pos {
ui.painter().circle(
pos + cursor.offset,
10.0,
egui::Color32::RED,
egui::Stroke::new(1.0, egui::Color32::WHITE),
);
}

ui.ctx().request_repaint();
}
});
},
)
}
Loading

0 comments on commit 9db6b26

Please sign in to comment.