Skip to content

Instantly share code, notes, and snippets.

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 Kaji01/8592e9c7494a9d2c4d8b855a017c5707 to your computer and use it in GitHub Desktop.
Save Kaji01/8592e9c7494a9d2c4d8b855a017c5707 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
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment