Skip to content

Instantly share code, notes, and snippets.

@badrinathvm
Created September 8, 2019 09:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save badrinathvm/5cba9b9b1c2778f6f7ae78b3370e4593 to your computer and use it in GitHub Desktop.
Save badrinathvm/5cba9b9b1c2778f6f7ae78b3370e4593 to your computer and use it in GitHub Desktop.
Animate Particles With Custom Path
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