animate interpolate

This commit is contained in:
Alex Janka 2024-07-24 15:14:10 +10:00
parent 54abb1756b
commit 981501613a
3 changed files with 68 additions and 3 deletions

7
Cargo.lock generated
View file

@ -273,6 +273,12 @@ version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
[[package]]
name = "lab"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf36173d4167ed999940f804952e6b08197cae5ad5d572eb4db150ce8ad5d58f"
[[package]]
name = "libc"
version = "0.2.155"
@ -560,6 +566,7 @@ name = "sway-flash-indicator"
version = "0.1.0"
dependencies = [
"futures-util",
"lab",
"log",
"pretty_env_logger",
"swayipc-async",

View file

@ -9,3 +9,4 @@ pretty_env_logger = "0.5.0"
swayipc-async = "2.0.3"
tokio = { version = "1.39.1", features = ["full"] }
futures-util = "0.3.30"
lab = "0.11.0"

View file

@ -1,4 +1,17 @@
use futures_util::StreamExt;
use lab::Lab;
const INTERPOLATE_FROM: Lab = Lab {
l: 53.2,
a: 80.1,
b: 67.2,
};
const FRAMES_DELAY: u32 = 5;
const FRAMES_ANIM: u32 = 20;
const REFRESH_RATE: u64 = 60;
const DUR_PER_FRAME: std::time::Duration = std::time::Duration::from_millis(1000 / REFRESH_RATE);
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
@ -7,16 +20,27 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
}
pretty_env_logger::init();
let connection = swayipc_async::Connection::new().await?;
let mut events = connection
let event_connection = swayipc_async::Connection::new().await?;
let mut events = event_connection
.subscribe([swayipc_async::EventType::Binding])
.await?;
let mut fut: Option<tokio::task::JoinHandle<()>> = None;
while let Some(event) = events.next().await {
if let Ok(event) = event {
match event {
swayipc_async::Event::Binding(swayipc_async::BindingEvent { binding, .. }) => {
if binding.command.starts_with("split") {
log::info!("split change");
if let Some(fut) = fut.take() {
fut.abort();
}
fut = Some(tokio::spawn(async {
if let Err(e) = interpolate_task().await {
log::warn!("error {e:?}");
}
}));
}
}
_ => unreachable!(),
@ -26,3 +50,36 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
Ok(())
}
async fn interpolate_task() -> Result<(), Box<dyn std::error::Error>> {
let mut connection = swayipc_async::Connection::new().await?;
let to = Lab::from_rgb(&[0x88, 0xc0, 0xd0]);
let per_frame = 1.0 / FRAMES_ANIM as f32;
let (d_l, d_a, d_b) = (
(to.l - INTERPOLATE_FROM.l) * per_frame,
(to.a - INTERPOLATE_FROM.a) * per_frame,
(to.b - INTERPOLATE_FROM.b) * per_frame,
);
let mut c = INTERPOLATE_FROM;
connection.run_command(set_command(&c)).await?;
tokio::time::sleep(DUR_PER_FRAME * FRAMES_DELAY).await;
for _ in 0..FRAMES_ANIM {
c.l += d_l;
c.a += d_a;
c.b += d_b;
connection.run_command(set_command(&c)).await?;
tokio::time::sleep(DUR_PER_FRAME).await;
}
connection
.run_command("client.focused #000000 #88c0d0 #000000 #88c0d0")
.await?;
Ok(())
}
fn set_command(colour: &Lab) -> String {
let [r, g, b] = colour.to_rgb();
format!("client.focused #000000 #88c0d0 #000000 #{r:02x}{g:02x}{b:02x}")
}