Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes for iOS 15 animation. Issue: https://github.com/maustinstar/li… #9

Merged
merged 1 commit into from
Jan 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 26 additions & 22 deletions Sources/Liquid/PrivateViews/LiquidCircleView.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//
// LiquidCircleView.swift
//
//
//
// Created by Michael Verges on 8/17/20.
//
Expand All @@ -19,51 +19,55 @@ struct LiquidCircleView: View {
self._samples = .init(initialValue: samples)
self._radians = .init(initialValue: AnimatableArray(LiquidCircleView.generateRadial(samples)))
self.period = period

startTimer()
}

var body: some View {
LiquidCircle(radians: radians)
.animation(.linear(duration: period))
.onAppear {
self.radians = AnimatableArray(LiquidCircleView.generateRadial(self.samples))

self.startTimer()
startTimer()
}
.onDisappear {
self.stopTimer()
stopTimer()
}
}

static func generateRadial(_ count: Int = 6) -> [Double] {

var radians: [Double] = []
let offset = Double.random(in: 0...(.pi / Double(count)))
for i in 0..<count {
let min = Double(i) / Double(count) * 2 * .pi
let max = Double(i + 1) / Double(count) * 2 * .pi
radians.append(Double.random(in: min...max) + offset)
}

return radians
}

private func startTimer() {
guard self.cancellable == nil else {
return
guard cancellable == nil else { return }

// Get the animation started immediately by updating the radians.
DispatchQueue.main.asyncAfter(deadline: .now()) {
animatedRadianUpdate()
}

self.cancellable = Timer.publish(every: period, on: .main, in: .common)

// Periodically update the radians to continue the animation.
cancellable = Timer.publish(every: period, on: .main, in: .common)
.autoconnect()
.sink { _ in
self.radians = AnimatableArray(LiquidCircleView.generateRadial(self.samples))
animatedRadianUpdate()
}

func animatedRadianUpdate() {
withAnimation(.linear(duration: period)) {
radians = AnimatableArray(LiquidCircleView.generateRadial(samples))
}
}
}

private func stopTimer() {
self.cancellable?.cancel()
self.cancellable = nil
cancellable?.cancel()
cancellable = nil
}

}
17 changes: 9 additions & 8 deletions Sources/Liquid/PrivateViews/LiquidPathView.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//
// LiquidPathView.swift
//
//
//
// Created by Michael Verges on 8/17/20.
//
Expand All @@ -10,7 +10,7 @@ import Combine
import Accelerate

struct LiquidPathView: View {

let pointCloud: (x: [Double], y: [Double])
@State var x: AnimatableArray = .zero
@State var y: AnimatableArray = .zero
Expand All @@ -27,16 +27,17 @@ struct LiquidPathView: View {
self.cancellable = self.trigger.connect()
self.pointCloud = path.getPoints().interpolate(interpolate)
}

func generate() {
let points = Array(0..<pointCloud.x.count).randomElements(samples)
self.x = AnimatableArray(points.map { self.pointCloud.x[$0] })
self.y = AnimatableArray(points.map { self.pointCloud.y[$0] })
withAnimation(.linear(duration: period)) {
let points = Array(0..<pointCloud.x.count).randomElements(samples)
self.x = AnimatableArray(points.map { self.pointCloud.x[$0] })
self.y = AnimatableArray(points.map { self.pointCloud.y[$0] })
}
}

var body: some View {
LiquidPath(x: x, y: y)
.animation(.linear(duration: period))
.onReceive(trigger) { _ in
self.generate()
}.onAppear {
Expand Down