-
Notifications
You must be signed in to change notification settings - Fork 316
/
Copy pathMenuItemsAnimator.swift
51 lines (42 loc) · 1.76 KB
/
MenuItemsAnimator.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
//
// Copyright © 2014 Yalantis
// Licensed under the MIT license: http://opensource.org/licenses/MIT
// Latest version can be found at http://github.com/yalantis/Side-Menu.iOS
//
import UIKit
private func TransformForRotatingLayer(_ layer: CALayer, angle: CGFloat) -> CATransform3D {
let offset = layer.bounds.width / 2
var transform = CATransform3DIdentity
transform.m34 = -0.002
transform = CATransform3DTranslate(transform, -offset, 0, 0)
transform = CATransform3DRotate(transform, angle, 0, 1, 0)
transform = CATransform3DTranslate(transform, offset, 0, 0)
return transform
}
class MenuItemsAnimator {
var completion: () -> Void = {}
var duration: CFTimeInterval = 0
fileprivate let layers: [CALayer]
fileprivate let startAngle: CGFloat
fileprivate let endAngle: CGFloat
init(views: [UIView], startAngle: CGFloat, endAngle: CGFloat) {
self.layers = views.map { $0.layer }
self.startAngle = startAngle
self.endAngle = endAngle
}
func start() {
let count = Double(layers.count)
let duration = self.duration * count / (4 * count - 3)
for (index, layer) in layers.enumerated() {
layer.transform = TransformForRotatingLayer(layer, angle: startAngle)
let delay = 3 * duration * Double(index) / count
UIView.animate(withDuration: duration, delay: delay, options: .curveEaseIn, animations: {
layer.transform = TransformForRotatingLayer(layer, angle: self.endAngle)
}, completion: nil)
}
let delay = DispatchTime.now() + Double(Int64(self.duration * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC)
DispatchQueue.main.asyncAfter(deadline: delay) {
self.completion()
}
}
}