-
Notifications
You must be signed in to change notification settings - Fork 34
/
LFTPulseAnimation.swift
98 lines (80 loc) · 3.46 KB
/
LFTPulseAnimation.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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
//
// LFTPulseAnimation.swift
//
// Created by Christoffer Tews on 18.12.14.
// Copyright (c) 2014 Christoffer Tews. All rights reserved.
//
// Swift clone of: https://github.com/shu223/PulsingHalo/blob/master/PulsingHalo/PulsingHaloLayer.m
import UIKit
class LFTPulseAnimation: CALayer {
var radius: CGFloat = 200.0
var fromValueForRadius: Float = 0.0
var fromValueForAlpha: Float = 0.45
var keyTimeForHalfOpacity: Float = 0.2
var animationDuration: TimeInterval = 3.0
var pulseInterval: TimeInterval = 0.0
var useTimingFunction: Bool = true
var animationGroup: CAAnimationGroup = CAAnimationGroup()
var repetitions: Float = Float.infinity
// Need to implement that, because otherwise it can't find
// the constructor init(layer:AnyObject!)
// Doesn't seem to look in the super class
override init(layer: Any) {
super.init(layer: layer)
}
init(repeatCount: Float=Float.infinity, radius: CGFloat, position: CGPoint) {
super.init()
self.contentsScale = UIScreen.main.scale
self.opacity = 0.0
self.backgroundColor = UIColor.blue.cgColor
self.radius = radius;
self.repetitions = repeatCount;
self.position = position
DispatchQueue.global(qos: .background).async {
self.setupAnimationGroup()
self.setPulseRadius(radius: self.radius)
if (self.pulseInterval != Double.infinity) {
DispatchQueue.main.async {
self.add(self.animationGroup, forKey: "pulse")
}
}
}
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setPulseRadius(radius: CGFloat) {
self.radius = radius
let tempPos = self.position
let diameter = self.radius * 2
self.bounds = CGRect(x: 0.0, y: 0.0, width: diameter, height: diameter)
self.cornerRadius = self.radius
self.position = tempPos
}
func setupAnimationGroup() {
self.animationGroup = CAAnimationGroup()
self.animationGroup.duration = self.animationDuration + self.pulseInterval
self.animationGroup.repeatCount = self.repetitions
self.animationGroup.isRemovedOnCompletion = false
if self.useTimingFunction {
let defaultCurve = CAMediaTimingFunction(name: kCAMediaTimingFunctionDefault)
self.animationGroup.timingFunction = defaultCurve
}
self.animationGroup.animations = [createScaleAnimation(), createOpacityAnimation()]
}
func createScaleAnimation() -> CABasicAnimation {
let scaleAnimation = CABasicAnimation(keyPath: "transform.scale.xy")
scaleAnimation.fromValue = NSNumber(value: self.fromValueForRadius)
scaleAnimation.toValue = NSNumber(value: 1.0)
scaleAnimation.duration = self.animationDuration
return scaleAnimation
}
func createOpacityAnimation() -> CAKeyframeAnimation {
let opacityAnimation = CAKeyframeAnimation(keyPath: "opacity")
opacityAnimation.duration = self.animationDuration
opacityAnimation.values = [self.fromValueForAlpha, 0.8, 0]
opacityAnimation.keyTimes = [0, self.keyTimeForHalfOpacity as NSNumber, 1]
opacityAnimation.isRemovedOnCompletion = false
return opacityAnimation
}
}