Created
September 8, 2019 09:25
-
-
Save badrinathvm/5cba9b9b1c2778f6f7ae78b3370e4593 to your computer and use it in GitHub Desktop.
Animate Particles With Custom Path
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 UIKit | |
class ViewController: UIViewController { | |
let width: CGFloat = 240.0 | |
let height: CGFloat = 160.0 | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
let sineView = HingeView(frame: UIScreen.main.bounds) | |
sineView.backgroundColor = .yellow | |
view.addSubview(sineView) | |
view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleTap))) | |
} | |
func handleTap() { | |
(0...10).forEach { (_) in | |
generateAnimatedViews() | |
} | |
} | |
fileprivate func generateAnimatedViews() { | |
let image = drand48() > 0.5 ? #imageLiteral(resourceName: "confetti") : #imageLiteral(resourceName: "diamond") | |
let imageView = UIImageView(image: image) | |
let dimension = 20 + drand48() * 10 | |
imageView.frame = CGRect(x: 0, y: 0, width: dimension, height: dimension) | |
//instead of imageView do , emitter particles | |
let confettiView = ConfettiView() | |
confettiView.intensity = 0.7 | |
confettiView.type = ConfettiType.image(image) | |
confettiView.startConfetti() | |
let animation = CAKeyframeAnimation(keyPath: "position") | |
//animation.path = customPath().cgPath | |
//animation.path = trainglePathWithCenter(center: CGPoint(x: 150, y: 150), side: 375 / 2).cgPath | |
animation.path = hinge(CGRect(x: 0, y: 0, width: 414, height: 896)).reversing().cgPath | |
animation.duration = 2 + drand48() * 3 | |
animation.fillMode = kCAFillModeForwards | |
animation.isRemovedOnCompletion = false | |
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut) | |
//imageView.layer.add(animation, forKey: nil) | |
//view.addSubview(imageView) | |
confettiView.layer.add(animation, forKey: nil) | |
view.addSubview(confettiView) | |
CATransaction.begin() | |
CATransaction.setCompletionBlock { | |
let transition = CATransition() | |
//transition.delegate = self | |
transition.type = kCATransitionFade | |
transition.duration = 10 | |
transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut) | |
transition.setValue(imageView, forKey: "position") | |
transition.isRemovedOnCompletion = false | |
// imageView.layer.add(transition, forKey: nil) | |
// imageView.layer.opacity = 0 | |
confettiView.layer.add(transition, forKey: nil) | |
confettiView.layer.opacity = 0 | |
//confettiView.stopConfetti() | |
} | |
CATransaction.commit() | |
} | |
} | |
class HingeView: UIView{ | |
override func draw(_ rect: CGRect) { | |
let path = hinge(rect) | |
UIColor.black.setStroke() | |
path.lineWidth = 3 | |
path.stroke() | |
} | |
} | |
fileprivate func hinge(_ rect: CGRect) -> UIBezierPath { | |
_ = rect.width | |
let height = rect.height | |
let path = UIBezierPath() | |
let origin = CGPoint(x: 150, y: height) | |
path.move(to: origin) | |
path.addLine(to: CGPoint(x: 150, y: height / 2)) | |
let endPoint = CGPoint(x: 400, y: 200) | |
let randomYShift = 200 + drand48() * 300 | |
let cp1 = CGPoint(x: 150, y: 200 + randomYShift) | |
let cp2 = CGPoint(x: 150, y: 200 - randomYShift) | |
path.addCurve(to: endPoint, controlPoint1: cp1, controlPoint2: cp2) | |
return path | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment