Search code examples
swiftsprite-kitskspritenodeskshapenode

How to apply a gradient to SKShapeNode created from a path


I am trying to apply a gradient texture to a SKShapeNode created from a path so that the line goes from a solid color to transparent. This works on a SKSpriteNode but i can't get it to work on SKShapeNode. Does anyone know a solution for this problem? Surely something basic like this should be possible?

I have tried all sorts of things. The most obvious one being that i tried to apply it as strokeTexture (see code below). This code demonstrates the gradient working on a SpriteNode, but the same texture giving different results on the ShapeNode.

I've tried to work around this issue by trying to use Shaders (but i couldn't get that to work either/similar issues). I've tried to fix a spriteNode to the shapeNode with a joint, but i couldn't get it to stick/fixed perfectly since, in my app, the line in question moves around (as a tangent line between 2 circles) and run in to orientation issues.

So, back to square one. I'm sure something this simple should be possible. Maybe i'm overlooking something?

Take this simplified code for example:

// create gradient texture (with help of https://github.com/maximbilan/SKTextureGradient/blob/master/SKTextureGradient.swift)
var testTexture = SKTexture(size: CGSize(width: 200, height: 1), color1: CIColor(red: 1.0, green: 0.0, blue: 1.0, alpha: 1.0), color2: CIColor(red: 1.0, green: 0.0, blue: 1.0, alpha: 0.0), direction: GradientDirection.Left)
// create path for shape node
var testPath = CGMutablePath()
testPath.move(to: CGPoint(x: 50, y: 200))
testPath.addLine(to: CGPoint(x: 250, y: 200))
testPath.closeSubpath()
// assign path to shape
var testLine = SKShapeNode()
testLine.path = testPath
testLine.lineWidth = 1
self.addChild(testLine)
// add gradient as strokeTexture
testLine.strokeColor = UIColor.white
testLine.strokeTexture = testTexture
// apply gradient to SKSpriteNode
var testSprite = SKSpriteNode()
testSprite.size = CGSize(width: 200, height: 1)
testSprite.position = CGPoint(x: 50 + (testSprite.frame.width / 2), y: 150)
testSprite.texture = testTexture
self.addChild(testSprite)

Which outputs something like this:

How do i get the first line (the SKShapeNode) to look like the second line (the SKSpriteNode)?


Solution

  • You really should thank me as I have to use an iPhone not simulator to do the try and error.

    testLine.isAntialiased = false
    

    will solve your problem.