Keyframes
A library for converting Adobe AE shape based animations to a data format and playing it back on Android and iOS devices.
Install / Use
/learn @facebookarchive/KeyframesREADME

Keyframes
Keyframes is a combination of (1) an ExtendScript script that extracts image animation data from an After Effects file and (2) a corresponding rendering library for Android and iOS. Keyframes can be used to export and render high quality, vector based animations with complex shape and path curves, all with minimal file footprint.
Usage
Developing Animations in After Effects
For a detailed list of constraints for developing animations to use with the Keyframes library, please refer to the Keyframes After Effects Guidelines.
Image Data Extraction
Use of the extraction script requires an installation of Adobe After Effects as well as Adobe ExtendScript Toolkit. If Keyframes JSON files are already available, only the corresponding iOS and Android libraries are needed.
For detailed steps on running the ExtendScript script on your AE comp, please refer to the instructions detailed here.
iOS Rendering
Installation
CocoaPods
Keyframes is available on CocoaPods. Add the following to your Podfile:
target 'MyApp' do
pod "keyframes"
end
Quit Xcode completely before running
pod install
in the project directory in terminal.
Carthage
Keyframes is also available through Carthage.
Add the following to your Cartfile to get the latest release branch:
github "facebookincubator/Keyframes"
Or, to get the master branch:
github "facebookincubator/Keyframes" "master"
Run
> carthage update
In Xcode, on your application targets’ "General" settings tab, in the "Linked Frameworks and Libraries" section, drag and drop the framework from the Carthage/Build folder.
Rendering Setup
Use the provided deserializers on the generated JSON blob from the Image Data Extraction step to create a KFVector model object. If your JSON blob lives in the assets directory, this might look like:
NSString *filePath = [[NSBundle bundleForClass:[self class]] pathForResource:@"asset_name" ofType:@"json" inDirectory:nil];
NSData *data = [NSData dataWithContentsOfFile:filePath];
NSDictionary *vectorDictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
KFVector *vector = KFVectorFromDictionary(vectorDictionary);
Then a KFVectorLayer can be created using this KFVector, KFVectorLayer can be used as normal CALayer.
KFVectorLayer *layer = [KFVectorLayer layer];
// Set a non-zero layer frame before setting the KFVector is required.
layer.frame = $AnyNonZeroCGRect$;
layer.faceModel = vector;
If you don't want the control of animation and prefer a UIView, KFVectorView can also be created using KFVector.
KFVectorView *view = [[KFVectorView alloc] initWithFrame:$AnyNonZeroCGRect$ faceVector:vector];
Play!
Use startAnimation, pauseAnimation, resumeAnimation and seekToProgress on KFVectorLayer to control the animation.
// Animation will start from beginning.
[layer startAnimation];
// Pause the animation at current progress.
[layer pauseAnimation];
// Resume the animation from where we paused last time.
[layer resumeAnimation];
// Seek to a given progress in range [0, 1]
[layer seekToProgress:0.5]; // seek to the mid point of the animation
Android Rendering
Download
Download the latest JARs or grab via Gradle:
compile 'com.facebook.keyframes:keyframes:1.0'
or Maven:
<dependency>
<groupId>com.facebook.keyframes</groupId>
<artifactId>keyframes</artifactId>
<version>1.0</version>
</dependency>
Rendering setup
Use the provided deserializers on the generated JSON blob from the Image Data Extraction step to create a KFImage model object. If your JSON blob lives in the assets directory, this might look like:
InputStream stream = getResources().getAssets().open("asset_name");
KFImage kfImage = KFImageDeserializer.deserialize(stream);
A KeyframesDrawable object can be created now using this KFImage, and this drawable can be used as a normal drawable. It is highly recommended to use the software layer on any views displaying Keyframes animations.
KeyframesDrawable kfDrawable = new KeyframesDrawableBuilder().withImage(kfImage).build();
ImageView imageView = (ImageView) findViewById(R.id.some_image_view);
imageView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
imageView.setImageDrawable(kfDrawable);
imageView.setImageAlpha(0);
Play!
Use the start and stop animations on the drawable when appropriate to begin playback of the animation or end it after the end of the current loop.
// Starts a loop that progresses animation from the beginning and invalidates the drawable.
kfDrawable.startAnimation();
// Pause the animation at current progress.
kfDrawable.pauseAnimation();
// Resume the animation from where we paused last time.
kfDrawable.resumeAnimation();
// Stops the animation.
kfDrawable.stopAnimation();
// Stops the animation when the current animation ends.
kfDrawable.stopAnimationAtLoopEnd();
// Starts the animation and plays it once. Will stop at the end
kfDrawable.playOnce();
Mobile Frameworks
Existing implementations for mobile frameworks:
| Framework | Platform | Author | Link | |-----------------------|-------------|-----------------|-----------------------------------------------------------------| | React Native (imperative api) | Android/IOS | Tomas Roos| https://github.com/ptomasroos/react-native-keyframes/ | Appcelerator Titanium | iOS | Hans Knoechel | https://github.com/hansemannn/ti.keyframes | | Appcelerator Titanium | Android | Michael Gangolf | https://github.com/m1ga/ti.keyframes | | React Native | Android/iOS | Underscope | https://github.com/underscopeio/react-native-facebook-keyframes | | NativeScript | Android/IOS | Eddy Verbruggen| https://github.com/EddyVerbruggen/nativescript-keyframes
Understanding Keyframes Model Objects
Image
An Image in Keyframes consists of a number of important fields, which together, describe an animated and scalable image. At the top level, an image contains information about how to scale (canvas_size) an image, as well as how to play back an animation at the correct speed (frame_rate, frame_count). The animation itself is not bound to the discrete frame_rate that the image was extracted at, as the Keyframes rendering library supports fractional frames. In addition to these global parameters of an Image, an Image also contains a number of Features, which describe different shapes to be drawn, as well as Animation Groups, which describe transforms that can be applied to multiple Features or even other Animation Groups at once.
Let's break down this simple image of a star against a circle scaling up and down. The animation was exported at 24FPS, and the frame number is shown in the top left corner as well as the scale of the star on the bottom.

Let's slow that down a bit, frame by frame.

Features
A Feature is any independent visual object of the image. Most important, it includes shape drawing commands, presented very similary to SVG type commands, which describe the Feature's shape at any given time. A Feature may belong to a larger Animation Group, as well as contain features specific animations of its own, including a specialized STROKE_WIDTH animation. The shape of a Feature can also change over time, using the same Keyframe and Interpolator pattern described below.
Shape
A shape is any list of line drawing commands, which strung together, describe a continuous line or closed shape that can be filled or stroked. The commands are given as a series of Move, Line, Quadratic, and Cubic commands, one after another.
Here are the important shapes for the above image, along with vertices (squares) and control points (circles), if relevant.

Animations
Transforms
The Keyframes rendering library includes support for the common matrix based transform operations, SCALE, ROTATE, and TRANSLATE. For Features specifically, an additional non-matrix STROKE_WIDTH is available. Animations may belong to specific Features, or as part of a larger Animation Group.
Animation Progression
The values of a transform of an animation and how they change during the playback of an animation are determined by two key fields, Keyframes and Timing Curves. Using the combination of the two fields, we can calculate back a value for a transform at any specified time in the animation.
Keyframes are specific frames in the animation that have specific target values. For example, in scaling a shape up and
Related Skills
node-connect
343.1kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
90.0kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
343.1kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
343.1kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
