feat: 测试灯效,流光溢彩

This commit is contained in:
2022-11-23 00:36:28 +08:00
parent f7b290dcbf
commit a9394bd73c
11 changed files with 139 additions and 36 deletions

7
src-tauri/Cargo.lock generated
View File

@ -306,6 +306,12 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
[[package]]
name = "color_space"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3776b2bcc4e914db501bb9be9572dd706e344b9eb8f882894f3daa651d281381"
[[package]]
name = "combine"
version = "4.6.6"
@ -2458,6 +2464,7 @@ dependencies = [
"anyhow",
"base64",
"bmp",
"color_space",
"hex",
"once_cell",
"paris",

View File

@ -30,6 +30,7 @@ tracing-subscriber = "0.3.16"
hex = "0.4.3"
rumqttc = "0.17.0"
time = { version = "0.3.17", features = ["formatting"] }
color_space = "0.5.3"
[features]
# by default Tauri runs in production mode

View File

@ -0,0 +1,51 @@
use once_cell::sync::OnceCell;
use paris::info;
use std::{sync::Arc, time::Duration};
use tokio::{sync::Mutex, time::sleep};
use tracing::warn;
use crate::{picker::led_color::LedColor, rpc};
pub struct CoreManager {
flowing_light_mode: Arc<Mutex<bool>>,
}
impl CoreManager {
pub fn global() -> &'static CoreManager {
static CORE_MANAGER: OnceCell<CoreManager> = OnceCell::new();
CORE_MANAGER.get_or_init(|| CoreManager {
flowing_light_mode: Arc::new(Mutex::new(false)),
})
}
pub async fn play_flowing_light(&self) {
*self.flowing_light_mode.lock().await = true;
let mut hue = 0f64;
let step_length = 2.0;
while self.flowing_light_mode.lock().await.to_owned() {
let mut colors = Vec::<LedColor>::new();
for i in 0..60 {
let color = LedColor::from_hsv((hue + i as f64 * step_length) % 360.0, 1.0, 0.5);
colors.push(color);
}
hue = (hue + 1.0) % 360.0;
match rpc::manager::Manager::global()
.publish_led_colors(&colors)
.await
{
Ok(_) => {}
Err(error) => {
warn!("publish led colors failed. {}", error);
}
}
sleep(Duration::from_millis(10)).await;
}
}
pub async fn stop_flowing_light(&self) {
let mut mode = self.flowing_light_mode.lock().await;
*mode = false;
}
}

View File

@ -0,0 +1,3 @@
mod core;
pub use self::core::*;

View File

@ -3,15 +3,15 @@
windows_subsystem = "windows"
)]
mod core;
mod picker;
mod rpc;
use paris::*;
use picker::led_color::LedColor;
use picker::manager::Picker;
use std::{
time::Instant,
};
use crate::core::CoreManager;
use std::time::Instant;
#[tauri::command]
async fn refresh_displays() {
@ -59,26 +59,13 @@ async fn get_led_strip_colors() -> Result<Vec<LedColor>, String> {
}
}
async fn bitmap_to_webp_base64(width: usize, height: usize, bitmap: Vec<u8>) -> String {
let mut bitflipped = Vec::with_capacity(width * height * 3);
let stride = bitmap.len() / height;
// let mut img = Image::new(w as u32, h as u32);
for y in 0..height {
for x in 0..width {
let i = stride * y + 4 * x;
bitflipped.extend_from_slice(&[bitmap[i + 2], bitmap[i + 1], bitmap[i]]);
// img.set_pixel(
// x as u32,
// y as u32,
// Pixel::new(buffer[i + 2], buffer[i + 1], buffer[i]),
// );
}
}
let webp_memory =
webp::Encoder::from_rgb(bitflipped.as_slice(), width as u32, height as u32).encode(100.0);
return base64::encode(&*webp_memory);
#[tauri::command]
async fn play_flowing_light() {
CoreManager::global().play_flowing_light().await;
}
#[tauri::command]
async fn stop_flowing_light() {
CoreManager::global().stop_flowing_light().await;
}
#[tokio::main]
@ -88,7 +75,9 @@ async fn main() {
.invoke_handler(tauri::generate_handler![
take_snapshot,
refresh_displays,
get_led_strip_colors
get_led_strip_colors,
play_flowing_light,
stop_flowing_light,
])
.run(tauri::generate_context!())
.expect("error while running tauri application");

View File

@ -1,3 +1,4 @@
use color_space::{Hsv, Rgb};
use paris::info;
use serde::Serialize;
@ -15,6 +16,33 @@ impl LedColor {
Self { bits: [r, g, b] }
}
pub fn from_hsv(h: f64, s: f64, v: f64) -> Self {
let rgb = Rgb::from(Hsv::new(h, s, v));
// let h = h % 360;
// let rgb_max = v * 255.0;
// let rgb_min = rgb_max * (1.0 - s as f32);
// let i = h / 60;
// let diff = h % 60;
// let rgb_adj = (rgb_max - rgb_min) * diff as f32 / 60.0;
// let bits: [u8; 3] = if i == 0 {
// [rgb_max as u8, (rgb_min + rgb_adj) as u8, rgb_min as u8]
// } else if i == 1 {
// [(rgb_max - rgb_adj) as u8, rgb_max as u8, rgb_min as u8]
// } else if i == 2 {
// [rgb_min as u8, rgb_max as u8, (rgb_min + rgb_adj) as u8]
// } else if i == 3 {
// [rgb_min as u8, (rgb_max - rgb_adj) as u8, rgb_max as u8]
// } else if i == 4 {
// [(rgb_min + rgb_adj) as u8, rgb_min as u8, rgb_max as u8]
// } else {
// [rgb_max as u8, rgb_min as u8, (rgb_max - rgb_adj) as u8]
// };
Self { bits: [rgb.r as u8, rgb.g as u8, rgb.b as u8] }
}
pub fn get_rgb(&self) -> [u8; 3] {
self.bits
}
@ -43,7 +71,6 @@ impl Serialize for LedColor {
where
S: serde::Serializer,
{
info!("{:?}", self.bits);
let hex = format!("#{}", hex::encode(self.bits));
serializer.serialize_str(hex.as_str())
}

View File

@ -2,6 +2,7 @@ use crate::picker::led_color::LedColor;
use super::mqtt::MqttConnection;
use once_cell::sync::OnceCell;
use paris::info;
pub struct Manager {
mqtt: MqttConnection,

View File

@ -27,9 +27,9 @@ impl MqttConnection {
self.broadcast_desktop_online();
}
fn subscribe_board(&self) {
async fn subscribe_board(&self) {
self.client
.subscribe("screen-bg-light/board/#", QoS::AtMostOnce);
.subscribe("screen-bg-light/board/#", QoS::AtMostOnce).await;
}
fn broadcast_desktop_online(&mut self) {