Skip to content

Instantly share code, notes, and snippets.

@kylehowells
Created June 28, 2020 17:37
Show Gist options
  • Save kylehowells/0254847af5d712237cb9eb326ba3756e to your computer and use it in GitHub Desktop.
Save kylehowells/0254847af5d712237cb9eb326ba3756e to your computer and use it in GitHub Desktop.
Scifi Style Speedometer Concept in SwiftUI
import SwiftUI
struct ContentView: View {
let backgroundGradient = Gradient(colors: [
Color(red: 65.0/255.0, green: 65.0/255.0, blue: 84.0/255.0, opacity: 1.0),
Color(red: 20.0/255.0, green: 20.0/255.0, blue: 24.0/255.0, opacity: 1.0)
])
let blueGradient = Gradient(colors: [
Color(red: 149.0/255.0, green: 236.0/255.0, blue: 236.0/255.0, opacity: 1.0),
Color(red: 4.0/255.0, green: 51.0/255.0, blue: 255.0/255.0, opacity: 1.0),
Color.clear,
Color.clear,
Color.clear,
Color.clear,
Color.clear
])
let lightBlueGradient = Gradient(colors: [
Color(red: 149.0/255.0, green: 236.0/255.0, blue: 236.0/255.0, opacity: 1.0),
Color(red: 89.0/255.0, green: 219.0/255.0, blue: 232.0/255.0, opacity: 1.0),
Color(red: 42.0/255.0, green: 45.0/255.0, blue: 93.0/255.0, opacity: 1.0),
Color.clear
])
let clearGradient = Gradient(colors: [
Color.clear,
Color.black
])
let centerWidth:CGFloat = 150
let lineWidth:CGFloat = 60
@State private var animate = false
@State private var speed:Double = 30
var body: some View {
ZStack {
Group {
GeometryReader { geo in
// Background
RadialGradient(
gradient: self.backgroundGradient,
center: .center,
startRadius: 1,
endRadius: geo.size.height)
}
// Inner Circle
GeometryReader { geo in
Circle()
.stroke(
RadialGradient(
gradient: self.lightBlueGradient,
center: .center,
startRadius: (self.centerWidth * 0.5) - (self.lineWidth * 0.5),
endRadius: (self.centerWidth * 0.5) + (self.lineWidth * 0.5)),
lineWidth: self.lineWidth)
.frame(
width: self.centerWidth + (self.lineWidth * 0.5),
height: self.centerWidth + (self.lineWidth * 0.5),
alignment: .center)
}
ZStack {
// Outer Circle
Circle()
.stroke(Color.white, lineWidth: 1)
.frame(width: 324, height: 324)
// Dashed Circle
Circle()
.stroke(Color.white, style: .init(lineWidth: 1, dash: [40, 25], dashPhase: 100))
.frame(width: 275, height: 275)
.rotationEffect(Angle.degrees(animate ? -360 : 0))
// Dashed Circle
Circle()
.stroke(Color.white, style: .init(lineWidth: 1, dash: [20], dashPhase: 50))
.frame(width: 265, height: 265)
.opacity(0)
// Dashed Circle
Circle()
.stroke(Color.white, style: .init(lineWidth: 1, dash: [20, 30], dashPhase: 000))
.frame(width: 275, height: 275)
.rotationEffect(Angle.degrees(animate ? 360 : 0))
// Blue Axial Gradient
Circle()
.stroke(
AngularGradient(
gradient: self.blueGradient,
center: .center,
angle: .degrees(270)
), lineWidth: 20)
.frame(width: 300, height: 300)
.mask(Circle()
.stroke(
// Dark Gradient Mask
RadialGradient(
gradient: self.clearGradient,
center: .center,
startRadius: 140,
endRadius: 160
), lineWidth: 20)
.frame(width: 300, height: 300)
)
}.padding(20)
}
.drawingGroup()
.onAppear {
withAnimation(Animation.linear(duration: 20.0).repeatForever()) {
self.animate = true
}
}
VStack {
Text("\(speed, specifier: "%.0f")")
.font(Font.system(size: 50, weight: .bold, design: .default).monospacedDigit())
.foregroundColor(Color.white)
.shadow(color: Color(white: 1, opacity:0.5), radius: 6)
Text("MPH")
.font(.system(size: 28, weight: .bold, design: .default))
.foregroundColor(Color.white)
.shadow(color: Color(white: 1, opacity:0.5), radius: 6)
}.padding(4)
VStack {
Spacer()
Slider(value: $speed, in: 0...100, step: 0.1)
.padding(.bottom, 30)
.padding(.horizontal, 30)
}
}.edgesIgnoringSafeArea(.all)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView().previewLayout(.fixed(width: 720, height: 400))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment