Skip to content

Instantly share code, notes, and snippets.

@Bersaelor
Created August 16, 2018 11:21
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Bersaelor/d6ea241278665173485e8aabafbe9047 to your computer and use it in GitHub Desktop.
Save Bersaelor/d6ea241278665173485e8aabafbe9047 to your computer and use it in GitHub Desktop.
ShadowLabelNode
// based on objective-c code Erica Sadun: https://github.com/erica/useful-things
import SpriteKit
fileprivate let shadowEffectNodeKey = "ShadowEffectNodeKey"
class ShadowLabelNode: SKLabelNode {
var offset : CGPoint = CGPoint(x: 1, y: -1) {
didSet { updateShadow() }
}
var shadowColor : UIColor = UIColor.darkGray.color(alpha: 0.8) {
didSet { updateShadow() }
}
var blurRadius : CGFloat = 3 {
didSet { updateShadow() }
}
private var hasObservers: Bool = false
override init() {
super.init()
for keyPath in ["text", "fontName", "fontSize", "verticalAlignmentMode", "horizontalAlignmentMode", "fontColor"] {
self.addObserver(self, forKeyPath: keyPath, options: NSKeyValueObservingOptions.new, context: nil)
}
self.updateShadow()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override init(fontNamed: String?) {
super.init(fontNamed: fontNamed)
for keyPath in ["text", "fontName", "fontSize", "verticalAlignmentMode", "horizontalAlignmentMode", "fontColor"] {
self.addObserver(self, forKeyPath: keyPath, options: NSKeyValueObservingOptions.new, context: nil)
}
self.updateShadow()
}
private func makeEffectNode() -> SKEffectNode {
let effectNode = SKEffectNode()
effectNode.name = "ShadowEffectNodeKey"
effectNode.shouldEnableEffects = true
effectNode.zPosition = -1
return effectNode
}
func updateShadow () {
let effectNode = self.childNode(withName: shadowEffectNodeKey) as? SKEffectNode ?? makeEffectNode()
let filter: CIFilter? = CIFilter(name: "CIGaussianBlur")
filter?.setDefaults();
filter?.setValue(blurRadius, forKey: "inputRadius")
effectNode.filter = filter
effectNode.removeAllChildren()
// Duplicate and offset the label
let labelNode = SKLabelNode(fontNamed: self.fontName)
labelNode.text = self.text
labelNode.fontSize = self.fontSize
labelNode.verticalAlignmentMode = self.verticalAlignmentMode
labelNode.horizontalAlignmentMode = self.horizontalAlignmentMode
labelNode.fontColor = shadowColor
labelNode.position = offset
effectNode.addChild(labelNode)
if effectNode.parent == nil {
self.addChild(effectNode)
}
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
self.updateShadow()
}
}
extension ShadowLabelNode {
// Removes all of the observers for the shadow node and the label itself.
func removeLabel () {
for keyPath in ["text", "fontName", "fontSize", "verticalAlignmentMode", "horizontalAlignmentMode", "fontColor"] {
self.removeObserver(self, forKeyPath: keyPath);
self.removeFromParent();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment