A macOS application for rendering SpriteKit animations frame-by-frame as PNG image sequences. SKAnimator reads animation data from JSON files and exports each frame as a numbered PNG file.
SKAnimator is a command-line tool that takes a JSON scene definition file and renders an animation sequence frame-by-frame using SpriteKit. It's designed for batch rendering of animations with precise control over timing, interpolation, and export settings.
-
Sprite Animation: Animate sprites with keyframe-based properties:
- Position (x, y)
- Color (RGB channels)
- Alpha transparency
- Scale
- Visibility
-
Text Support: Frame-based text animation (currently in development)
-
Keyframe Interpolation:
- Linear interpolation for numeric channels
- Discrete keyframes for non-interpolated values
-
Frame Range Control: Specify start frame, end frame, and frame step increment
-
Custom Textures: Load and use custom image textures for sprites
-
Batch Export: Automatically exports each frame as a PNG image with sequential naming
- macOS (minimum version specified in project settings)
- Xcode
- Swift
- Build the project in Xcode
- Run from the command line with a JSON scene file:
./SKAnimator path/to/scene.jsonThe application will:
- Load the scene definition from the JSON file
- Render frames according to the specified range
- Export each frame as
{scene_name}_{frame_number}.png - Automatically terminate when rendering is complete
The scene JSON file should follow this structure:
{
"name": "scene_name",
"size": [width, height],
"range": [start_frame, end_frame, step],
"textures": {
"texture_name": "~/path/to/image.png"
},
"sprites": [
{
"texture": "texture_name",
"x": [[time1, value1], [time2, value2], ...],
"y": [[time1, value1], [time2, value2], ...],
"r": [[time1, value1], [time2, value2], ...],
"g": [[time1, value1], [time2, value2], ...],
"b": [[time1, value1], [time2, value2], ...],
"a": [[time1, value1], [time2, value2], ...],
"scale": [[time1, value1], [time2, value2], ...],
"visible": {frame: bool, ...},
"anchor": [x, y]
}
],
"texts": [
{
"text": {frame: "string", ...},
"x": {frame: value, ...},
"y": {frame: value, ...},
"visible": {frame: bool, ...}
}
]
}- name: Scene identifier used in output filenames
- size: Canvas dimensions
[width, height] - range: Frame range
[start, end]or[start, end, step](step defaults to 1) - textures: Dictionary mapping texture names to file paths (supports
~expansion) - sprites: Array of sprite objects with animated properties
- All numeric properties (x, y, r, g, b, a, scale) use
[[time, value], ...]format visibleis optional and uses discrete frame-based visibilityanchoris optional anchor point[x, y](defaults to center)
- All numeric properties (x, y, r, g, b, a, scale) use
- texts: Array of text objects (currently in development)
SKAnimator/
├── AppDelegate.swift # Application entry point
├── ViewController.swift # Main view controller
├── SAScene.swift # Scene management and rendering
├── SAKeyframe.swift # Keyframe data structure
├── Channels/
│ ├── SAChannel.swift # Channel protocol
│ ├── SANumericChannel.swift # Numeric interpolation channel
│ └── SADiscreteChannel.swift # Discrete value channel
└── Nodes/
├── SASprite.swift # Sprite node implementation
└── SAText.swift # Text node implementation (stub)
- SAScene: Manages the SpriteKit scene, frame rendering, and PNG export
- SANumericChannel: Handles linear interpolation of numeric values using SpriteKit's
SKKeyframeSequence - SADiscreteChannel: Manages discrete keyframe values without interpolation
- SASprite: Represents an animated sprite with position, color, scale, and alpha channels
- SAText: Text node support (implementation pending)
Exported frames are saved as PNG files with the naming pattern:
{scene_name}_{frame_number:04d}.png
For example, a scene named "intro" would produce:
intro_0000.pngintro_0001.pngintro_0002.png- etc.
Copyright © Gabe Montague. All rights reserved.
- The application uses asynchronous rendering disabled (
isAsynchronous = false) for precise frame-by-frame output - Sprite blend mode is set to
.addfor additive blending effects - The application automatically terminates after rendering completes
- Debug builds print a warning message at startup