Skip to content

Instantly share code, notes, and snippets.

@joebez
Last active June 8, 2023 23:57
Show Gist options
  • Save joebez/b929d383d114b2144599a1597950b948 to your computer and use it in GitHub Desktop.
Save joebez/b929d383d114b2144599a1597950b948 to your computer and use it in GitHub Desktop.
import SwiftUI
import enum Accelerate.vDSP
struct RootView: View {
@State private var vector: AnimatableVector = .zero
@State private var index: Int = 0
let vectorArray: [AnimatableVector] = [
.zero,
AnimatableVector(values: [50, 100, 75, 100]),
AnimatableVector(values: [100, 200, 100, 0])
]
var body: some View {
VStack {
LineChart(vector: vector)
.stroke(Color.red)
.animation(Animation.default, value: vector)
// .animation(Animation.spring(), value: vector) // Only first element of vector will animate
}
.contentShape(Rectangle())
.onTapGesture(count: 1) {
if index + 1 < vectorArray.count { index += 1 }
else { index = 0 }
vector = vectorArray[index]
}
}
}
struct LineChart: Shape {
var vector: AnimatableVector
var animatableData: AnimatableVector {
get { vector }
set { vector = newValue }
}
func path(in rect: CGRect) -> Path {
Path { path in
let xStep = rect.width / CGFloat(vector.values.count)
var currentX: CGFloat = xStep
path.move(to: .zero)
vector.values.forEach {
path.addLine(to: CGPoint(x: currentX, y: CGFloat($0)))
currentX += xStep
}
}
}
}
struct AnimatableVector: VectorArithmetic {
static var zero = AnimatableVector(values: [0.0])
static func + (lhs: AnimatableVector, rhs: AnimatableVector) -> AnimatableVector {
let count = min(lhs.values.count, rhs.values.count)
return AnimatableVector(values: vDSP.add(lhs.values[0..<count], rhs.values[0..<count]))
}
static func += (lhs: inout AnimatableVector, rhs: AnimatableVector) {
let count = min(lhs.values.count, rhs.values.count)
vDSP.add(lhs.values[0..<count], rhs.values[0..<count], result: &lhs.values[0..<count])
}
static func - (lhs: AnimatableVector, rhs: AnimatableVector) -> AnimatableVector {
let count = min(lhs.values.count, rhs.values.count)
return AnimatableVector(values: vDSP.subtract(lhs.values[0..<count], rhs.values[0..<count]))
}
static func -= (lhs: inout AnimatableVector, rhs: AnimatableVector) {
let count = min(lhs.values.count, rhs.values.count)
vDSP.subtract(lhs.values[0..<count], rhs.values[0..<count], result: &lhs.values[0..<count])
}
var values: [Double]
mutating func scale(by rhs: Double) {
values = vDSP.multiply(rhs, values)
}
var magnitudeSquared: Double {
vDSP.sum(vDSP.multiply(values, values))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment