// // PrismMark.swift // Prisme // // Author: Simon-Pierre Boucher // import SwiftUI /// The Prisme logo, drawn in code so it adapts to light/dark and any size. /// Same geometry as the app icon (Design/icon/prisme-icon.svg): a white beam /// enters a glass prism and exits as a spectrum fan. struct PrismMark: View { var body: some View { Canvas { context, size in let s = min(size.width, size.height) / 1024 func point(_ x: CGFloat, _ y: CGFloat) -> CGPoint { CGPoint(x: x * s, y: y * s) } func polygon(_ pts: [(CGFloat, CGFloat)]) -> Path { var path = Path() path.move(to: point(pts[0].0, pts[0].1)) for p in pts.dropFirst() { path.addLine(to: point(p.0, p.1)) } path.closeSubpath() return path } // Spectrum fan (clipped by the canvas, like the icon). let origin: (CGFloat, CGFloat) = (614, 470) let boundaries: [(CGFloat, CGFloat)] = [ (1211, 248), (1238, 348), (1250, 451), (1244, 555), (1223, 657), (1185, 753), (1132, 843), ] let colors: [Color] = [ Color(red: 1.00, green: 0.23, blue: 0.36), Color(red: 1.00, green: 0.62, blue: 0.11), Color(red: 1.00, green: 0.88, blue: 0.40), Color(red: 0.24, green: 0.86, blue: 0.52), Color(red: 0.22, green: 0.71, blue: 1.00), Color(red: 0.55, green: 0.36, blue: 0.96), ] for (index, color) in colors.enumerated() { let band = polygon([origin, boundaries[index], boundaries[index + 1]]) context.fill(band, with: .color(color.opacity(0.95))) } // Incoming beam, stopping on the left face. Light stays white in // both color schemes; a soft shadow keeps it visible on light // backgrounds. let beam = polygon([(82, 132), (142, 98), (398, 488), (372, 510)]) context.drawLayer { layer in layer.addFilter(.shadow(color: .black.opacity(0.22), radius: 7 * s, y: 2 * s)) layer.fill(beam, with: .color(.white)) } context.stroke(beam, with: .color(.black.opacity(0.10)), lineWidth: 2 * s) // Internal refraction. let inner = polygon([(386, 494), (614, 462), (614, 478), (390, 508)]) context.fill(inner, with: .color(.white.opacity(0.9))) context.stroke(inner, with: .color(.black.opacity(0.08)), lineWidth: 1.5 * s) // Glass triangle. let prism = polygon([(512, 268), (292, 688), (732, 688)]) context.fill(prism, with: .color(.primary.opacity(0.07))) context.stroke( prism, with: .color(.primary.opacity(0.75)), style: StrokeStyle(lineWidth: 10 * s, lineCap: .round, lineJoin: .round) ) } } } #Preview { PrismMark() .frame(width: 160, height: 160) .padding() }