You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

100 lines
3.8 KiB

2 years ago
2 years ago
2 years ago
  1. //
  2. // ItemsExtension.swift
  3. // lottie-swift
  4. //
  5. // Created by Brandon Withrow on 1/18/19.
  6. //
  7. import Foundation
  8. // MARK: - NodeTree
  9. final class NodeTree {
  10. var rootNode: AnimatorNode? = nil
  11. var transform: ShapeTransform? = nil
  12. var renderContainers: [ShapeContainerLayer] = []
  13. var paths: [PathOutputNode] = []
  14. var childrenNodes: [AnimatorNode] = []
  15. }
  16. extension Array where Element == ShapeItem {
  17. func initializeNodeTree() -> NodeTree {
  18. let nodeTree = NodeTree()
  19. for item in self {
  20. guard item.hidden == false, item.type != .unknown else { continue }
  21. if let fill = item as? Fill {
  22. let node = FillNode(parentNode: nodeTree.rootNode, fill: fill)
  23. nodeTree.rootNode = node
  24. nodeTree.childrenNodes.append(node)
  25. } else if let stroke = item as? Stroke {
  26. let node = StrokeNode(parentNode: nodeTree.rootNode, stroke: stroke)
  27. nodeTree.rootNode = node
  28. nodeTree.childrenNodes.append(node)
  29. } else if let gradientFill = item as? GradientFill {
  30. let node = GradientFillNode(parentNode: nodeTree.rootNode, gradientFill: gradientFill)
  31. nodeTree.rootNode = node
  32. nodeTree.childrenNodes.append(node)
  33. } else if let gradientStroke = item as? GradientStroke {
  34. let node = GradientStrokeNode(parentNode: nodeTree.rootNode, gradientStroke: gradientStroke)
  35. nodeTree.rootNode = node
  36. nodeTree.childrenNodes.append(node)
  37. } else if let ellipse = item as? Ellipse {
  38. let node = EllipseNode(parentNode: nodeTree.rootNode, ellipse: ellipse)
  39. nodeTree.rootNode = node
  40. nodeTree.childrenNodes.append(node)
  41. } else if let rect = item as? Rectangle {
  42. let node = RectangleNode(parentNode: nodeTree.rootNode, rectangle: rect)
  43. nodeTree.rootNode = node
  44. nodeTree.childrenNodes.append(node)
  45. } else if let star = item as? Star {
  46. switch star.starType {
  47. case .none:
  48. continue
  49. case .polygon:
  50. let node = PolygonNode(parentNode: nodeTree.rootNode, star: star)
  51. nodeTree.rootNode = node
  52. nodeTree.childrenNodes.append(node)
  53. case .star:
  54. let node = StarNode(parentNode: nodeTree.rootNode, star: star)
  55. nodeTree.rootNode = node
  56. nodeTree.childrenNodes.append(node)
  57. }
  58. } else if let shape = item as? Shape {
  59. let node = ShapeNode(parentNode: nodeTree.rootNode, shape: shape)
  60. nodeTree.rootNode = node
  61. nodeTree.childrenNodes.append(node)
  62. } else if let trim = item as? Trim {
  63. let node = TrimPathNode(parentNode: nodeTree.rootNode, trim: trim, upstreamPaths: nodeTree.paths)
  64. nodeTree.rootNode = node
  65. nodeTree.childrenNodes.append(node)
  66. } else if let xform = item as? ShapeTransform {
  67. nodeTree.transform = xform
  68. continue
  69. } else if let group = item as? Group {
  70. let tree = group.items.initializeNodeTree()
  71. let node = GroupNode(name: group.name, parentNode: nodeTree.rootNode, tree: tree)
  72. nodeTree.rootNode = node
  73. nodeTree.childrenNodes.append(node)
  74. /// Now add all child paths to current tree
  75. nodeTree.paths.append(contentsOf: tree.paths)
  76. nodeTree.renderContainers.append(node.container)
  77. } else if item is Repeater {
  78. LottieLogger.shared.warn("""
  79. The Main Thread rendering engine doesn't currently support repeaters.
  80. To play an animation with repeaters, you can use the Core Animation rendering engine instead.
  81. """)
  82. }
  83. if let pathNode = nodeTree.rootNode as? PathNode {
  84. //// Add path container to the node tree
  85. nodeTree.paths.append(pathNode.pathOutput)
  86. }
  87. if let renderNode = nodeTree.rootNode as? RenderNode {
  88. nodeTree.renderContainers.append(ShapeRenderLayer(renderer: renderNode.renderer))
  89. }
  90. }
  91. return nodeTree
  92. }
  93. }