Skip to content

Instantly share code, notes, and snippets.

@ConfusedVorlon
Last active July 3, 2023 22:03
Show Gist options
  • Save ConfusedVorlon/dff94f24da62d306e5e43d9087db2688 to your computer and use it in GitHub Desktop.
Save ConfusedVorlon/dff94f24da62d306e5e43d9087db2688 to your computer and use it in GitHub Desktop.
//
// ContentView.swift
// Stars
//
// Created by Rob Jonson on 03/07/2023.
//
import SwiftUI
struct ContentView: View {
@State var rating:CGFloat = 0
var body: some View {//
// ContentView.swift
// Stars
//
// Created by Rob Jonson on 03/07/2023.
//
import SwiftUI
struct ContentView: View {
@State var rating:CGFloat = 0
var body: some View {
VStack {
HStack(spacing:20) {
ForEach(Array(0...4),id:\.self) {
value in
StarView(bottom: value, value: rating)
}
}
Slider(value: $rating,in:0...5)
Button("Jump") {
rating = rating + 1
}
}
.padding()
.animation(.easeInOut, value: rating)
}
}
struct StarView:View {
internal init(bottom: Int,value:CGFloat) {
self.bottom = bottom
self.value = value
}
let bottom:Int
var value: CGFloat
var body: some View {
VStack {
gradient
.frame(maxWidth:.infinity,maxHeight: .infinity)
.aspectRatio(1,contentMode: .fit)
.mask(Image(systemName: "star.fill").resizable())
}
}
var gradient:LinearGradient {
let gradientStops: [Gradient.Stop] = [
.init(color: .yellow, location: 0.0),
.init(color: .yellow, location: percentToShow),
.init(color: .gray, location: percentToShow),
.init(color: .gray, location: 1.0)
]
return LinearGradient(
gradient: Gradient(stops: gradientStops),
startPoint: .leading,
endPoint: .trailing
)
}
var percentToShow:CGFloat {
let relativeValue = value - CGFloat(bottom)
return min(max(relativeValue, 0), 1)
}
}
extension StarView: Animatable {
var animatableData: CGFloat {
get { value }
set { value = newValue }
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
VStack {
HStack(spacing:20) {
ForEach(Array(0...4),id:\.self) {
value in
StarView(bottom: value, value: rating)
}
}
Slider(value: $rating,in:0...5)
Button("Jump") {
rating = rating + 1
}
}
.padding()
.animation(.easeInOut, value: rating)
}
}
struct StarView:View {
internal init(bottom: Int,value:CGFloat) {
self.bottom = bottom
self.value = value
}
let bottom:Int
var value: CGFloat
var body: some View {
VStack {
gradient
.frame(maxWidth:.infinity,maxHeight: .infinity)
.aspectRatio(1,contentMode: .fit)
.mask(Image(systemName: "star.fill").resizable())
}
}
var gradient:LinearGradient {
let gradientStops: [Gradient.Stop] = [
.init(color: .yellow, location: 0.0),
.init(color: .yellow, location: percentToShow),
.init(color: .gray, location: percentToShow),
.init(color: .gray, location: 1.0)
]
return LinearGradient(
gradient: Gradient(stops: gradientStops),
startPoint: .leading,
endPoint: .trailing
)
}
var percentToShow:CGFloat {
let relativeValue = value - CGFloat(bottom)
return min(max(relativeValue, 0), 1)
}
}
extension StarView: Animatable {
var animatableData: CGFloat {
get { value }
set { value = newValue }
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment