I am having trouble figuring out how the fillTexture
property of an SKShapeNode
works when rotating that node. In this example I create a fan of 4 rotating blades around the center. The texture applied however varies in intensity as the blades rotate. Why? I want the gradient texture application be invariable with rotation.
func buildBackground() {
let bg = SKShapeNode.init(rect: UIScreen.main.bounds)
bg.fillColor = .orange
self.addChild(bg) // self == SKScene
let size = UIScreen.main.bounds.size
let fan = SKNode.init()
let H = size.height
let W = size.width/2
let blades = 4
let triangle = CGMutablePath.init()
triangle.move(to: .zero)
triangle.addLine(to: CGPoint(-W,H))
triangle.addLine(to: CGPoint(+W,H))
triangle.addLine(to: .zero)
triangle.closeSubpath()
let da = 360.0/CGFloat(blades)
var r : CGFloat = 0
let texture = SKTexture.init(size: size, color0: .white, color1: .clear, radius0: 0.25, radius1: 1)
for i in 0..<blades {
let blade = SKShapeNode.init(path: triangle)
fan.addChild(blade)
blade.fillTexture = texture
blade.lineWidth = 0
blade.fillColor = .black
blade.zRotation = r.degreesToRadians
r += da
}
bg.addChild(fan)
fan.position = bg.frame.center
fan.run(.repeatForever(.rotate(byAngle: -0.1, duration: 0.2)))
fan.alpha = 0.5
}
public extension SKTexture {
convenience init(size : CGSize,
color0 : SKColor,
color1 : SKColor,
radius0 : CGFloat, // 0
radius1 : CGFloat) // 1
{
let coreImageContext = CIContext(options: nil)
let gradientFilter = CIFilter(name: "CIRadialGradient")!
let inputCenter = CIVector.init(x: size.width/2, y: size.height/2)
let inputRadius0 = radius0 * size.diagonal/2
let inputRadius1 = radius1 * size.diagonal/2
gradientFilter.setDefaults()
gradientFilter.setValue(inputCenter, forKey: "inputCenter")
gradientFilter.setValue(inputRadius0, forKey: "inputRadius0")
gradientFilter.setValue(inputRadius1, forKey: "inputRadius1")
gradientFilter.setValue(color0.asCIColor, forKey: "inputColor0")
gradientFilter.setValue(color1.asCIColor, forKey: "inputColor1")
let coreImage = coreImageContext.createCGImage(gradientFilter.outputImage!, from: .init(size)) //CGRect(x: 0, y: 0, width: size.width, height: size.height))
self.init(cgImage: coreImage!)
}
}