Confused
Confused

Reputation: 6278

How to draw gradient with SKKeyframeSequence: as per Apple docs

The Apple docs on SKKeyframeSequence have brief sample code designed to create a gradient:

let colorSequence = SKKeyframeSequence(keyframeValues: [SKColor.green,
                                                        SKColor.yellow,
                                                        SKColor.red,
                                                        SKColor.blue],
                                       times: [0, 0.25, 0.5, 1])
colorSequence.interpolationMode = .linear
stride(from: 0, to: 1, by: 0.001).forEach {
    let color = colorSequence.sample(atTime: CGFloat($0)) as! SKColor
}

When combined with a drawing system of some sort, this is said to output this: enter image description here How can this be drawn from the sampling of the sequence of colours in the demo code?

ps I don't have any clue how to draw this with SpriteKit objects, hence the absence of attempted code. I'm not asking for code, just an answer on how to use this 'array' of colours to create a gradient that can be used as a texture in SpriteKit.

Upvotes: 5

Views: 576

Answers (1)

Fluidity
Fluidity

Reputation: 3995

The colors are different for some reason, but here is what I came up with using their source code:

PG setup:

import SpriteKit
import PlaygroundSupport

let sceneView = SKView(frame: CGRect(origin: CGPoint.zero, size: CGSize(width: 1000, height: 450)))
let scene     = SKScene(size: CGSize(width: 1000, height: 450))

LOADSCENE: do {
  scene.backgroundColor = .white
  scene.anchorPoint = CGPoint(x: 0, y: 0.5)
  scene.physicsWorld.gravity = CGVector.zero
  sceneView.presentScene(scene)

  PlaygroundPage.current.liveView = sceneView
}

Solution:

// Utility func:
func drawLine(from point1: CGPoint, to point2: CGPoint, color: SKColor) {
  let linePath = CGMutablePath()
  linePath.move(to: point1)
  linePath.addLine(to: point2)

  let newLine = SKShapeNode(path: linePath)
  newLine.strokeColor = color
  newLine.lineWidth = 1
  newLine.zPosition = 10
  scene.addChild(newLine)
  newLine.position.x = point1.x

}

// Holds our soon-to-be-generated colors:
var colors = [SKColor]()

LOADCOLORS: do {
  let colorSequence = SKKeyframeSequence(keyframeValues: [SKColor.green,
                                                          SKColor.yellow,
                                                          SKColor.red,
                                                          SKColor.blue],
                                         times: [0, 0.25, 0.5, 1])

  colorSequence.interpolationMode = .linear
  stride(from: 0, to: 1, by: 0.001).forEach {
    colors.append(colorSequence.sample(atTime: CGFloat($0)) as! SKColor)
  }
}

DRAWGRAD: do {
  for i in 1...999 {
    let p1 = CGPoint(x: CGFloat(i), y: scene.frame.minY)
    let p2 = CGPoint(x: CGFloat(i), y: scene.frame.maxY)
    drawLine(from: p1, to: p2, color: colors[i])
  }

  print("Give me my 25 cookie points, please and TY")
}

enter image description here

You should then be able to get this as a texture as such:

let texture = sceneView.texture(from: scene)

Rendering this took about a million years to render on my gen2 i5 at 2.6ghz for some reason. Will have to look into that, unless it was just a PG bug...

Upvotes: 5

Related Questions