-
-
Notifications
You must be signed in to change notification settings - Fork 3.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support to TextProviders
for CoreAnimation
#1723
Changes from 5 commits
5436bf7
ba40ed1
f4fe478
ae4e887
2632390
b542f66
01307aa
5055f10
a053713
31f3bf9
7a71e9a
c8a84c2
c7a21ce
ff77091
77bb6ba
8cb4ccd
8bbf3c9
1d50bef
913e1da
de65cbb
b2309b6
8be6a68
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
|
@@ -23,6 +23,22 @@ final class TextLayer: BaseCompositionLayer { | |||
fatalError("init(coder:) has not been implemented") | ||||
} | ||||
|
||||
override func setupAnimations(context: LayerAnimationContext) throws { | ||||
try super.setupAnimations(context: context) | ||||
|
||||
// Question 1: Which keypath to pass? | ||||
_ = try context.currentKeypath.keys.map { key in | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should pass the entire keypath here, e.g. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think we need this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Got rid of it in c8a84c2 β |
||||
// Question 2: Where do we get the text layer text? | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Due to limitations of Core Animation text rendering, this text layer only supports displaying a static text value over the entire animation. That's why we extract a single string from the keyframes using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updated the method in 5055f10 π‘
Do you mean that text won't be able to be animated in the end anyway, or that just the text can't be changed during the animation? Like we can't start animation with text "Hell.." and finish it with "Hello!" π€ |
||||
let customText = context.textProvider.textFor(keypathName: key, sourceText: "text layer text") | ||||
if customText.isEmpty { | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think we need this lottie-ios/Sources/Private/MainThread/LayerContainers/CompLayers/TextCompositionLayer.swift Line 115 in 167812e
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updated the method in 5055f10 π‘ Okay, I see. But then I just don't understand how do we actually decide when to set this: and when do this:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we always just do There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay, then it is this way already in the code! π |
||||
renderLayer.text = customText | ||||
} else { | ||||
renderLayer.text = try textLayerModel.text.exactlyOneKeyframe(context: context, description: "text layer text").text | ||||
} | ||||
} | ||||
} | ||||
|
||||
|
||||
/// Called by CoreAnimation to create a shadow copy of this layer | ||||
/// More details: https://developer.apple.com/documentation/quartzcore/calayer/1410842-init | ||||
override init(layer: Any) { | ||||
|
@@ -48,6 +64,9 @@ final class TextLayer: BaseCompositionLayer { | |||
// - We may be able to support animating `fillColor` by getting clever with layer blend modes | ||||
// or masks (e.g. use `CoreTextRenderLayer` to draw black glyphs, and then fill them in | ||||
// using a `CAShapeLayer`). | ||||
|
||||
// Question 3: Should we somehow initialize LayerContextAnimations at this stage | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we can remove the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right! Fixed in 01307aa β |
||||
// and pass it to `self.setupAnimations(context: layerAnimationsContext)` | ||||
if !textLayerModel.animators.isEmpty { | ||||
try context.logCompatibilityIssue(""" | ||||
The Core Animation rendering engine currently doesn't support text animators. | ||||
|
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -22,6 +22,9 @@ struct SnapshotConfiguration { | |||||
/// A custom `AnimationImageProvider` to use when rendering this animation | ||||||
var customImageProvider: AnimationImageProvider? | ||||||
|
||||||
/// A custom `AnimationTextProvider` to use when rendering this animatino | ||||||
var customTextProvider: AnimationTextProvider? | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
btw our readme has instructions on how you can run our code formatter (which will be necessary for CI to pass): https://github.com/airbnb/lottie-ios#contributing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 31f3bf9 β There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. By the way, I am experiencing some troubles with the ruby version and therefore can't run the linter. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All good, I'll run it locally and push There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ruby can be a nightmare π« |
||||||
|
||||||
/// A custom `AnimationFontProvider` to use when rendering this animation | ||||||
var customFontProvider: AnimationFontProvider? | ||||||
|
||||||
|
@@ -70,6 +73,9 @@ extension SnapshotConfiguration { | |||||
// Test cases for `AnimatedImageProvider` | ||||||
"Nonanimating/_dog": .customImageProvider(HardcodedImageProvider(imageName: "Samples/Images/dog.png")), | ||||||
|
||||||
// Test cases for `AnimatedTextProvider` | ||||||
"": .customTextProvider(HardcodedTextProvider()), | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be:
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. a053713 β |
||||||
|
||||||
// Test cases for `AnimationFontProvider` | ||||||
"Nonanimating/Text_Glyph": .customFontProvider(HardcodedFontProvider(font: UIFont(name: "Chalkduster", size: 36)!)), | ||||||
|
||||||
|
@@ -128,6 +134,15 @@ extension SnapshotConfiguration { | |||||
return configuration | ||||||
} | ||||||
|
||||||
static func customTextProvider( | ||||||
_ customTextProvider: AnimationTextProvider) | ||||||
-> SnapshotConfiguration | ||||||
{ | ||||||
var configuration = SnapshotConfiguration.default | ||||||
configuration.customTextProvider = customTextProvider | ||||||
return configuration | ||||||
} | ||||||
|
||||||
/// A `SnapshotConfiguration` value using the given custom value providers | ||||||
static func customFontProvider( | ||||||
_ customFontProvider: AnimationFontProvider) | ||||||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,22 @@ | ||||||||||||||||||||||||||||||||||||||||||||||
// Created by Igor Katselenbogen on 08/19/22. | ||||||||||||||||||||||||||||||||||||||||||||||
// Copyright Β© 2022 Airbnb Inc. All rights reserved. | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
import Lottie | ||||||||||||||||||||||||||||||||||||||||||||||
import QuartzCore | ||||||||||||||||||||||||||||||||||||||||||||||
#if os(iOS) | ||||||||||||||||||||||||||||||||||||||||||||||
import UIKit | ||||||||||||||||||||||||||||||||||||||||||||||
#endif | ||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are these necessary?
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 8bbf3c9 β |
||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
// MARK: - HardcodedImageProvider | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
/// An `AnimationTextProvider` that always returns a specific hardcoded text | ||||||||||||||||||||||||||||||||||||||||||||||
class HardcodedTextProvider: AnimationTextProvider { | ||||||||||||||||||||||||||||||||||||||||||||||
// Question 4: What should we actually return here? | ||||||||||||||||||||||||||||||||||||||||||||||
func textFor(keypathName: String, sourceText: String) -> String { | ||||||||||||||||||||||||||||||||||||||||||||||
#if os(iOS) | ||||||||||||||||||||||||||||||||||||||||||||||
return "text layer text" | ||||||||||||||||||||||||||||||||||||||||||||||
#else | ||||||||||||||||||||||||||||||||||||||||||||||
return nil | ||||||||||||||||||||||||||||||||||||||||||||||
#endif | ||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this should be:
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Alrighty! a053713 β |
||||||||||||||||||||||||||||||||||||||||||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reloadFonts()
/reloadTexts()
doesn't causesetupAnimations(context:)
to be called again. Instead I think we need to callrebuildCurrentAnimation()
, like we do insetValueProvider(_:keypath:)
below.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got you! Thanks!
Fixed in b542f66 β