Skip to content

Commit

Permalink
Merge pull request #11 from the-grid/optim
Browse files Browse the repository at this point in the history
Allow turn and repeat count in initialization
  • Loading branch information
nickvelloff committed May 1, 2016
2 parents 978c6c7 + 3063c41 commit 6e903a9
Showing 1 changed file with 94 additions and 112 deletions.
206 changes: 94 additions & 112 deletions GridLogo/GridLogo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,30 +22,81 @@ extension CGPoint {

public class GridLogo: UIView {

var mystic: CGFloat = 4
var turns = 9
var xstep = [1,0,-1,0]
var ystep = [0,1,0,-1]
static let xstep = [1,0,-1,0]
static let ystep = [0,1,0,-1]

var md: CGFloat!
var strokeRatio: CGFloat!
var last: CGPoint!
var curr: CGPoint!
var scalestep: CGFloat!
static func shapeLayerWithLogoPath(strokeColor: UIColor, lineJoin: String, lineWidth: CGFloat, turns: Int, md: CGFloat) -> CAShapeLayer {

var curr = CGPointZero
var last = CGPointZero
var scalestep: CGFloat
let path = UIBezierPath()
path.moveToPoint(curr)

for i in 0 ..< turns {
scalestep = round((CGFloat(i) + 1) / 2.0) * CGFloat(md)
curr = CGPoint(x: CGFloat(last.x) + (scalestep * CGFloat(xstep[i % 4])), y: CGFloat(last.y) + (scalestep * CGFloat(ystep[i % 4]))).toInt()

if i + 1 == turns {
curr = CGPoint(x: CGFloat(curr.x) - (md * CGFloat(xstep[i % 4])), y: CGFloat(curr.y) - (md * CGFloat(ystep[i % 4]))).toInt()
}

path.addLineToPoint(curr)
last = curr
}

let shapeLayer = CAShapeLayer()
shapeLayer.path = path.CGPath
shapeLayer.strokeColor = strokeColor.CGColor
shapeLayer.fillColor = nil
shapeLayer.lineWidth = lineWidth
shapeLayer.lineJoin = lineJoin
return shapeLayer
}

weak var bgLayer: CAShapeLayer?
weak var fgLayer: CAShapeLayer?
var pathAnimationIn: CABasicAnimation!
var pathAnimationOut: CABasicAnimation!
var pathAnimationGroup: CAAnimationGroup!
static func setupAnimation(duration: CFTimeInterval, repeatCount: Float) -> CAAnimationGroup {

let pathAnimationIn = CABasicAnimation(keyPath: "strokeEnd")
let pathAnimationOut = CABasicAnimation(keyPath: "strokeStart")
let pathAnimationGroup = CAAnimationGroup()



let startPos: CGFloat = 0.0
let endPos: CGFloat = 1.0


pathAnimationIn.fromValue = startPos
pathAnimationIn.toValue = endPos
pathAnimationIn.duration = duration / 2
pathAnimationIn.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)


pathAnimationOut.fromValue = startPos
pathAnimationOut.toValue = endPos
pathAnimationOut.duration = duration / 2
pathAnimationOut.beginTime = duration / 2
pathAnimationOut.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)


pathAnimationGroup.animations = [pathAnimationIn, pathAnimationOut]
pathAnimationGroup.duration = duration
pathAnimationGroup.repeatCount = repeatCount
pathAnimationGroup.removedOnCompletion = false
pathAnimationGroup.fillMode = kCAFillModeBackwards

return pathAnimationGroup
}

private var duration: CFTimeInterval = 5.0
private var startPos: CGFloat = 0.0
private var endPos: CGFloat = 1.0
private var mystic: CGFloat = 4
private var turns: Int
private var md: CGFloat
private let bgLayer: CAShapeLayer
private let fgLayer: CAShapeLayer
private let pathAnimationGroup: CAAnimationGroup
private var duration: CFTimeInterval
private var reverses = false
private var repeatCount: Float = 14.5
private var lineWidth: CGFloat?

private var lineWidth: CGFloat
private let fadeDuration = dispatch_time(DISPATCH_TIME_NOW, Int64(0.5 * Double(NSEC_PER_SEC)))

let fadeInAnimation: CABasicAnimation = {
Expand All @@ -64,132 +115,63 @@ public class GridLogo: UIView {
return animation
}()

public init(mystic m: CGFloat, duration d: CFTimeInterval, lineWidth lw: CGFloat = 1, bgColor: UIColor = UIColor(red: 51/255, green: 51/255, blue: 48/255, alpha: 1), fgColor: UIColor = UIColor(red: 1, green: 246/255, blue: 153/255, alpha: 1)) {
super.init(frame: CGRectZero)
public init(mystic m: CGFloat, duration d: CFTimeInterval, lineWidth lw: CGFloat = 1, bgColor: UIColor = UIColor(red: 51/255, green: 51/255, blue: 48/255, alpha: 1), fgColor: UIColor = UIColor(red: 1, green: 246/255, blue: 153/255, alpha: 1), turns t: Int = 9, repeatCount: Float = 14) {

mystic = m
duration = d
lineWidth = lw
md = m
strokeRatio = CGFloat(md) / CGFloat(mystic)
turns = t
bgLayer = GridLogo.shapeLayerWithLogoPath(bgColor, lineJoin: kCALineJoinMiter, lineWidth: lineWidth, turns: turns, md: md)
fgLayer = GridLogo.shapeLayerWithLogoPath(fgColor, lineJoin: kCALineJoinMiter, lineWidth: lineWidth, turns: turns, md: md)
pathAnimationGroup = GridLogo.setupAnimation(duration, repeatCount: repeatCount)

super.init(frame: CGRectZero)
layer.addSublayer(bgLayer)
layer.addSublayer(fgLayer)
userInteractionEnabled = false
addBackground(bgColor)
setupAnimation(fgColor)

}

required public init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

var logoPath: UIBezierPath {
get{
self.curr = CGPoint.zero
self.last = CGPoint.zero
let path = UIBezierPath()
path.moveToPoint(curr)

for i in 0 ..< turns {
scalestep = round((CGFloat(i) + 1) / 2.0) * CGFloat(md)
curr = CGPoint(x: CGFloat(last.x) + (scalestep * CGFloat(xstep[i % 4])), y: CGFloat(last.y) + (scalestep * CGFloat(ystep[i % 4]))).toInt()

if i + 1 == turns {
curr = CGPoint(x: CGFloat(curr.x) - (md * CGFloat(xstep[i % 4])), y: CGFloat(curr.y) - (md * CGFloat(ystep[i % 4]))).toInt()
}

path.addLineToPoint(curr)
last = curr
}
return path
}
}

func setupAnimation(color: UIColor) {
if fgLayer == nil {

let foreground = shapeLayerWithLogoPath(color, lineJoin: kCALineJoinMiter)
self.fgLayer = foreground
self.layer.addSublayer(foreground)
}
pathAnimationIn = CABasicAnimation(keyPath: "strokeEnd")
pathAnimationIn.fromValue = self.startPos
pathAnimationIn.toValue = self.endPos
pathAnimationIn.duration = self.duration / 2
pathAnimationIn.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)

pathAnimationOut = CABasicAnimation(keyPath: "strokeStart")
pathAnimationOut.fromValue = self.startPos
pathAnimationOut.toValue = self.endPos
pathAnimationOut.duration = self.duration / 2
pathAnimationOut.beginTime = self.duration / 2
pathAnimationOut.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)

pathAnimationGroup = CAAnimationGroup()
pathAnimationGroup.animations = [pathAnimationIn, pathAnimationOut]
pathAnimationGroup.duration = self.duration
pathAnimationGroup.repeatCount = self.repeatCount
pathAnimationGroup.removedOnCompletion = false
pathAnimationGroup.fillMode = kCAFillModeBackwards
}

public func show(completionHandler: (() -> Void)? = nil) {
self.startAnimation()

self.fgLayer?.opacity = 1
self.bgLayer?.opacity = 1
self.fgLayer.opacity = 1
self.bgLayer.opacity = 1

self.fgLayer?.addAnimation(self.fadeInAnimation, forKey: "fade")
self.bgLayer?.addAnimation(self.fadeInAnimation, forKey: "fade")
self.fgLayer.addAnimation(self.fadeInAnimation, forKey: "fade")
self.bgLayer.addAnimation(self.fadeInAnimation, forKey: "fade")

dispatch_after(self.fadeDuration, dispatch_get_main_queue()) {
completionHandler?()
}
}

public func hide(completionHandler: (() -> Void)? = nil) {
self.fgLayer?.opacity = 0
self.bgLayer?.opacity = 0
self.fgLayer.opacity = 0
self.bgLayer.opacity = 0

self.fgLayer?.addAnimation(self.fadeOutAnimation, forKey: "fade")
self.bgLayer?.addAnimation(self.fadeOutAnimation, forKey: "fade")
self.fgLayer.addAnimation(self.fadeOutAnimation, forKey: "fade")
self.bgLayer.addAnimation(self.fadeOutAnimation, forKey: "fade")

dispatch_after(self.fadeDuration, dispatch_get_main_queue()) {
self.fgLayer?.removeAllAnimations()
self.fgLayer.removeAllAnimations()
completionHandler?()
}
}

func startAnimation() {
self.fgLayer?.removeAllAnimations()
self.fgLayer?.addAnimation(pathAnimationGroup, forKey: "group")
self.fgLayer.removeAllAnimations()
self.fgLayer.addAnimation(pathAnimationGroup, forKey: "group")
}

func endAnimation() {
self.fgLayer?.removeAllAnimations()
}

func shapeLayerWithLogoPath(strokeColor: UIColor, lineJoin: String) -> CAShapeLayer {
let shapeLayer = CAShapeLayer()
shapeLayer.path = logoPath.CGPath
shapeLayer.strokeColor = strokeColor.CGColor
shapeLayer.fillColor = nil
if lineWidth == nil {
shapeLayer.lineWidth = self.strokeRatio
} else {
shapeLayer.lineWidth = self.lineWidth!
}
shapeLayer.lineJoin = lineJoin
return shapeLayer
}

func addBackground(color: UIColor) {
if bgLayer == nil {
let background = shapeLayerWithLogoPath(color, lineJoin: kCALineJoinMiter)
self.bgLayer = background
self.layer.addSublayer(background)
}
}

override public func needsUpdateConstraints() -> Bool {
return true
self.fgLayer.removeAllAnimations()
}

}

0 comments on commit 6e903a9

Please sign in to comment.