mirror of
https://github.com/4yn/slidershim.git
synced 2024-11-12 00:40:49 +01:00
air leds
This commit is contained in:
parent
e0046ede81
commit
121aeadbd8
@ -183,19 +183,52 @@ button.primary {
|
|||||||
|
|
||||||
.air {
|
.air {
|
||||||
height: 2rem;
|
height: 2rem;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
border-radius: 0.5rem 0.5rem 0 0;
|
||||||
|
overflow: clip;
|
||||||
|
|
||||||
|
background: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-btn, .air-led {
|
||||||
|
height: 2rem;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
align-items: stretch;
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-led {
|
||||||
|
flex-flow: row nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-led-left, .air-led-right {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: column-reverse nowrap;
|
flex-flow: column-reverse nowrap;
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
|
flex: 1;
|
||||||
border-radius: 0.5rem 0.5rem 0 0;
|
|
||||||
overflow: clip;
|
|
||||||
}
|
}
|
||||||
.air-data {
|
.air-led-data {
|
||||||
flex: 1 0;
|
flex: 1 0;
|
||||||
}
|
}
|
||||||
.air-data-0 {
|
|
||||||
background: #000;
|
.air-led-space {
|
||||||
|
flex: 14;
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-btn {
|
||||||
|
background: #0008;
|
||||||
|
flex-flow: column-reverse nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-data {
|
||||||
|
flex: 1 0;
|
||||||
}
|
}
|
||||||
.air-data-1 {
|
.air-data-1 {
|
||||||
background: #0aa;
|
background: #0aa;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#![ allow( dead_code, unused_imports, non_upper_case_globals ) ]
|
||||||
|
|
||||||
/* automatically generated by rust-bindgen 0.54.1 */
|
/* automatically generated by rust-bindgen 0.54.1 */
|
||||||
|
|
||||||
pub const INTERCEPTION_MAX_KEYBOARD: u32 = 10;
|
pub const INTERCEPTION_MAX_KEYBOARD: u32 = 10;
|
||||||
|
@ -43,6 +43,8 @@ impl Config {
|
|||||||
"ledFaster": false,
|
"ledFaster": false,
|
||||||
"ledColorActive": "#ff00ff",
|
"ledColorActive": "#ff00ff",
|
||||||
"ledColorInactive": "#ffff00",
|
"ledColorInactive": "#ffff00",
|
||||||
|
"ledColorAirActive": "#0086ed",
|
||||||
|
"ledColorAirInactive": "#000000",
|
||||||
"ledSensitivity": 20,
|
"ledSensitivity": 20,
|
||||||
"ledWebsocketUrl": "localhost:3001",
|
"ledWebsocketUrl": "localhost:3001",
|
||||||
"ledSerialPort": "COM5"
|
"ledSerialPort": "COM5"
|
||||||
|
@ -13,6 +13,8 @@ pub enum ReactiveLayout {
|
|||||||
pub struct ColorScheme {
|
pub struct ColorScheme {
|
||||||
pub active: [u8; 3],
|
pub active: [u8; 3],
|
||||||
pub inactive: [u8; 3],
|
pub inactive: [u8; 3],
|
||||||
|
pub air_active: [u8; 3],
|
||||||
|
pub air_inactive: [u8; 3],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ColorScheme {
|
impl ColorScheme {
|
||||||
@ -28,6 +30,16 @@ impl ColorScheme {
|
|||||||
u8::from_str_radix(&v["ledColorInactive"].as_str()?[3..5], 16).ok()?,
|
u8::from_str_radix(&v["ledColorInactive"].as_str()?[3..5], 16).ok()?,
|
||||||
u8::from_str_radix(&v["ledColorInactive"].as_str()?[5..7], 16).ok()?,
|
u8::from_str_radix(&v["ledColorInactive"].as_str()?[5..7], 16).ok()?,
|
||||||
],
|
],
|
||||||
|
air_active: [
|
||||||
|
u8::from_str_radix(&v["ledColorAirActive"].as_str()?[1..3], 16).ok()?,
|
||||||
|
u8::from_str_radix(&v["ledColorAirActive"].as_str()?[3..5], 16).ok()?,
|
||||||
|
u8::from_str_radix(&v["ledColorAirActive"].as_str()?[5..7], 16).ok()?,
|
||||||
|
],
|
||||||
|
air_inactive: [
|
||||||
|
u8::from_str_radix(&v["ledColorAirInactive"].as_str()?[1..3], 16).ok()?,
|
||||||
|
u8::from_str_radix(&v["ledColorAirInactive"].as_str()?[3..5], 16).ok()?,
|
||||||
|
u8::from_str_radix(&v["ledColorAirInactive"].as_str()?[5..7], 16).ok()?,
|
||||||
|
],
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,6 +47,8 @@ impl ColorScheme {
|
|||||||
Self {
|
Self {
|
||||||
active: [255, 0, 255],
|
active: [255, 0, 255],
|
||||||
inactive: [255, 255, 0],
|
inactive: [255, 255, 0],
|
||||||
|
air_active: [0, 134, 237],
|
||||||
|
air_inactive: [0, 0, 0],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,6 +57,8 @@ impl ColorScheme {
|
|||||||
.or(Some(Self {
|
.or(Some(Self {
|
||||||
active: [255, 0, 255],
|
active: [255, 0, 255],
|
||||||
inactive: [255, 255, 0],
|
inactive: [255, 255, 0],
|
||||||
|
air_active: [0, 134, 237],
|
||||||
|
air_inactive: [0, 0, 0],
|
||||||
}))
|
}))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use log::{error, info};
|
use log::{error, info};
|
||||||
use palette::{FromColor, Hsv, Srgb};
|
use palette::{encoding::Srgb as SrgbEncoding, rgb::Rgb, FromColor, Hsv, Srgb};
|
||||||
use serialport::{ClearBuffer, SerialPort};
|
use serialport::{ClearBuffer, SerialPort};
|
||||||
use std::{
|
use std::{
|
||||||
ops::DerefMut,
|
ops::DerefMut,
|
||||||
@ -15,6 +15,22 @@ use crate::{
|
|||||||
|
|
||||||
use super::config::{LightsMode, ReactiveLayout};
|
use super::config::{LightsMode, ReactiveLayout};
|
||||||
|
|
||||||
|
fn get_rainbow(phase: f64, desaturate: bool) -> Rgb<SrgbEncoding, u8> {
|
||||||
|
let phase = ((phase % 1.0) + 1.0) % 1.0;
|
||||||
|
let color = Srgb::from_color(Hsv::new(
|
||||||
|
phase * 360.0,
|
||||||
|
match desaturate {
|
||||||
|
false => 1.0,
|
||||||
|
true => 0.2,
|
||||||
|
_ => unreachable!(),
|
||||||
|
},
|
||||||
|
1.0,
|
||||||
|
))
|
||||||
|
.into_format::<u8>();
|
||||||
|
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
pub struct LightsJob {
|
pub struct LightsJob {
|
||||||
state: SliderState,
|
state: SliderState,
|
||||||
mode: LightsMode,
|
mode: LightsMode,
|
||||||
@ -75,6 +91,16 @@ impl LightsJob {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for idx in 0..3 {
|
||||||
|
lights.paint_air(
|
||||||
|
idx,
|
||||||
|
match flat_input[32 + idx * 2] || flat_input[33 + idx * 2] {
|
||||||
|
true => &color.air_active,
|
||||||
|
false => &color.air_inactive,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ReactiveLayout::Six => {
|
ReactiveLayout::Six => {
|
||||||
let banks: Vec<bool> = [0..6, 6..10, 10..16, 16..22, 22..26, 26..32]
|
let banks: Vec<bool> = [0..6, 6..10, 10..16, 16..22, 22..26, 26..32]
|
||||||
@ -106,6 +132,16 @@ impl LightsJob {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for idx in 0..3 {
|
||||||
|
lights.paint_air(
|
||||||
|
idx,
|
||||||
|
match flat_input[32 + idx * 2] || flat_input[33 + idx * 2] {
|
||||||
|
true => &color.air_active,
|
||||||
|
false => &color.air_inactive,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ReactiveLayout::Voltex => {
|
ReactiveLayout::Voltex => {
|
||||||
lights.ground.fill(0);
|
lights.ground.fill(0);
|
||||||
@ -207,23 +243,32 @@ impl LightsJob {
|
|||||||
.elapsed()
|
.elapsed()
|
||||||
.div_duration_f64(Duration::from_secs(4))
|
.div_duration_f64(Duration::from_secs(4))
|
||||||
% 1.0;
|
% 1.0;
|
||||||
|
|
||||||
for idx in 0..31 {
|
for idx in 0..31 {
|
||||||
let slice_theta = (&theta + (idx as f64) / 32.0) % 1.0;
|
let slice_theta = theta + (idx as f64) / 32.0;
|
||||||
let color = Srgb::from_color(Hsv::new(
|
let color = get_rainbow(slice_theta, ((idx % 2) == 0) && banks[idx / 2]);
|
||||||
slice_theta * 360.0,
|
|
||||||
match idx % 2 {
|
|
||||||
0 => match banks[idx / 2] {
|
|
||||||
true => 0.2,
|
|
||||||
false => 1.0,
|
|
||||||
},
|
|
||||||
1 => 1.0,
|
|
||||||
_ => unreachable!(),
|
|
||||||
},
|
|
||||||
1.0,
|
|
||||||
))
|
|
||||||
.into_format::<u8>();
|
|
||||||
lights.paint(idx, &[color.red, color.green, color.blue]);
|
lights.paint(idx, &[color.red, color.green, color.blue]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// left
|
||||||
|
for idx in 0..3 {
|
||||||
|
let slice_theta = theta - ((idx + 1) as f64) / 32.0;
|
||||||
|
let color = get_rainbow(
|
||||||
|
slice_theta,
|
||||||
|
flat_input[32 + idx * 2] || flat_input[33 + idx * 2],
|
||||||
|
);
|
||||||
|
lights.paint_air_left(idx, &[color.red, color.green, color.blue]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// right
|
||||||
|
for idx in 0..3 {
|
||||||
|
let slice_theta = theta + (idx as f64) / 32.0;
|
||||||
|
let color = get_rainbow(
|
||||||
|
slice_theta,
|
||||||
|
flat_input[32 + idx * 2] || flat_input[33 + idx * 2],
|
||||||
|
);
|
||||||
|
lights.paint_air_right(idx, &[color.red, color.green, color.blue]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -233,11 +278,26 @@ impl LightsJob {
|
|||||||
.elapsed()
|
.elapsed()
|
||||||
.div_duration_f64(Duration::from_secs(4))
|
.div_duration_f64(Duration::from_secs(4))
|
||||||
% 1.0;
|
% 1.0;
|
||||||
|
|
||||||
for idx in 0..31 {
|
for idx in 0..31 {
|
||||||
let slice_theta = (&theta + (idx as f64) / 32.0) % 1.0;
|
let slice_theta = theta + (idx as f64) / 32.0;
|
||||||
let color = Srgb::from_color(Hsv::new(slice_theta * 360.0, 1.0, 1.0)).into_format::<u8>();
|
let color = get_rainbow(slice_theta, false);
|
||||||
lights.paint(idx, &[color.red, color.green, color.blue]);
|
lights.paint(idx, &[color.red, color.green, color.blue]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// left
|
||||||
|
for idx in 0..3 {
|
||||||
|
let slice_theta = theta - ((idx + 1) as f64) / 32.0;
|
||||||
|
let color = get_rainbow(slice_theta, false);
|
||||||
|
lights.paint_air_left(idx, &[color.red, color.green, color.blue]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// right
|
||||||
|
for idx in 0..3 {
|
||||||
|
let slice_theta = theta + (idx as f64) / 32.0;
|
||||||
|
let color = get_rainbow(slice_theta, false);
|
||||||
|
lights.paint_air_right(idx, &[color.red, color.green, color.blue]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
LightsMode::Serial { .. } => {
|
LightsMode::Serial { .. } => {
|
||||||
// https://github.com/jmontineri/OpeNITHM/blob/89e9a43f7484e8949cd31bbff79c32f21ea3ec1d/Firmware/OpeNITHM/SerialProcessor.h
|
// https://github.com/jmontineri/OpeNITHM/blob/89e9a43f7484e8949cd31bbff79c32f21ea3ec1d/Firmware/OpeNITHM/SerialProcessor.h
|
||||||
|
@ -108,6 +108,12 @@ async fn handle_umgr_leds(ws_stream: WebSocketStream<Upgraded>, state: SliderSta
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for i in 0..3 {
|
||||||
|
let pos = 94 + i * 3;
|
||||||
|
lights_handle
|
||||||
|
.paint_air(2 - i, &[payload[pos], payload[pos + 1], payload[pos + 2]]);
|
||||||
|
}
|
||||||
|
|
||||||
if latest_lights.elapsed() > delay {
|
if latest_lights.elapsed() > delay {
|
||||||
lights_handle.dirty = true;
|
lights_handle.dirty = true;
|
||||||
latest_lights = Instant::now();
|
latest_lights = Instant::now();
|
||||||
|
@ -61,6 +61,10 @@ pub struct SliderLights {
|
|||||||
/// right. Alternates between 16 touch pad pixels and 15 divider pixels.
|
/// right. Alternates between 16 touch pad pixels and 15 divider pixels.
|
||||||
pub ground: [u8; 3 * 31],
|
pub ground: [u8; 3 * 31],
|
||||||
|
|
||||||
|
// RGB light values for left and right air sensors, bottom to top
|
||||||
|
pub air_left: [u8; 3 * 3],
|
||||||
|
pub air_right: [u8; 3 * 3],
|
||||||
|
|
||||||
/// Internal dirty flag used to indicate that new lighting data is available.
|
/// Internal dirty flag used to indicate that new lighting data is available.
|
||||||
pub dirty: bool,
|
pub dirty: bool,
|
||||||
|
|
||||||
@ -73,6 +77,8 @@ impl SliderLights {
|
|||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
ground: [0; 3 * 31],
|
ground: [0; 3 * 31],
|
||||||
|
air_left: [0; 3 * 3],
|
||||||
|
air_right: [0; 3 * 3],
|
||||||
dirty: false,
|
dirty: false,
|
||||||
start: Instant::now(),
|
start: Instant::now(),
|
||||||
}
|
}
|
||||||
@ -83,8 +89,23 @@ impl SliderLights {
|
|||||||
self.ground[3 * idx..3 * (idx + 1)].copy_from_slice(color);
|
self.ground[3 * idx..3 * (idx + 1)].copy_from_slice(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn paint_air(&mut self, idx: usize, color: &[u8; 3]) {
|
||||||
|
self.air_left[3 * idx..3 * (idx + 1)].copy_from_slice(color);
|
||||||
|
self.air_right[3 * idx..3 * (idx + 1)].copy_from_slice(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn paint_air_left(&mut self, idx: usize, color: &[u8; 3]) {
|
||||||
|
self.air_left[3 * idx..3 * (idx + 1)].copy_from_slice(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn paint_air_right(&mut self, idx: usize, color: &[u8; 3]) {
|
||||||
|
self.air_right[3 * idx..3 * (idx + 1)].copy_from_slice(color);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn reset(&mut self) {
|
pub fn reset(&mut self) {
|
||||||
self.ground.fill(0);
|
self.ground.fill(0);
|
||||||
|
self.air_left.fill(0);
|
||||||
|
self.air_right.fill(0);
|
||||||
self.dirty = true;
|
self.dirty = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -122,6 +143,8 @@ impl SliderState {
|
|||||||
{
|
{
|
||||||
let lights_handle = self.lights.lock();
|
let lights_handle = self.lights.lock();
|
||||||
buf.extend(lights_handle.ground);
|
buf.extend(lights_handle.ground);
|
||||||
|
buf.extend(lights_handle.air_left);
|
||||||
|
buf.extend(lights_handle.air_right);
|
||||||
};
|
};
|
||||||
|
|
||||||
buf
|
buf
|
||||||
|
@ -21,6 +21,8 @@
|
|||||||
let ledFaster = false;
|
let ledFaster = false;
|
||||||
let ledColorActive = "#ff00ff";
|
let ledColorActive = "#ff00ff";
|
||||||
let ledColorInactive = "#ffff00";
|
let ledColorInactive = "#ffff00";
|
||||||
|
let ledColorAirActive = "#0086ed";
|
||||||
|
let ledColorAirInactive = "#000000";
|
||||||
let ledSensitivity = 20;
|
let ledSensitivity = 20;
|
||||||
let ledWebsocketUrl = "http://localhost:3001";
|
let ledWebsocketUrl = "http://localhost:3001";
|
||||||
let ledUmgrWebsocketPort = 7124;
|
let ledUmgrWebsocketPort = 7124;
|
||||||
@ -77,6 +79,8 @@
|
|||||||
ledFaster = payload.ledFaster || false;
|
ledFaster = payload.ledFaster || false;
|
||||||
ledColorActive = payload.ledColorActive || "#ff00ff";
|
ledColorActive = payload.ledColorActive || "#ff00ff";
|
||||||
ledColorInactive = payload.ledColorInactive || "#ffff00";
|
ledColorInactive = payload.ledColorInactive || "#ffff00";
|
||||||
|
ledColorAirActive = payload.ledColorAirActive || "#0086ed";
|
||||||
|
ledColorAirInactive = payload.ledColorAirInactive || "#000000";
|
||||||
ledSensitivity = payload.ledSensitivity || 20;
|
ledSensitivity = payload.ledSensitivity || 20;
|
||||||
ledWebsocketUrl = payload.ledWebsocketUrl || "http://localhost:3001";
|
ledWebsocketUrl = payload.ledWebsocketUrl || "http://localhost:3001";
|
||||||
ledUmgrWebsocketPort = payload.ledUmgrWebsocketPort || 7124;
|
ledUmgrWebsocketPort = payload.ledUmgrWebsocketPort || 7124;
|
||||||
@ -133,6 +137,8 @@
|
|||||||
ledFaster,
|
ledFaster,
|
||||||
ledColorActive,
|
ledColorActive,
|
||||||
ledColorInactive,
|
ledColorInactive,
|
||||||
|
ledColorAirActive,
|
||||||
|
ledColorAirInactive,
|
||||||
ledSensitivity,
|
ledSensitivity,
|
||||||
ledWebsocketUrl,
|
ledWebsocketUrl,
|
||||||
ledUmgrWebsocketPort,
|
ledUmgrWebsocketPort,
|
||||||
@ -470,23 +476,53 @@
|
|||||||
{/if}
|
{/if}
|
||||||
{#if ledMode.slice(0, 8) === "reactive" && ["16", "8", "6", "4"].includes(ledMode.slice(9))}
|
{#if ledMode.slice(0, 8) === "reactive" && ["16", "8", "6", "4"].includes(ledMode.slice(9))}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="label">Active Color</div>
|
<div class="label">Slider Color</div>
|
||||||
<div class="input">
|
<div class="input">
|
||||||
|
<span>
|
||||||
<input
|
<input
|
||||||
type="color"
|
type="color"
|
||||||
|
id="color-active"
|
||||||
|
style="width: 3rem;"
|
||||||
bind:value={ledColorActive}
|
bind:value={ledColorActive}
|
||||||
on:change={markDirty}
|
on:change={markDirty}
|
||||||
/>
|
/>
|
||||||
</div>
|
<label for="color-active">Active</label>
|
||||||
</div>
|
</span>
|
||||||
<div class="row">
|
<span>
|
||||||
<div class="label">Base Color</div>
|
|
||||||
<div class="input">
|
|
||||||
<input
|
<input
|
||||||
type="color"
|
type="color"
|
||||||
|
id="color-base"
|
||||||
|
style="width: 3rem;"
|
||||||
bind:value={ledColorInactive}
|
bind:value={ledColorInactive}
|
||||||
on:change={markDirty}
|
on:change={markDirty}
|
||||||
/>
|
/>
|
||||||
|
<label for="color-base">Inactive</label>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="label">Air Color</div>
|
||||||
|
<div class="input">
|
||||||
|
<span>
|
||||||
|
<input
|
||||||
|
type="color"
|
||||||
|
id="color-active"
|
||||||
|
style="width: 3rem;"
|
||||||
|
bind:value={ledColorAirActive}
|
||||||
|
on:change={markDirty}
|
||||||
|
/>
|
||||||
|
<label for="color-active">Active</label>
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
<input
|
||||||
|
type="color"
|
||||||
|
id="color-base"
|
||||||
|
style="width: 3rem;"
|
||||||
|
bind:value={ledColorAirInactive}
|
||||||
|
on:change={markDirty}
|
||||||
|
/>
|
||||||
|
<label for="color-base">Inactive</label>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -8,9 +8,11 @@
|
|||||||
|
|
||||||
let ledDatas = Array(16).fill("#ff0");
|
let ledDatas = Array(16).fill("#ff0");
|
||||||
let ledDividerDatas = Array(15).fill("#ff0");
|
let ledDividerDatas = Array(15).fill("#ff0");
|
||||||
|
let airLedLeftDatas = Array(3).fill(0);
|
||||||
|
let airLedRightDatas = Array(3).fill(0);
|
||||||
|
|
||||||
$: {
|
$: {
|
||||||
if (data.length === 134) {
|
if (data.length === 152) {
|
||||||
// console.log(data);
|
// console.log(data);
|
||||||
for (let i = 0; i < 16; i++) {
|
for (let i = 0; i < 16; i++) {
|
||||||
topDatas[i] = data[i * 2 + 1];
|
topDatas[i] = data[i * 2 + 1];
|
||||||
@ -33,16 +35,43 @@
|
|||||||
ledDividerDatas[(i - 1) / 2] = rgbstr;
|
ledDividerDatas[(i - 1) / 2] = rgbstr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (let i = 0; i < 3; i++) {
|
||||||
|
let rgbstr = `rgb(${data[134 + i * 3]}, ${data[135 + i * 3]}, ${
|
||||||
|
data[136 + i * 3]
|
||||||
|
})`;
|
||||||
|
airLedLeftDatas[i] = rgbstr;
|
||||||
|
}
|
||||||
|
for (let i = 0; i < 3; i++) {
|
||||||
|
let rgbstr = `rgb(${data[143 + i * 3]}, ${data[144 + i * 3]}, ${
|
||||||
|
data[145 + i * 3]
|
||||||
|
})`;
|
||||||
|
airLedRightDatas[i] = rgbstr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<main class="preview">
|
<main class="preview">
|
||||||
<div class="air">
|
<div class="air">
|
||||||
|
<div class="air-led">
|
||||||
|
<div class="air-led-left">
|
||||||
|
{#each airLedLeftDatas as airLedData, idx (idx)}
|
||||||
|
<div class="air-led-data" style={`background-color: ${airLedData}`} />
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
<div class="air-led-space" />
|
||||||
|
<div class="air-led-right">
|
||||||
|
{#each airLedRightDatas as airLedData, idx (idx)}
|
||||||
|
<div class="air-led-data" style={`background-color: ${airLedData}`} />
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="air-btn">
|
||||||
{#each airDatas as airData, idx (idx)}
|
{#each airDatas as airData, idx (idx)}
|
||||||
<div class={`air-data air-data-${airData}`} />
|
<div class={`air-data air-data-${airData}`} />
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<div class="ground">
|
<div class="ground">
|
||||||
<div class="ground-led">
|
<div class="ground-led">
|
||||||
<div class="ground-row">
|
<div class="ground-row">
|
||||||
|
Loading…
Reference in New Issue
Block a user