krz/moonrise

Night-sky companion for iPhone, Apple Watch and Vision Pro: what's up tonight, the Moon, planets, launches and missions, and a Library of the solar system. SwiftUI app with a Cloudflare Workers backend. astronomy cloudflare-workers ios night-sky space swiftui visionos watchos

scripts/make-icon.swift

main
moonrise/scripts/make-icon.swift history · blame · raw

44 lines · 2367 bytes

1 symbol in this file
  • Icon struct, line 5
 1// Renders the app icon: swift scripts/make-icon.swift App/Sources/Assets.xcassets/AppIcon.appiconset/icon-1024.png
 2import AppKit
 3import SwiftUI
 4
 5struct Icon: View {
 6    var body: some View {
 7        Canvas { context, size in
 8            let w = size.width
 9            context.fill(Path(CGRect(origin: .zero, size: size)), with: .color(Color(red: 0.043, green: 0.078, blue: 0.141)))
10            // Stars
11            let stars: [(Double, Double, Double)] = [(0.18, 0.16, 5), (0.32, 0.30, 3), (0.74, 0.14, 4), (0.86, 0.34, 3), (0.12, 0.44, 3), (0.58, 0.24, 2.5), (0.44, 0.10, 3)]
12            for (x, y, r) in stars {
13                context.fill(Path(ellipseIn: CGRect(x: x * w - r, y: y * w - r, width: 2 * r, height: 2 * r)), with: .color(.white.opacity(0.85)))
14            }
15            // Moon, rising: a waxing gibbous disc partly behind the horizon
16            let c = CGPoint(x: w * 0.5, y: w * 0.60), r = w * 0.24
17            context.fill(Path(ellipseIn: CGRect(x: c.x - r, y: c.y - r, width: 2 * r, height: 2 * r)), with: .color(Color(red: 0.16, green: 0.20, blue: 0.27)))
18            var lit = Path()
19            lit.move(to: CGPoint(x: c.x, y: c.y - r))
20            lit.addArc(center: c, radius: r, startAngle: .degrees(-90), endAngle: .degrees(90), clockwise: false)
21            for i in 0...48 {
22                let a = Double.pi / 2 - Double.pi * Double(i) / 48
23                lit.addLine(to: CGPoint(x: c.x - r * 0.45 * cos(a), y: c.y + r * sin(a)))
24            }
25            lit.closeSubpath()
26            context.fill(lit, with: .color(Color(red: 0.93, green: 0.91, blue: 0.85)))
27            // Ground and horizon line
28            let horizon = w * 0.70
29            context.fill(Path(CGRect(x: 0, y: horizon, width: w, height: w - horizon)), with: .color(Color(red: 0.02, green: 0.035, blue: 0.06)))
30            context.fill(Path(CGRect(x: 0, y: horizon - w * 0.006, width: w, height: w * 0.012)), with: .color(Color(red: 0.88, green: 0.24, blue: 0.19)))
31        }
32        .frame(width: 1024, height: 1024)
33    }
34}
35
36let out = URL(fileURLWithPath: CommandLine.arguments[1])
37MainActor.assumeIsolated {
38    let renderer = ImageRenderer(content: Icon())
39    renderer.scale = 1
40    let cg = renderer.cgImage!
41    let rep = NSBitmapImageRep(cgImage: cg)
42    try! rep.representation(using: .png, properties: [:])!.write(to: out)
43}
44print("wrote \(out.path)")