164 lines
4.0 KiB
Swift
164 lines
4.0 KiB
Swift
//
|
|
// ShapeItem.swift
|
|
// lottie-swift
|
|
//
|
|
// Created by Brandon Withrow on 1/8/19.
|
|
//
|
|
|
|
import Foundation
|
|
|
|
// MARK: - ShapeType + ClassFamily
|
|
|
|
/// Used for mapping a heterogeneous list to classes for parsing.
|
|
extension ShapeType: ClassFamily {
|
|
|
|
static var discriminator: Discriminator = .type
|
|
|
|
func getType() -> AnyObject.Type {
|
|
switch self {
|
|
case .ellipse:
|
|
return Ellipse.self
|
|
case .fill:
|
|
return Fill.self
|
|
case .gradientFill:
|
|
return GradientFill.self
|
|
case .group:
|
|
return Group.self
|
|
case .gradientStroke:
|
|
return GradientStroke.self
|
|
case .merge:
|
|
return Merge.self
|
|
case .rectangle:
|
|
return Rectangle.self
|
|
case .repeater:
|
|
return Repeater.self
|
|
case .shape:
|
|
return Shape.self
|
|
case .star:
|
|
return Star.self
|
|
case .stroke:
|
|
return Stroke.self
|
|
case .trim:
|
|
return Trim.self
|
|
case .transform:
|
|
return ShapeTransform.self
|
|
default:
|
|
return ShapeItem.self
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: - ShapeType
|
|
|
|
enum ShapeType: String, Codable {
|
|
case ellipse = "el"
|
|
case fill = "fl"
|
|
case gradientFill = "gf"
|
|
case group = "gr"
|
|
case gradientStroke = "gs"
|
|
case merge = "mm"
|
|
case rectangle = "rc"
|
|
case repeater = "rp"
|
|
case round = "rd"
|
|
case shape = "sh"
|
|
case star = "sr"
|
|
case stroke = "st"
|
|
case trim = "tm"
|
|
case transform = "tr"
|
|
case unknown
|
|
|
|
public init(from decoder: Decoder) throws {
|
|
self = try ShapeType(rawValue: decoder.singleValueContainer().decode(RawValue.self)) ?? .unknown
|
|
}
|
|
}
|
|
|
|
// MARK: - ShapeItem
|
|
|
|
/// An item belonging to a Shape Layer
|
|
class ShapeItem: Codable, DictionaryInitializable {
|
|
|
|
// MARK: Lifecycle
|
|
|
|
required init(from decoder: Decoder) throws {
|
|
let container = try decoder.container(keyedBy: ShapeItem.CodingKeys.self)
|
|
name = try container.decodeIfPresent(String.self, forKey: .name) ?? "Layer"
|
|
type = try container.decode(ShapeType.self, forKey: .type)
|
|
hidden = try container.decodeIfPresent(Bool.self, forKey: .hidden) ?? false
|
|
}
|
|
|
|
required init(dictionary: [String: Any]) throws {
|
|
name = (try? dictionary.value(for: CodingKeys.name)) ?? "Layer"
|
|
type = ShapeType(rawValue: try dictionary.value(for: CodingKeys.type)) ?? .unknown
|
|
hidden = (try? dictionary.value(for: CodingKeys.hidden)) ?? false
|
|
}
|
|
|
|
init(
|
|
name: String,
|
|
type: ShapeType,
|
|
hidden: Bool)
|
|
{
|
|
self.name = name
|
|
self.type = type
|
|
self.hidden = hidden
|
|
}
|
|
|
|
// MARK: Internal
|
|
|
|
/// The name of the shape
|
|
let name: String
|
|
|
|
/// The type of shape
|
|
let type: ShapeType
|
|
|
|
let hidden: Bool
|
|
|
|
// MARK: Fileprivate
|
|
|
|
fileprivate enum CodingKeys: String, CodingKey {
|
|
case name = "nm"
|
|
case type = "ty"
|
|
case hidden = "hd"
|
|
}
|
|
}
|
|
|
|
extension Array where Element == ShapeItem {
|
|
|
|
static func fromDictionaries(_ dictionaries: [[String: Any]]) throws -> [ShapeItem] {
|
|
try dictionaries.compactMap { dictionary in
|
|
let shapeType = dictionary[ShapeItem.CodingKeys.type.rawValue] as? String
|
|
switch ShapeType(rawValue: shapeType ?? ShapeType.unknown.rawValue) {
|
|
case .ellipse:
|
|
return try Ellipse(dictionary: dictionary)
|
|
case .fill:
|
|
return try Fill(dictionary: dictionary)
|
|
case .gradientFill:
|
|
return try GradientFill(dictionary: dictionary)
|
|
case .group:
|
|
return try Group(dictionary: dictionary)
|
|
case .gradientStroke:
|
|
return try GradientStroke(dictionary: dictionary)
|
|
case .merge:
|
|
return try Merge(dictionary: dictionary)
|
|
case .rectangle:
|
|
return try Rectangle(dictionary: dictionary)
|
|
case .repeater:
|
|
return try Repeater(dictionary: dictionary)
|
|
case .shape:
|
|
return try Shape(dictionary: dictionary)
|
|
case .star:
|
|
return try Star(dictionary: dictionary)
|
|
case .stroke:
|
|
return try Stroke(dictionary: dictionary)
|
|
case .trim:
|
|
return try Trim(dictionary: dictionary)
|
|
case .transform:
|
|
return try ShapeTransform(dictionary: dictionary)
|
|
case .none:
|
|
return nil
|
|
default:
|
|
return try ShapeItem(dictionary: dictionary)
|
|
}
|
|
}
|
|
}
|
|
}
|