diff --git a/src/main.rs b/src/main.rs index 92121b7..db8e4f7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -61,6 +61,44 @@ fn hour_marker( .add(utc_hour_text) } +fn get_range_path( + image_width: u32, + radius: f32, + range_name: &str, + start_time: i32, + end_time: i32, +) -> Path { + let start_deg = time_to_degrees(start_time); + let end_deg = time_to_degrees(end_time); + let deg_diff = end_deg - start_deg; + + let start_delta_x = radius * start_deg.to_radians().sin(); + let start_delta_y = radius * (1.0 - start_deg.to_radians().cos()); + let end_delta_x = radius * end_deg.to_radians().sin(); + let end_delta_y = radius * (1.0 - end_deg.to_radians().cos()); + + let large_arc_flag = if deg_diff.abs() >= 180.0 { 0 } else { 1 }; + + let path_data = PathData::new() + .move_to((image_width / 2, image_width / 2)) + .line_to(( + image_width as f32 / 2.0 - start_delta_x, + image_width as f32 / 2.0 + radius - start_delta_y, + )) + .elliptical_arc_to(( + radius, + radius, + deg_diff, + large_arc_flag, + 0, + image_width as f32 / 2.0 - end_delta_x, + image_width as f32 / 2.0 + radius - end_delta_y, + )) + .close(); + + Path::new().set("class", range_name).set("d", path_data) +} + 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; @@ -128,6 +166,30 @@ fn gen_svg() -> Document { .timestamp_millis(sun_times.nadir.0) .time() .num_seconds_from_midnight() as i32; + let morning_golden_end = Local + .timestamp_millis(sun_times.golden_hour_end.0) + .time() + .num_seconds_from_midnight() as i32; + let evening_golden_start = Local + .timestamp_millis(sun_times.golden_hour.0) + .time() + .num_seconds_from_midnight() as i32; + let sunrise = Local + .timestamp_millis(sun_times.sunrise.0) + .time() + .num_seconds_from_midnight() as i32; + let sunset = Local + .timestamp_millis(sun_times.sunset.0) + .time() + .num_seconds_from_midnight() as i32; + let dawn = Local + .timestamp_millis(sun_times.dawn.0) + .time() + .num_seconds_from_midnight() as i32; + let dusk = Local + .timestamp_millis(sun_times.dusk.0) + .time() + .num_seconds_from_midnight() as i32; let local_hour_font_size = image_width as f32 * 0.02357; let hour_name_font_size = image_width as f32 * 0.019109; @@ -136,6 +198,7 @@ fn gen_svg() -> Document { let ring_width = hour_name_font_size * 3.0; let sun_radius = image_width as f32 * 0.0142871; let marker_radius = outer_r - ring_width - 2.0 * utc_hour_font_size; + let border = Rectangle::new() .set("x", 0i32) .set("y", 0i32) @@ -147,6 +210,10 @@ fn gen_svg() -> Document { #border {stroke: none; fill: rgb(19, 17, 30); } .hour text.utc {stroke: none; fill: rgb(91, 68, 38);} .local-hour {stroke: none; fill: rgb(238, 187, 85);} + .night-time {stroke: none; fill: 19, 17, 30);} + .blue-hour {stroke: none; fill: rgb(9, 1, 119);} + .golden-hour {stroke: none; fill: rgb(170, 132, 44);} + .day-time {stroke: none; fill: rgb(125, 197, 240);} .moon-background {stroke: rgb(170, 170, 170); stroke-width: 2px; fill: rgb(19, 17, 30);} .moon {stroke: none; fill: rgb(170, 170, 170);} .mid-marker {stroke: red;} @@ -196,6 +263,37 @@ fn gen_svg() -> Document { )); } + let daytime_circle = Circle::new() + .set("class", "day-time") + .set("cx", image_width / 2) + .set("cy", image_width / 2) + .set("r", marker_radius); + + let golden_hour_path = get_range_path( + image_width, + marker_radius, + "golden-hour", + morning_golden_end, + evening_golden_start, + ); + + let blue_hour_path = get_range_path( + image_width, + marker_radius, + "blue-hour", + sunrise, // morning_blue_end + sunset, // evening_blue_start + ); + + let nighttime_path = get_range_path(image_width, marker_radius, "night-time", dawn, dusk); + + let day_parts_group = Group::new() + .set("id", "day-parts") + .add(daytime_circle) + .add(golden_hour_path) + .add(blue_hour_path) + .add(nighttime_path); + let moon_circle = Circle::new() .set("class", "moon-background") .set("cx", image_width / 2) @@ -271,6 +369,7 @@ fn gen_svg() -> Document { .add(stylesheet) .add(border) .add(local_clock) + .add(day_parts_group) .add(seasonal_clock) .add(moon_group) .add(noon_marker)