๐Polygon
Last updated
Last updated
โฌ๏ธ ้่ฆ๏ผ Vector2D, floating +โโจรท int
// 2022.03.01
import SwiftUI
import Extensions // FloatingPoint+
import Protocols // Vector2D
/// an animatable polygon shape
/// ```
/// Polygon(sides: 6, scale: 1.2)
/// Polygon(5)
/// ```
public struct Polygon: Shape {
var sides: CGFloat
var scale: CGFloat = 1.0
public init(sides: CGFloat, scale: CGFloat = 1.0) {
self.sides = sides
self.scale = scale
}
// โญ๏ธ `animatableData` (AnimatablePair)
public var animatableData: AnimatablePair<CGFloat, CGFloat> {
get { AnimatablePair(sides, scale) }
// โญ๏ธ set new animation value
set {
sides = newValue.first
scale = newValue.second
}
}
public func path(in rect: CGRect) -> Path {
let r = scale * rect.minSide / 2 // radius
let c = rect.center // polygon center
let a0 = -0.5 * CGFloat.pi // start angle
let a = CGFloat.pi / sides * 2 // difference to next angle
let n = Int(sides.rounded(.up)) // integral sides
return Path { path in
path.move(to: c + .polar(r, a0))
for i in 1..<n {
path.addLine(to: c + .polar(r, a0 + a * i))
}
path.closeSubpath()
}
}
}
// convenience init
extension Polygon {
/// `Polygon(3)`
public init(_ n: CGFloat) {
self.init(sides: n)
}
}
Animations:
implicit animations: .animation()
modifier
disable animation: .animation(nil)
explicit animations: withAnimation{ ... }
closure
related protocol: `Animatable`
`animatableData`: computed property (with default implementation by doing nothing)
`Shape` conforms to `Animatable`
`AnimatablePair<First, Second>`: animate ove 2 parameters
`Animatable`: Angle, CGPoint, CGRect, CGSize, EdgeInsets, StrokeStyle, UnitPoint.
`VectorArithmetic`: AnimatablePair, CGFloat, Double, EmptyAnimatableData, Float.
โฌ๏ธ ้่ฆ๏ผ .decimalPlaces(), floating +โโจรท int
// 2022.03.01
import SwiftUI
struct ContentView: View {
@State private var sides: CGFloat = 3
@State private var scale: CGFloat = 1
var body: some View {
VStack {
polygon
Slider(value: $sides, in: 1...15)
buttons
}
.padding()
}
}
extension ContentView {
/// polygon
var polygon: some View {
Polygon(sides: sides, scale: scale) // ๐ Polygon
.stroke(.green)
.overlay {
Text("\(scale.decimalPlaces(2))") // ๐FloatingPoint+
.font(.caption)
.bold()
.shadow(radius: 6)
}
.background {
Circle().stroke(.secondary)
Polygon(sides).stroke(.blue) // ๐ Polygon
}
.border(.secondary)
.frame(height: 200)
}
/// buttons
var buttons: some View {
HStackForEach(1..<10){i in
Button {
withAnimation(.easeInOut(duration: 1.5)) {
sides = 1.0 * i // ๐FloatingPoint+
scale = CGFloat.random(in: 0.2...1.2)
}
} label: {
Text("\(i)")
.font(.title3).bold()
.foregroundColor(.primary)
.padding()
.background(.pink)
.cornerRadius(6)
}
}
}
}
SwiftUI โฉ Animations โฉ
Animatable (protocol)
animatableData - conforms to VectorArithmetic (protocol).
AnimatablePair (struct)
SwiftUI Lab โฉ Advanced SwiftUI Animations โฉ
is an Animatable Shape.