From c2ef71ed9215eae0c7e7a20a4e981138c21ba6e4 Mon Sep 17 00:00:00 2001 From: Gergely Polonkai Date: Tue, 17 May 2022 17:23:26 +0200 Subject: [PATCH] Add the current Moon phase in the middle --- Cargo.lock | 7 ++++++ Cargo.toml | 1 + src/main.rs | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 71 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 8b96e66..d860cf8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -491,6 +491,12 @@ dependencies = [ "wayland-protocols", ] +[[package]] +name = "suncalc" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830c44c596fd2dfa93ad514462622e014c3e58e5d7e6844a87f7d510e8e68045" + [[package]] name = "svg" version = "0.10.0" @@ -730,6 +736,7 @@ dependencies = [ "chrono", "resvg", "smithay-client-toolkit", + "suncalc", "svg", "tiny-skia", "usvg", diff --git a/Cargo.toml b/Cargo.toml index 150698c..868a14f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,3 +10,4 @@ svg = "0.10" usvg = "0.22" tiny-skia = "0.6" resvg = "0.22" +suncalc = "0.4" diff --git a/src/main.rs b/src/main.rs index 00f2e51..ef24593 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,7 +7,8 @@ use chrono::Timelike; use sctk::reexports::client::protocol::{wl_shm, wl_surface}; use sctk::shm::AutoMemPool; use sctk::window::{Event as WEvent, FallbackFrame}; -use svg::node::element::{Group, Line, Rectangle, Style, Text}; +use svg::node::element::path::Data as PathData; +use svg::node::element::{Circle, Group, Line, Path, Rectangle, Style, Text}; use svg::node::Text as TextNode; use svg::Document; @@ -22,6 +23,46 @@ fn time_to_degrees(timestamp: i32, // should be time/timestamp seconds_to_degrees(timestamp) } +fn get_moon_path(image_width: u32, radius: f32, moon_phase: f64) -> Path { + let handle_x_pos = radius as f64 * 1.34; + let handle_y_pos = radius * 0.88; + let min_x = image_width as f64 / 2.0 - handle_x_pos; + let max_x = min_x + 2.0 * handle_x_pos; + let top_y = image_width as f32 / 2.0 - handle_y_pos; + let bottom_y = image_width as f32 / 2.0 + handle_y_pos; + + let h1_x: f64; + let h2_x: f64; + + if moon_phase < 14.0 { + h1_x = min_x + 2.0 * handle_x_pos * (1.0 - moon_phase / 14.0); + h2_x = max_x; + } else { + h1_x = min_x; + h2_x = max_x + 2.0 * handle_x_pos * (1.0 - moon_phase / 14.0) + } + + let path_data = PathData::new() + .move_to((image_width as f32 / 2.0, image_width as f32 / 2.0 - radius)) + .cubic_curve_to(( + h1_x, + top_y, + h1_x, + bottom_y, + image_width as f32 / 2.0, + image_width as f32 / 2.0 + radius, + )) + .cubic_curve_to(( + h2_x, + bottom_y, + h2_x, + top_y, + image_width / 2, + image_width as f32 / 2.0 - radius, + )); + Path::new().set("class", "moon").set("d", path_data) +} + fn gen_svg() -> Document { // These should be calculated let local_timestamp = Local::now(); @@ -29,6 +70,13 @@ fn gen_svg() -> Document { // TODO: These should be calculated instead of hardcoded let image_width = 700u32; + + // Calculate the Moon phase + let unixtime = suncalc::Timestamp(local_timestamp.timestamp_millis()); + let moon_illumination = suncalc::moon_illumination(unixtime); + let moon_radius = image_width as f32 * 0.071428571; + let moon_phase = moon_illumination.phase * 28.0; + let local_hour_font_size = 16.5; let hour_name_font_size = 13.37699; let outer_r = (image_width as f32) / 2.0 - 3.0 * hour_name_font_size; @@ -43,6 +91,8 @@ fn gen_svg() -> Document { "\ #border {stroke: none; fill: rgb(19, 17, 30); } .local-hour {stroke: none; fill: rgb(238, 187, 85);} + .moon-background {stroke: rgb(170, 170, 170); stroke-width: 2px; fill: rgb(19, 17, 30);} + .moon {stroke: none; fill: rgb(170, 170, 170);} .dial {stroke-width: 2px; stroke: rgb(238, 187, 85);}", ); let mut local_clock = Group::new().set("id", "local-clock"); @@ -69,6 +119,17 @@ fn gen_svg() -> Document { local_clock = local_clock.add(hour_node); } + let moon_circle = Circle::new() + .set("class", "moon-background") + .set("cx", image_width / 2) + .set("cy", image_width / 2) + .set("r", moon_radius); + + let moon_group = Group::new() + .set("id", "moon-container") + .add(moon_circle) + .add(get_moon_path(image_width, moon_radius, moon_phase)); + let dial = Line::new() .set("id", "dial") .set("class", "dial") @@ -97,6 +158,7 @@ fn gen_svg() -> Document { .add(stylesheet) .add(border) .add(local_clock) + .add(moon_group) .add(dial) }