summaryrefslogtreecommitdiff
path: root/makima/ios/Sources/Makima/Design/Components/Logo.swift
diff options
context:
space:
mode:
Diffstat (limited to 'makima/ios/Sources/Makima/Design/Components/Logo.swift')
-rw-r--r--makima/ios/Sources/Makima/Design/Components/Logo.swift51
1 files changed, 51 insertions, 0 deletions
diff --git a/makima/ios/Sources/Makima/Design/Components/Logo.swift b/makima/ios/Sources/Makima/Design/Components/Logo.swift
new file mode 100644
index 0000000..01d263e
--- /dev/null
+++ b/makima/ios/Sources/Makima/Design/Components/Logo.swift
@@ -0,0 +1,51 @@
+import SwiftUI
+
+/// Makima concentric-ring logo.
+/// Loads from bundled `makima-logo.svg` if present; otherwise falls back to
+/// a Canvas-rendered concentric-ring approximation so the app always builds
+/// even if the SVG copy step is skipped.
+struct Logo: View {
+ var size: CGFloat = 120
+
+ var body: some View {
+ Group {
+ if let uiImage = Self.loadedSVG(named: "makima-logo") {
+ Image(uiImage: uiImage)
+ .resizable()
+ .renderingMode(.template)
+ .foregroundStyle(Palette.accent)
+ } else {
+ Canvas { ctx, canvasSize in
+ let center = CGPoint(x: canvasSize.width / 2, y: canvasSize.height / 2)
+ let maxR = min(canvasSize.width, canvasSize.height) / 2
+ let rings = 5
+ for i in 0..<rings {
+ let t = CGFloat(i + 1) / CGFloat(rings)
+ let r = maxR * t
+ let rect = CGRect(x: center.x - r, y: center.y - r,
+ width: r * 2, height: r * 2)
+ let shading = GraphicsContext.Shading.color(
+ Palette.accent.opacity(1.0 - Double(i) * 0.15)
+ )
+ ctx.stroke(Circle().path(in: rect), with: shading, lineWidth: 1.25)
+ }
+ let dotR = maxR * 0.06
+ ctx.fill(Circle().path(in: CGRect(x: center.x - dotR, y: center.y - dotR,
+ width: dotR * 2, height: dotR * 2)),
+ with: .color(Palette.accent))
+ }
+ }
+ }
+ .frame(width: size, height: size)
+ .accessibilityLabel("Makima")
+ }
+
+ /// SwiftUI 18 doesn't natively decode SVG through UIImage, so we try PDF
+ /// fallback first (Xcode auto-converts SVGs placed in asset catalogs to PDF).
+ /// If the file ships as a raw `.svg` bundle resource, we decline and fall back
+ /// to the Canvas drawing. This keeps M1 buildable without additional deps.
+ private static func loadedSVG(named name: String) -> UIImage? {
+ if let img = UIImage(named: name) { return img }
+ return nil
+ }
+}