Files
2026-08-12 07:06:01 +07:00

124 lines
5.1 KiB
Swift
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import SwiftUI
// MARK: - Палитра
/// Фирменные цвета Rapira из дизайн-макета.
enum RapiraPalette {
// Рост
static let accent = Color(red: 0.251, green: 0.835, blue: 0.216) // #40D537
static let accentEdge = Color(red: 0.051, green: 0.157, blue: 0.082) // #0D2815
static let accentHalo = Color(red: 0.075, green: 0.214, blue: 0.106) // #13371B
static let accentText = Color(red: 0.277, green: 0.895, blue: 0.239) // #47E43D
// Падение зеркальная красная гамма.
static let negative = Color(red: 0.949, green: 0.267, blue: 0.267) // #F24444
static let negativeEdge = Color(red: 0.161, green: 0.051, blue: 0.051)
static let negativeHalo = Color(red: 0.220, green: 0.075, blue: 0.075)
static let negativeText = Color(red: 0.965, green: 0.310, blue: 0.290)
// Фон и разделители
static let backgroundTint = Color(red: 0.157, green: 0.161, blue: 0.169) // #28292B
static let divider = Color.white.opacity(0.06)
// MARK: Выбор цвета по направлению движения
static func line(_ positive: Bool) -> Color { positive ? accent : negative }
static func lineEdge(_ positive: Bool) -> Color { positive ? accentEdge : negativeEdge }
static func halo(_ positive: Bool) -> Color { positive ? accentHalo : negativeHalo }
static func stat(_ positive: Bool) -> Color { positive ? accentText : negativeText }
}
// MARK: - Фон
/// Радиальный фон из макета: широкая подсветка от верхней кромки, уходящая
/// в чёрный на 61%. В исходнике это эллипс с радиусами 995×512 отсюда
/// растяжение по горизонтали.
struct RapiraBackground: View {
var body: some View {
GeometryReader { geo in
RadialGradient(
gradient: Gradient(stops: [
.init(color: RapiraPalette.backgroundTint, location: 0),
.init(color: .black, location: 0.612),
]),
center: UnitPoint(x: 0.5, y: 0),
startRadius: 0,
endRadius: geo.size.height
)
.frame(width: geo.size.width, height: geo.size.height)
.scaleEffect(x: 1.94, y: 1, anchor: .top)
.clipped()
}
}
}
// MARK: - Логотип
/// Знак Rapira две «ленты», кривые сняты с фирменного SVG
/// (34.7 × 32 в исходных координатах).
struct RapiraMark: View {
var size: CGFloat = 22
var body: some View {
ZStack {
MarkShape(part: .upper).fill(.white)
MarkShape(part: .lower).fill(.white.opacity(0.6))
}
.frame(width: size * (34.736 / 32.0), height: size)
}
private struct MarkShape: Shape {
enum Part { case upper, lower }
let part: Part
func path(in rect: CGRect) -> Path {
let sx = rect.width / 34.736
let sy = rect.height / 32.0
func p(_ x: CGFloat, _ y: CGFloat) -> CGPoint {
CGPoint(x: rect.minX + x * sx, y: rect.minY + y * sy)
}
var path = Path()
switch part {
case .upper:
path.move(to: p(15.545, 0))
path.addCurve(to: p(7.406, 6.217), control1: p(12.037, 0), control2: p(8.393, 2.783))
path.addLine(to: p(0, 31.996))
path.addLine(to: p(6.942, 31.996))
path.addLine(to: p(12.094, 14.062))
path.addCurve(to: p(20.233, 7.845), control1: p(13.081, 10.629), control2: p(16.725, 7.845))
path.addLine(to: p(32.482, 7.845))
path.addLine(to: p(34.736, 0))
case .lower:
path.move(to: p(31.083, 12.803))
path.addLine(to: p(27.464, 25.713))
path.addCurve(to: p(19.432, 32.0), control1: p(26.490, 29.186), control2: p(22.895, 32.0))
path.addLine(to: p(11.886, 32.0))
path.addLine(to: p(15.506, 19.090))
path.addCurve(to: p(23.537, 12.803), control1: p(16.479, 15.618), control2: p(20.075, 12.803))
path.addLine(to: p(31.083, 12.803))
}
path.closeSubpath()
return path
}
}
}
// MARK: - Цвета монет
/// Фолбэк-цвета для иконок монет, когда SVG с CDN недоступен.
enum CoinPalette {
static func color(for currency: String) -> Color {
switch currency {
case "BTC": .orange
case "ETH": Color(red: 0.39, green: 0.49, blue: 0.94)
case "SOL": Color(red: 0.56, green: 0.25, blue: 0.95)
case "BNB": Color(red: 0.96, green: 0.72, blue: 0.04)
case "XRP": Color(red: 0.14, green: 0.14, blue: 0.14)
case "TON": Color(red: 0.04, green: 0.65, blue: 0.93)
case "USDT": Color(red: 0.149, green: 0.631, blue: 0.482)
default: Color(red: 0.55, green: 0.55, blue: 0.60)
}
}
}