SpriteKit at times can seem a little rudimentary – small tasks can seem to take longer than they should! Today I ran into a limitation of SKShapeNodes – there doesn’t seem to be a default way to set up a gradient fill. I have created an extension to SKTexture to generate a gradient – you can then use this SKTexture in a SKShapeNode (fillTexture) or a SKSpriteNode.
Credit to an Objective C class developed by Joseph Preiss that I found here and heavily based my Swift version on. I made it an extension of SKTexture and added gradient direction.
enum GradientDirection { case up case left case upLeft case upRight } extension SKTexture { convenience init(size:CGSize,color1:CIColor,color2:CIColor,direction:GradientDirection = .up) { let coreImageContext = CIContext(options: nil) let gradientFilter = CIFilter(name: "CILinearGradient") gradientFilter.setDefaults() var startVector:CIVector var endVector:CIVector switch direction { case .up: startVector = CIVector(x: size.width/2, y: 0) endVector = CIVector(x: size.width/2, y: size.height) case .left: startVector = CIVector(x: size.width, y: size.height/2) endVector = CIVector(x: 0, y: size.height/2) case .upLeft: startVector = CIVector(x: size.width, y: 0) endVector = CIVector(x: 0, y: size.height) case .upRight: startVector = CIVector(x: 0, y: 0) endVector = CIVector(x: size.width, y: size.height) } gradientFilter.setValue(startVector, forKey: "inputPoint0") gradientFilter.setValue(endVector, forKey: "inputPoint1") gradientFilter.setValue(color1, forKey: "inputColor0") gradientFilter.setValue(color2, forKey: "inputColor1") let cgimg = coreImageContext.createCGImage(gradientFilter.outputImage, fromRect: CGRect(x: 0, y: 0, width: size.width, height: size.height)) self.init(CGImage:cgimg) } }
Leave a Reply