Skip to content

Commit

Permalink
Add value provider for key path property ‘Colors’
Browse files Browse the repository at this point in the history
  • Loading branch information
enriquebk committed Oct 28, 2019
1 parent 76880a0 commit 47c43e7
Show file tree
Hide file tree
Showing 2 changed files with 145 additions and 0 deletions.
12 changes: 12 additions & 0 deletions Lottie.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -615,6 +615,11 @@
486E89F4220B790E007CD915 /* KeyframeExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 486E879E220B78BF007CD915 /* KeyframeExtensions.swift */; };
486E89F5220B790E007CD915 /* AnimationContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 486E87A0220B78BF007CD915 /* AnimationContext.swift */; };
48F4EECD229F167F00949A97 /* TextCompositionLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 486E8724220B78BF007CD915 /* TextCompositionLayer.swift */; };
CD1616482367325A00325353 /* ColorsValueProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD1616472367325A00325353 /* ColorsValueProvider.swift */; };
CD1616492367325A00325353 /* ColorsValueProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD1616472367325A00325353 /* ColorsValueProvider.swift */; };
CD16164A2367325A00325353 /* ColorsValueProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD1616472367325A00325353 /* ColorsValueProvider.swift */; };
CD16164B2367325A00325353 /* ColorsValueProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD1616472367325A00325353 /* ColorsValueProvider.swift */; };
CD16164C2367325A00325353 /* ColorsValueProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD1616472367325A00325353 /* ColorsValueProvider.swift */; };
E654753422AAA91600FE590F /* AnimationTextProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6EAA7B722AA834F00F345A4 /* AnimationTextProvider.swift */; };
E654753522AAA91600FE590F /* AnimationTextProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6EAA7B722AA834F00F345A4 /* AnimationTextProvider.swift */; };
E654753622AAA91700FE590F /* AnimationTextProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6EAA7B722AA834F00F345A4 /* AnimationTextProvider.swift */; };
Expand Down Expand Up @@ -774,6 +779,7 @@
486E879D220B78BF007CD915 /* Interpolatable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Interpolatable.swift; sourceTree = "<group>"; };
486E879E220B78BF007CD915 /* KeyframeExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyframeExtensions.swift; sourceTree = "<group>"; };
486E87A0220B78BF007CD915 /* AnimationContext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnimationContext.swift; sourceTree = "<group>"; };
CD1616472367325A00325353 /* ColorsValueProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ColorsValueProvider.swift; sourceTree = "<group>"; };
E654753822AAA9AD00FE590F /* LayerTextProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LayerTextProvider.swift; sourceTree = "<group>"; };
E6EAA7B722AA834F00F345A4 /* AnimationTextProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnimationTextProvider.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
Expand Down Expand Up @@ -969,6 +975,7 @@
486E871C220B78BF007CD915 /* FloatValueProvider.swift */,
486E871D220B78BF007CD915 /* SizeValueProvider.swift */,
486E871E220B78BF007CD915 /* PointValueProvider.swift */,
CD1616472367325A00325353 /* ColorsValueProvider.swift */,
);
path = ValueProviders;
sourceTree = "<group>";
Expand Down Expand Up @@ -1634,6 +1641,7 @@
486E87FB220B78D1007CD915 /* DashPattern.swift in Sources */,
486E87FC220B78D1007CD915 /* Transform.swift in Sources */,
486E87FD220B78D1007CD915 /* Mask.swift in Sources */,
CD1616482367325A00325353 /* ColorsValueProvider.swift in Sources */,
486E87FE220B78D1007CD915 /* Marker.swift in Sources */,
E6EAA7B822AA834F00F345A4 /* AnimationTextProvider.swift in Sources */,
486E87FF220B78D1007CD915 /* KeyedDecodingContainerExtensions.swift in Sources */,
Expand Down Expand Up @@ -1767,6 +1775,7 @@
486E8873220B78E4007CD915 /* Animation.swift in Sources */,
486E8874220B78E4007CD915 /* DashPattern.swift in Sources */,
486E8875220B78E4007CD915 /* Transform.swift in Sources */,
CD1616492367325A00325353 /* ColorsValueProvider.swift in Sources */,
486E8876220B78E4007CD915 /* Mask.swift in Sources */,
486E8877220B78E4007CD915 /* Marker.swift in Sources */,
486E8878220B78E4007CD915 /* KeyedDecodingContainerExtensions.swift in Sources */,
Expand Down Expand Up @@ -1882,6 +1891,7 @@
486E88E7220B78F4007CD915 /* ShapeLayerModel.swift in Sources */,
486E88E8220B78F4007CD915 /* Animation.swift in Sources */,
486E88E9220B78F4007CD915 /* DashPattern.swift in Sources */,
CD16164A2367325A00325353 /* ColorsValueProvider.swift in Sources */,
486E88EA220B78F4007CD915 /* Transform.swift in Sources */,
486E88EB220B78F4007CD915 /* Mask.swift in Sources */,
486E88EC220B78F4007CD915 /* Marker.swift in Sources */,
Expand Down Expand Up @@ -2027,6 +2037,7 @@
486E8961220B78FF007CD915 /* Animation.swift in Sources */,
486E8962220B78FF007CD915 /* DashPattern.swift in Sources */,
486E8963220B78FF007CD915 /* Transform.swift in Sources */,
CD16164B2367325A00325353 /* ColorsValueProvider.swift in Sources */,
486E8964220B78FF007CD915 /* Mask.swift in Sources */,
486E8965220B78FF007CD915 /* Marker.swift in Sources */,
486E8966220B78FF007CD915 /* KeyedDecodingContainerExtensions.swift in Sources */,
Expand Down Expand Up @@ -2142,6 +2153,7 @@
486E89D4220B790E007CD915 /* PreCompLayerModel.swift in Sources */,
486E89D5220B790E007CD915 /* ShapeLayerModel.swift in Sources */,
486E89D6220B790E007CD915 /* Animation.swift in Sources */,
CD16164C2367325A00325353 /* ColorsValueProvider.swift in Sources */,
486E89D7220B790E007CD915 /* DashPattern.swift in Sources */,
486E89D8220B790E007CD915 /* Transform.swift in Sources */,
486E89D9220B790E007CD915 /* Mask.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
//
// ColorsValueProvider.swift
// lottie-swift
//
// Created by Enrique Bermúdez on 10/27/19.
//

import Foundation
import CoreGraphics

/// A `ValueProvider` that returns a Gradient Color Value.
public final class ColorsValueProvider: AnyValueProvider {

/// Returns a [Color] for a CGFloat(Frame Time).
public typealias ColorsValueBlock = (CGFloat) -> [Color]
/// Returns a [Double](Color locations) for a CGFloat(Frame Time).
public typealias ColorLocationsBlock = (CGFloat) -> [Double]

/// The colors values of the provider.
public var colors: [Color] {
didSet {
hasUpdate = true
}
}

/// The color location values of the provider.
public var locations: [Double] {
didSet {
hasUpdate = true
}
}

/// Initializes with a block provider.
public init(block: @escaping ColorsValueBlock,
locations: ColorLocationsBlock? = nil) {
self.block = block
self.locationsBlock = locations
self.colors = []
self.locations = []
}

/// Initializes with an array of colors.
public init(_ colors: [Color],
locations: [Double] = []) {
self.colors = colors
self.locations = locations
hasUpdate = true
}

// MARK: ValueProvider Protocol

public var valueType: Any.Type {
return [Double].self
}

public func hasUpdate(frame: CGFloat) -> Bool {
if block != nil || locationsBlock != nil {
return true
}
return hasUpdate
}

public func value(frame: CGFloat) -> Any {
hasUpdate = false
let newColors: [Color]
if let block = block {
newColors = block(frame)
} else {
newColors = colors
}

let newLocations: [Double]
if let colorLocationsBlock = locationsBlock {
newLocations = colorLocationsBlock(frame)
} else {
newLocations = locations
}

return self.value(from: newColors, locations: newLocations)
}

// MARK: Private

func value(from colors: [Color], locations: [Double]) -> [Double] {

var colorValues = [Double]()
var alphaValues = [Double]()
var shouldAddAlphaValues = false

for i in 0..<colors.count {

if colors[i].a < 1 { shouldAddAlphaValues = true }

let location = locations.count > i ? locations[i] :
calculateLocation(withStartValue: locations.last ?? 0.0,
endValue: 1.0,
elements: colors.count - locations.count,
position: i - locations.count,
skipStartValue: locations.count > 0)

colorValues.append(location)
colorValues.append(colors[i].r)
colorValues.append(colors[i].g)
colorValues.append(colors[i].b)

alphaValues.append(location)
alphaValues.append(colors[i].a)
}

return colorValues + (shouldAddAlphaValues ? alphaValues : [])
}

private func calculateLocation(withStartValue startValue: Double,
endValue: Double,
elements: Int,
position: Int,
skipStartValue: Bool) -> Double{

guard startValue != endValue else { return 1.0 }

let strides = (elements - 1) + (skipStartValue ? 1 : 0)
let index = position + (skipStartValue ? 1 : 0)

return Array(stride(from: startValue,
through: endValue,
by: (endValue - startValue) / Double(strides)))[index]
}

private var hasUpdate: Bool = true

private var block: ColorsValueBlock?
private var locationsBlock: ColorLocationsBlock?
}

0 comments on commit 47c43e7

Please sign in to comment.