Skip to content

Commit

Permalink
Add fillMode support to GradientFill shape items (#1702)
Browse files Browse the repository at this point in the history
  • Loading branch information
calda authored Aug 4, 2022
1 parent 4cd4140 commit 10e0710
Show file tree
Hide file tree
Showing 6 changed files with 25 additions and 0 deletions.
1 change: 1 addition & 0 deletions Sources/Private/CoreAnimation/Layers/ShapeItemLayer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ final class ShapeItemLayer: BaseAnimationLayer {
pathMultiplier: 1)

if let (gradientFill, context) = otherItems.first(GradientFill.self, context: context) {
layers.shapeMaskLayer.fillRule = gradientFill.fillRule.caFillRule
try layers.gradientColorLayer.addGradientAnimations(for: gradientFill, type: .rgb, context: context)
try layers.gradientAlphaLayer?.addGradientAnimations(for: gradientFill, type: .alpha, context: context)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,11 @@ final class GradientFillRenderer: PassThroughOutputNode, Renderable {
}
}

var fillRule: CAShapeLayerFillRule {
get { maskLayer.fillRule }
set { maskLayer.fillRule = newValue }
}

func render(_: CGContext) {
// do nothing
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ final class GradientFillProperties: NodePropertyMap, KeypathSearchable {
colors = NodeProperty(provider: KeyframeInterpolator(keyframes: gradientfill.colors.keyframes))
gradientType = gradientfill.gradientType
numberOfColors = gradientfill.numberOfColors
fillRule = gradientfill.fillRule
keypathProperties = [
"Opacity" : opacity,
"Start Point" : startPoint,
Expand All @@ -42,6 +43,7 @@ final class GradientFillProperties: NodePropertyMap, KeypathSearchable {

let gradientType: GradientType
let numberOfColors: Int
let fillRule: FillRule

let keypathProperties: [String: AnyNodeProperty]
let properties: [AnyNodeProperty]
Expand Down Expand Up @@ -98,5 +100,6 @@ final class GradientFillNode: AnimatorNode, RenderNode {
fillRender.colors = fillProperties.colors.value.map { CGFloat($0) }
fillRender.type = fillProperties.gradientType
fillRender.numberOfColors = fillProperties.numberOfColors
fillRender.fillRule = fillProperties.fillRule.caFillRule
}
}
1 change: 1 addition & 0 deletions Sources/Private/Model/ShapeItems/Fill.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ final class Fill: ShapeItem {
/// The color keyframes for the fill
let color: KeyframeGroup<Color>

/// The fill rule to use when filling a path
let fillRule: FillRule

override func encode(to encoder: Encoder) throws {
Expand Down
14 changes: 14 additions & 0 deletions Sources/Private/Model/ShapeItems/GradientFill.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ final class GradientFill: ShapeItem {
gradientType = try container.decode(GradientType.self, forKey: .gradientType)
highlightLength = try container.decodeIfPresent(KeyframeGroup<Vector1D>.self, forKey: .highlightLength)
highlightAngle = try container.decodeIfPresent(KeyframeGroup<Vector1D>.self, forKey: .highlightAngle)
fillRule = try container.decodeIfPresent(FillRule.self, forKey: .fillRule) ?? .nonZeroWinding
let colorsContainer = try container.nestedContainer(keyedBy: GradientDataKeys.self, forKey: .colors)
colors = try colorsContainer.decode(KeyframeGroup<[Double]>.self, forKey: .colors)
numberOfColors = try colorsContainer.decode(Int.self, forKey: .numberOfColors)
Expand Down Expand Up @@ -61,6 +62,14 @@ final class GradientFill: ShapeItem {
let nestedColorsDictionary: [String: Any] = try colorsDictionary.value(for: GradientDataKeys.colors)
colors = try KeyframeGroup<[Double]>(dictionary: nestedColorsDictionary)
numberOfColors = try colorsDictionary.value(for: GradientDataKeys.numberOfColors)
if
let fillRuleRawValue = dictionary[CodingKeys.fillRule.rawValue] as? Int,
let fillRule = FillRule(rawValue: fillRuleRawValue)
{
self.fillRule = fillRule
} else {
fillRule = .nonZeroWinding
}
try super.init(dictionary: dictionary)
}

Expand Down Expand Up @@ -90,6 +99,9 @@ final class GradientFill: ShapeItem {
/// The Colors of the gradient.
let colors: KeyframeGroup<[Double]>

/// The fill rule to use when filling a path
let fillRule: FillRule

override func encode(to encoder: Encoder) throws {
try super.encode(to: encoder)
var container = encoder.container(keyedBy: CodingKeys.self)
Expand All @@ -99,6 +111,7 @@ final class GradientFill: ShapeItem {
try container.encode(gradientType, forKey: .gradientType)
try container.encodeIfPresent(highlightLength, forKey: .highlightLength)
try container.encodeIfPresent(highlightAngle, forKey: .highlightAngle)
try container.encodeIfPresent(fillRule, forKey: .fillRule)
var colorsContainer = container.nestedContainer(keyedBy: GradientDataKeys.self, forKey: .colors)
try colorsContainer.encode(numberOfColors, forKey: .numberOfColors)
try colorsContainer.encode(colors, forKey: .colors)
Expand All @@ -114,6 +127,7 @@ final class GradientFill: ShapeItem {
case highlightLength = "h"
case highlightAngle = "a"
case colors = "g"
case fillRule = "r"
}

private enum GradientDataKeys: String, CodingKey {
Expand Down
1 change: 1 addition & 0 deletions Tests/Samples/Issues/issue_1541.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"ip":0,"fr":60,"v":"5.1.20","assets":[],"layers":[{"ty":4,"nm":"header-icon","ip":0,"st":0,"ind":7,"hix":3,"ks":{"o":{"a":1,"k":[{"t":0,"s":[0],"e":[100],"i":{"x":[0.515],"y":[0.955]},"o":{"x":[0.455],"y":[0.03]}},{"t":28,"s":[100],"e":[100],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":69,"s":[100],"e":[0],"i":{"x":[0.515],"y":[0.955]},"o":{"x":[0.455],"y":[0.03]}},{"t":87}]},"or":{"a":0,"k":[0,0,0]},"a":{"a":0,"k":[45.5,51.5,0]},"p":{"s":true,"x":{"a":0,"k":164.5},"y":{"a":1,"k":[{"t":0,"s":[110],"e":[53.5],"i":{"x":[0.515],"y":[0.955]},"o":{"x":[0.455],"y":[0.03]}},{"t":28,"s":[53.5],"e":[53.5],"i":{"x":[1],"y":[1]},"o":{"x":[0],"y":[0]}},{"t":69,"s":[53.5],"e":[110],"i":{"x":[0.515],"y":[0.955]},"o":{"x":[0.455],"y":[0.03]}},{"t":87}]}},"rx":{"a":0,"k":0},"ry":{"a":0,"k":0},"rz":{"a":0,"k":0},"s":{"a":0,"k":[100,100,100]}},"shapes":[{"ty":"gr","nm":"header-icon shape group","it":[{"ty":"sh","ks":{"a":0,"k":{"c":true,"v":[[74.0312,20.0625],[74.0312,45.9375],[63.9688,56],[28.0312,56],[17.9688,45.9375],[17.9688,20.0625],[28.0312,10],[63.9688,10]],"i":[[0,-5.5573999999999995],[0,0],[5.557299999999998,0],[0,0],[0,5.557400000000001],[0,0],[-5.557299999999998,0],[0,0]],"o":[[0,0],[0,5.557400000000001],[0,0],[-5.557299999999998,0],[0,0],[0,-5.5573999999999995],[0,0],[5.557299999999998,0]]}}},{"ty":"sh","ks":{"a":0,"k":{"c":true,"v":[[28.0312,11.4375],[63.9688,11.4375],[72.5938,20.0625],[72.5938,27.9688],[63.6094,27.9688],[57.5,34.0781],[63.6094,40.1875],[72.5938,40.1875],[72.5938,45.9375],[63.9688,54.5625],[28.0312,54.5625],[19.4062,45.9375],[19.4062,20.0625]],"i":[[-4.763399999999997,0],[0,0],[0,-4.7635000000000005],[0,0],[0,0],[0,-3.3740999999999985],[-3.3740999999999985,0],[0,0],[0,0],[4.763400000000004,0],[0,0],[0,4.7635000000000005],[0,0]],"o":[[0,0],[4.763400000000004,0],[0,0],[0,0],[-3.3740999999999985,0],[0,3.3740999999999985],[0,0],[0,0],[0,4.7635000000000005],[0,0],[-4.763399999999997,0],[0,0],[0,-4.7635000000000005]]}}},{"ty":"sh","ks":{"a":0,"k":{"c":true,"v":[[63.6094,29.4062],[72.5938,29.4062],[72.5938,38.75],[63.6094,38.75],[58.9375,34.0781]],"i":[[-2.580199999999998,0],[0,0],[0,0],[0,0],[0,2.580199999999998]],"o":[[0,0],[0,0],[0,0],[-2.580199999999998,0],[0,-2.580199999999998]]}}},{"ty":"st","o":{"a":0,"k":0},"w":{"a":0,"k":0},"c":{"a":0,"k":[0,0,0,0]},"lc":3,"lj":1,"ml":1},{"ty":"gf","o":{"a":0,"k":100},"r":2,"g":{"p":2,"k":{"a":0,"k":[0.494792,0.5098039215686274,0.6862745098039216,0.8588235294117647,1,0.8784313725490196,0.4588235294117647,0.9607843137254902]}},"t":1,"s":{"a":0,"k":[17.9688,33]},"e":{"a":0,"k":[74.0313,33]}},{"ty":"tr","o":{"a":0,"k":100},"a":{"a":0,"k":[0,0]},"s":{"a":0,"k":[100,100]},"p":{"a":0,"k":[0,0]},"r":{"a":0,"k":0}}]}],"op":87}],"op":87,"w":327,"h":392}

0 comments on commit 10e0710

Please sign in to comment.