Created
December 11, 2019 18:14
-
-
Save eivindml/28e81d630cdd59521240a9adada7ddc2 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import SwiftUI | |
struct WheelData { | |
let strokeWidth: CGFloat | |
let knobWidth: CGFloat | |
} | |
struct WheelView: View { | |
@State var position: CGSize? | |
@State var angle: CGFloat = 0 | |
let wheel = WheelData( | |
strokeWidth: 40, | |
knobWidth: 40 | |
) | |
var body: some View { | |
GeometryReader { geometry in | |
ZStack { | |
Circle() | |
.stroke(Color.secondary, lineWidth: self.wheel.strokeWidth) | |
Circle() | |
.trim(from: 0.0, to: self.angle) | |
.stroke(Color.blue, lineWidth: self.wheel.strokeWidth) | |
Circle() | |
.fill(Color.primary) | |
.frame( | |
width: self.wheel.knobWidth, | |
height: self.wheel.knobWidth | |
) | |
.shadow(radius: CGFloat(10.0)) | |
.offset( | |
self.position ?? | |
CGSize( | |
width: geometry.size.width/2 - self.wheel.knobWidth/2, | |
height: 0 | |
) | |
) | |
.gesture(DragGesture() | |
.onChanged { value in | |
// Get center coordinate | |
let center = (geometry.size.width - self.wheel.strokeWidth) / 2 | |
// Calculate the ∠ from center to current touch point | |
let radians = atan2(value.location.y/center, value.location.x/center) | |
// Convert from radians to degrees | |
let degrees = radians * (180 / .pi) | |
// Normalize degrees to go from 0 to 360 | |
let normalizedDegrees = (degrees + 360).truncatingRemainder(dividingBy: 360) | |
// Calculate new position for knob using the angle and the fixed radius | |
// sin = oppsite/hypotenus | |
// cos = adjacent/hyptenus | |
let x = cos(radians) * center | |
let y = sin(radians) * center | |
self.position = CGSize( | |
width: x, | |
height: y | |
) | |
// Update global angle | |
self.angle = normalizedDegrees / 360 | |
// TODO: Emit angle from here | |
}) | |
}.frame( | |
width: geometry.size.width - self.wheel.strokeWidth, | |
height: geometry.size.width - self.wheel.strokeWidth | |
) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment