Skip to content

Instantly share code, notes, and snippets.

@johnnyw
Created February 23, 2018 07:44
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save johnnyw/e57969b7ede6237000e257ca2c22ef79 to your computer and use it in GitHub Desktop.
Save johnnyw/e57969b7ede6237000e257ca2c22ef79 to your computer and use it in GitHub Desktop.
[SpriteKit] Custom SKAction to transition the fill/stroke color of an SKShapeNode.
import CoreGraphics
import SpriteKit
extension SKAction {
static func transitionStrokeColor(from: SKColor, to: SKColor, duration: TimeInterval) -> SKAction {
return transitionColor(from: from, to: to, duration: duration, fill: false)
}
static func transitionFillColor(from: SKColor, to: SKColor, duration: TimeInterval) -> SKAction {
return transitionColor(from: from, to: to, duration: duration, fill: true)
}
static func transitionColor(from: SKColor, to: SKColor, duration: TimeInterval, fill: Bool) -> SKAction {
var fromRed: CGFloat = 0
var fromGreen: CGFloat = 0
var fromBlue: CGFloat = 0
var fromAlpha: CGFloat = 0
from.getRed(&fromRed, green: &fromGreen, blue: &fromBlue, alpha: &fromAlpha)
var toRed: CGFloat = 0
var toGreen: CGFloat = 0
var toBlue: CGFloat = 0
var toAlpha: CGFloat = 0
to.getRed(&toRed, green: &toGreen, blue: &toBlue, alpha: &toAlpha)
return SKAction.customAction(withDuration: duration, actionBlock: { (node, elapsed) in
guard let shapeNode = node as? SKShapeNode else { fatalError("Can only use SKAction.transitionColor(from:to:duration:fill) on an SKShapeNode.") }
let step: CGFloat = elapsed / CGFloat(duration)
let r = CGFloat.lerp(from: fromRed, to: toRed, step: step)
let g = CGFloat.lerp(from: fromGreen, to: toGreen, step: step)
let b = CGFloat.lerp(from: fromBlue, to: toBlue, step: step)
let a = CGFloat.lerp(from: fromAlpha, to: toAlpha, step: step)
let color = UIColor(red: r, green: g, blue: b, alpha: a)
if fill {
shapeNode.fillColor = color
} else {
shapeNode.strokeColor = color
}
})
}
}
extension CGFloat {
static func lerp(from: CGFloat, to: CGFloat, step: CGFloat) -> CGFloat {
return (1.0 - step) * from + step * to
}
}
@Kaji01
Copy link

Kaji01 commented Aug 12, 2020

Works like a charm. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment