// // SpinWheelView.swift // SodaLive // // Created by klaus on 2023/12/07. // import SwiftUI struct Triangle: Shape { public func path(in rect: CGRect) -> Path { var path = Path() path.move(to: CGPoint(x: rect.midX, y: rect.minY)) path.addLine(to: CGPoint(x: rect.minX, y: rect.maxY)) path.addLine(to: CGPoint(x: rect.maxX, y: rect.maxY)) path.addLine(to: CGPoint(x: rect.midX, y: rect.minY)) path.addCurve(to: CGPoint(x: rect.midX, y: rect.minY), control1: CGPoint(x: rect.maxX, y: rect.minY), control2: CGPoint(x: rect.midX, y: rect.minY)) return path } } struct SpinWheelPointer: View { var pointerColor: Color var body: some View { Triangle().frame(width: 50, height: 50) .foregroundColor(pointerColor).cornerRadius(24) .rotationEffect(.init(degrees: 180)) .shadow(color: Color(hex: "212121").opacity(0.5), radius: 5, x: 0.0, y: 1.0) } } struct SpinWheelBolt: View { var body: some View { ZStack { Circle().frame(width: 28, height: 28) .foregroundColor(Color(hex: "F4C25B")) Circle().frame(width: 18, height: 18) .foregroundColor(Color(hex: "FFD25A")) .shadow(color: Color(hex: "404040").opacity(0.35), radius: 3, x: 0.0, y: 1.0) } } } struct SpinWheelView: View { var data: [Double], labels: [String] private let colors: [Color] private let sliceOffset: Double = -.pi / 2 @available(macOS 10.15, *) init(data: [Double], labels: [String], colors: [Color]) { self.data = data self.labels = labels self.colors = colors } @available(macOS 10.15.0, *) var body: some View { GeometryReader { geo in ZStack(alignment: .center) { ForEach(0.. Double { switch index { case 0: return sliceOffset default: let ratio: Double = data[.. Double { switch index { case data.count - 1: return sliceOffset + 2 * .pi default: let ratio: Double = data[..<(index + 1)].reduce(0.0, +) / data.reduce(0.0, +) return sliceOffset + 2 * .pi * ratio } } private func viewOffset(for index: Int, in size: CGSize) -> CGSize { let radius = min(size.width, size.height) / 3 let dataRatio = (2 * data[..