-
-
Save joebez/b929d383d114b2144599a1597950b948 to your computer and use it in GitHub Desktop.
This file contains 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 | |
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