76 lines
2.4 KiB
Swift
76 lines
2.4 KiB
Swift
//
|
|
// PathElement.swift
|
|
// lottie-swift
|
|
//
|
|
// Created by Brandon Withrow on 1/11/19.
|
|
//
|
|
|
|
import CoreGraphics
|
|
import Foundation
|
|
|
|
/// A path section, containing one point and its length to the previous point.
|
|
///
|
|
/// The relationship between this path element and the previous is implicit.
|
|
/// Ideally a path section would be defined by two vertices and a length.
|
|
/// We don't do this however, as it would effectively double the memory footprint
|
|
/// of path data.
|
|
///
|
|
struct PathElement {
|
|
|
|
// MARK: Lifecycle
|
|
|
|
/// Initializes a new path with length of 0
|
|
init(vertex: CurveVertex) {
|
|
length = 0
|
|
self.vertex = vertex
|
|
}
|
|
|
|
/// Initializes a new path with length
|
|
private init(length: CGFloat, vertex: CurveVertex) {
|
|
self.length = length
|
|
self.vertex = vertex
|
|
}
|
|
|
|
// MARK: Internal
|
|
|
|
/// The absolute Length of the path element.
|
|
let length: CGFloat
|
|
|
|
/// The vertex of the element
|
|
let vertex: CurveVertex
|
|
|
|
/// Returns a new path element define the span from the receiver to the new vertex.
|
|
func pathElementTo(_ toVertex: CurveVertex) -> PathElement {
|
|
PathElement(length: vertex.distanceTo(toVertex), vertex: toVertex)
|
|
}
|
|
|
|
func updateVertex(newVertex: CurveVertex) -> PathElement {
|
|
PathElement(length: length, vertex: newVertex)
|
|
}
|
|
|
|
/// Splits an element span defined by the receiver and fromElement to a position 0-1
|
|
func splitElementAtPosition(fromElement: PathElement, atLength: CGFloat) ->
|
|
(leftSpan: (start: PathElement, end: PathElement), rightSpan: (start: PathElement, end: PathElement))
|
|
{
|
|
/// Trim the span. Start and trim go into the first, trim and end go into second.
|
|
let trimResults = fromElement.vertex.trimCurve(toVertex: vertex, atLength: atLength, curveLength: length, maxSamples: 3)
|
|
|
|
/// Create the elements for the break
|
|
let spanAStart = PathElement(
|
|
length: fromElement.length,
|
|
vertex: CurveVertex(
|
|
point: fromElement.vertex.point,
|
|
inTangent: fromElement.vertex.inTangent,
|
|
outTangent: trimResults.start.outTangent))
|
|
/// Recalculating the length here is a waste as the trimCurve function also accurately calculates this length.
|
|
let spanAEnd = spanAStart.pathElementTo(trimResults.trimPoint)
|
|
|
|
let spanBStart = PathElement(vertex: trimResults.trimPoint)
|
|
let spanBEnd = spanBStart.pathElementTo(trimResults.end)
|
|
return (
|
|
leftSpan: (start: spanAStart, end: spanAEnd),
|
|
rightSpan: (start: spanBStart, end: spanBEnd))
|
|
}
|
|
|
|
}
|