Skip to content

Commit

Permalink
♻️ (New GEK): Improve Nodes code
Browse files Browse the repository at this point in the history
  • Loading branch information
HPezz authored and ladislas committed Dec 5, 2024
1 parent 7b0e0b4 commit 2a56bfb
Show file tree
Hide file tree
Showing 2 changed files with 151 additions and 108 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,65 +13,16 @@ public class DnDAnswerNode: SKSpriteNode {
init(id: String, value: String, type: ChoiceType, size: CGSize) {
self.id = id
self.type = type
switch type {
let texture: SKTexture = switch type {
case .text:
Self.createTextTexture(value: value, size: size)
case .image:
guard let path = Bundle.path(forImage: value), let image = UIImage(named: path) else {
fatalError("Image not found")
}

let renderer = UIGraphicsImageRenderer(size: size)
let finalImage = renderer.image { _ in
let rect = CGRect(origin: .zero, size: size)
let path = UIBezierPath(roundedRect: rect, cornerRadius: 10 / 57 * size.width)
path.addClip()
image.draw(in: rect)
}

let texture = SKTexture(image: finalImage)
super.init(texture: texture, color: .clear, size: texture.size())

Self.createImageTexture(value: value, size: size)
case .sfsymbol:
guard let image = UIImage(systemName: value, withConfiguration: UIImage.SymbolConfiguration(pointSize: size.height * 3)) else {
fatalError("SFSymbol not found")
}

super.init(texture: SKTexture(image: image), color: .clear, size: CGSize(width: size.width * 0.8, height: size.height * 0.8))

case .text:
let rectSize = CGSize(width: size.width, height: size.height)
let renderer = UIGraphicsImageRenderer(size: rectSize)
let finalImage = renderer.image { _ in
let rect = CGRect(origin: .zero, size: rectSize)

let path = UIBezierPath(roundedRect: rect, cornerRadius: 10 / 57 * size.width)
path.addClip()

UIColor.white.setFill()
path.fill()

UIColor.gray.setStroke()
let strokeWidth: CGFloat = 2
let borderRect = rect.insetBy(dx: strokeWidth / 2, dy: strokeWidth / 2)
let borderPath = UIBezierPath(roundedRect: borderRect, cornerRadius: 10 / 57 * size.width)
borderPath.stroke()

let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .center

let attributes: [NSAttributedString.Key: Any] = [
.font: UIFont(name: "AvenirNext-Bold", size: 20) ?? UIFont.systemFont(ofSize: 20),
.foregroundColor: UIColor.black,
.paragraphStyle: paragraphStyle,
]

let textRect = rect.insetBy(dx: 10, dy: (rect.height - 20) / 2)
(value as NSString).draw(in: textRect, withAttributes: attributes)
}

let texture = SKTexture(image: finalImage)
super.init(texture: texture, color: .clear, size: texture.size())
Self.createSFSymbolTexture(value: value, size: size)
}

super.init(texture: texture, color: .clear, size: texture.size())
self.name = value
self.zPosition = 10
}
Expand All @@ -87,6 +38,75 @@ public class DnDAnswerNode: SKSpriteNode {
let type: ChoiceType
var initialPosition: CGPoint?
var isDraggable = true

// MARK: Private

private static let cornerRadiusFactor: CGFloat = 10 / 57
private static let sizeFactorSFSymbol: CGFloat = 0.6
}

extension DnDAnswerNode {
private static func createImageTexture(value: String, size: CGSize) -> SKTexture {
guard let path = Bundle.path(forImage: value),
let image = UIImage(named: path)
else {
fatalError("Image not found")
}

let renderer = UIGraphicsImageRenderer(size: size)
let finalImage = renderer.image { _ in
let rect = CGRect(origin: .zero, size: size)
let path = UIBezierPath(roundedRect: rect, cornerRadius: cornerRadiusFactor * size.width)
path.addClip()
image.draw(in: rect)
}

return SKTexture(image: finalImage)
}

private static func createSFSymbolTexture(value: String, size: CGSize) -> SKTexture {
guard let image = UIImage(systemName: value,
withConfiguration: UIImage.SymbolConfiguration(pointSize: size.height * sizeFactorSFSymbol))
else {
fatalError("SFSymbol not found")
}

return SKTexture(image: image)
}

private static func createTextTexture(value: String, size: CGSize) -> SKTexture {
let rectSize = CGSize(width: size.width, height: size.height)
let renderer = UIGraphicsImageRenderer(size: rectSize)
let finalImage = renderer.image { _ in
let rect = CGRect(origin: .zero, size: rectSize)

let path = UIBezierPath(roundedRect: rect, cornerRadius: cornerRadiusFactor * size.width)
path.addClip()

UIColor.white.setFill()
path.fill()

UIColor.gray.setStroke()
let strokeWidth: CGFloat = 2
let borderRect = rect.insetBy(dx: strokeWidth / 2, dy: strokeWidth / 2)
let borderPath = UIBezierPath(roundedRect: borderRect, cornerRadius: cornerRadiusFactor * size.width)
borderPath.stroke()

let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .center

let attributes: [NSAttributedString.Key: Any] = [
.font: UIFont(name: "AvenirNext-Bold", size: 20) ?? UIFont.systemFont(ofSize: 20),
.foregroundColor: UIColor.black,
.paragraphStyle: paragraphStyle,
]

let textRect = rect.insetBy(dx: 10, dy: (rect.height - 20) / 2)
(value as NSString).draw(in: textRect, withAttributes: attributes)
}

return SKTexture(image: finalImage)
}
}

// MARK: - DnDUIChoices
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,71 +13,26 @@ public class DnDDropZoneNode: SKSpriteNode {
init(id: String, value: String, type: ChoiceType, position: CGPoint) {
self.id = id
let size = CGSize(width: 420, height: 315)
switch type {
let texture: SKTexture = switch type {
case .image:
guard let path = Bundle.path(forImage: value), let image = UIImage(named: path) else {
fatalError("Image not found")
}

super.init(texture: SKTexture(image: image), color: .clear, size: size)

Self.createImageTexture(value: value, size: size)
case .sfsymbol:
guard let image = UIImage(systemName: value, withConfiguration: UIImage.SymbolConfiguration(pointSize: size.height)) else {
fatalError("SFSymbol not found")
}

super.init(texture: SKTexture(image: image), color: .clear, size: size)

Self.createSFSymbolTexture(value: value, size: size)
case .text:
super.init(texture: nil, color: .clear, size: size)

let rectangle = SKShapeNode(
rect: CGRect(x: -size.width / 2, y: -size.height / 2, width: size.width, height: size.height),
cornerRadius: 10
)

rectangle.fillColor = .white
rectangle.strokeColor = .black
rectangle.lineWidth = 0.5
rectangle.zPosition = -1
rectangle.position = CGPoint(x: 0, y: 0)

self.addChild(rectangle)

let label = SKLabelNode(text: value)

label.fontSize = 20
label.fontName = "AvenirNext-Bold"
label.fontColor = .black
label.position = CGPoint(x: 0, y: -10)
label.zPosition = 0

self.addChild(label)
Self.createTextTexture(value: value, size: size)
}

super.init(texture: texture, color: .clear, size: size)
self.name = value
self.position = position
self.zPosition = 10
}

init(node: DnDAnswerNode, position: CGPoint = .zero) {
self.id = node.id
switch node.type {
case .text:
let image = DnDDropZoneNode.createRoundedRectImage(size: node.size)
let texture = SKTexture(image: image)

super.init(texture: texture, color: .clear, size: node.size)
self.position = position

case .sfsymbol,
.image:
let image = DnDDropZoneNode.createRoundedRectImage(size: node.size)
let texture = SKTexture(image: image)

super.init(texture: texture, color: .clear, size: node.size)
self.position = position
}
let image = DnDDropZoneNode.createRoundedRectImage(size: node.size)
let texture = SKTexture(image: image)
super.init(texture: texture, color: .clear, size: node.size)
self.position = position
}

Expand All @@ -94,6 +49,74 @@ public class DnDDropZoneNode: SKSpriteNode {

// MARK: Private

private static let cornerRadiusFactor: CGFloat = 10 / 57
private static let defaultSize = CGSize(width: 420, height: 315)
private static let borderWidth: CGFloat = 2.0
private static let labelFontSize: CGFloat = 20
private static let labelFontName = "AvenirNext-Bold"
private static let horizontalPadding: CGFloat = 10
}

extension DnDDropZoneNode {
private static func createImageTexture(value: String, size: CGSize) -> SKTexture {
guard let path = Bundle.path(forImage: value), let image = UIImage(named: path) else {
fatalError("Image not found")
}

let renderer = UIGraphicsImageRenderer(size: size)
let finalImage = renderer.image { _ in
let rect = CGRect(origin: .zero, size: size)
let path = UIBezierPath(roundedRect: rect, cornerRadius: cornerRadiusFactor * size.width)
path.addClip()
image.draw(in: rect)
}

return SKTexture(image: finalImage)
}

private static func createSFSymbolTexture(value: String, size: CGSize) -> SKTexture {
guard let image = UIImage(systemName: value, withConfiguration: UIImage.SymbolConfiguration(pointSize: size.height * 0.6)) else {
fatalError("SFSymbol not found")
}

return SKTexture(image: image)
}

private static func createTextTexture(value: String, size: CGSize) -> SKTexture {
let renderer = UIGraphicsImageRenderer(size: size)

let finalImage = renderer.image { _ in
let rect = CGRect(origin: .zero, size: size)

let roundedPath = UIBezierPath(roundedRect: rect, cornerRadius: cornerRadiusFactor * size.width)
roundedPath.addClip()
UIColor.white.setFill()
roundedPath.fill()

UIColor.gray.setStroke()
let borderRect = rect.insetBy(dx: self.borderWidth / 2, dy: self.borderWidth / 2)
let borderPath = UIBezierPath(roundedRect: borderRect, cornerRadius: cornerRadiusFactor * size.width - self.borderWidth / 2)
borderPath.lineWidth = self.borderWidth
borderPath.stroke()

let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .center

let attributes: [NSAttributedString.Key: Any] = [
.font: UIFont(name: self.labelFontName, size: self.labelFontSize) ?? UIFont.systemFont(ofSize: self.labelFontSize),
.foregroundColor: UIColor.black,
.paragraphStyle: paragraphStyle,
]

let textHeight = (attributes[.font] as? UIFont)?.lineHeight ?? self.labelFontSize
let textRect = rect.insetBy(dx: self.horizontalPadding, dy: (rect.height - textHeight) / 2)

(value as NSString).draw(in: textRect, withAttributes: attributes)
}

return SKTexture(image: finalImage)
}

private static let dropzoneBackgroundColor: UIColor = .init(
light: UIColor.white,
dark: UIColor(displayP3Red: 242 / 255, green: 242 / 255, blue: 247 / 255, alpha: 1.0)
Expand Down

0 comments on commit 2a56bfb

Please sign in to comment.