Skip to content

Instantly share code, notes, and snippets.

@snowtema
Created October 12, 2021 18:30
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 snowtema/f29ff7b238016b4a0597fb4db8bcf39e to your computer and use it in GitHub Desktop.
Save snowtema/f29ff7b238016b4a0597fb4db8bcf39e to your computer and use it in GitHub Desktop.
Moon shadow
import UIKit
import Foundation
import PlaygroundSupport
import QuartzCore
import CoreGraphics
import Darwin
let view = UIView(frame: .init(x: 0, y: 0, width: 600, height: 600))
view.backgroundColor = .black
func calculateMoonPath(for angle: CGFloat) -> UIBezierPath {
let center = CGPoint(x: view.bounds.midX, y: view.bounds.midY)
let radius = view.bounds.height/2
let path = UIBezierPath(arcCenter: center,
radius: radius,
startAngle: -.pi/2,
endAngle: .pi/2,
clockwise: true)
path.addArc(withCenter: .init(x: center.x - radius * tan(angle), y: center.y),
radius: radius / CGFloat(cosf(Float(angle))),
startAngle: .pi/2 - angle,
endAngle: angle - .pi/2,
clockwise: false
)
path.close()
return path
}
func animatePhase(for layer: CALayer) {
let animation = CABasicAnimation(keyPath: "path")
animation.duration = 4
animation.toValue = calculateMoonPath(for:.pi/2*0.6).cgPath
animation.timingFunction = .init(name: .easeInEaseOut)
animation.isRemovedOnCompletion = false
animation.repeatCount = 100
layer.add(animation, forKey: nil)
}
func addMoonShadow() {
let shadowLayer = CAShapeLayer()
shadowLayer.frame = view.bounds
shadowLayer.path = calculateMoonPath(for: 0).cgPath
shadowLayer.fillColor = UIColor.black.withAlphaComponent(0.5).cgColor
shadowLayer.strokeColor = UIColor.red.cgColor
shadowLayer.lineWidth = 2
view.layer.addSublayer(shadowLayer)
animatePhase(for: shadowLayer)
}
addMoonShadow()
PlaygroundPage.current.needsIndefiniteExecution = true
PlaygroundPage.current.liveView = view
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment