Motion Demo Application
Relevant source files
The following files were used as context for generating this wiki page:
- Examples/MotionDemo/MotionDemo/MotionDemoApp.swift
- Examples/MotionDemo/MotionDemo/MotionDemoView.swift
- Sources/SwiftDitherKit/DitherMotion.swift
- Sources/SwiftDitherKit/DitherRasterView.swift
- Sources/SwiftDitherKit/DitherSparkles.swift
- Sources/SwiftDitherKit/DitherCartesianCharts.swift
- Sources/SwiftDitherKit/DitherPolarCharts.swift
The Motion Demo Application (also referred to as the "Motion Lab") is a showcase utility within the SwiftDitherKit project designed to demonstrate the library's animation, transition, and interaction capabilities. It serves as an interactive environment where developers can observe how ordered-dithered charts respond to data changes, user interactions, and system accessibility settings like "Reduce Motion."
Sources: Examples/MotionDemo/MotionDemo/MotionDemoView.swift:18-35, README.md:95-103
Application Architecture
The application is built using SwiftUI and follows a typical View-based architecture where state variables drive the configuration of dithered chart components. The entry point is MotionDemoApp, which initializes the MotionDemoView in a dark-themed window group.
Sources: Examples/MotionDemo/MotionDemo/MotionDemoApp.swift:3-11, Examples/MotionDemo/MotionDemo/MotionDemoView.swift:4-15
Core Components and State Management
The MotionDemoView manages several key states to control the chart's behavior:
- Chart Selection: A
DemoChartenum determines which chart type (Area, Donut, or Radar) is currently rendered. - Data Toggling: A boolean
alternateDataswitches between two distinct datasets (A and B) to demonstrate crossfade transitions. - Animation Control: States for
slowMotion,animationsEnabled, andreplayTokenallow for fine-grained testing of transition timing and manual re-triggering of entrance animations.
Sources: Examples/MotionDemo/MotionDemo/MotionDemoView.swift:7-14, Examples/MotionDemo/MotionDemo/MotionDemoView.swift:85-117
Data Flow for Chart Updates
The following diagram illustrates how user actions in the Demo App trigger state changes that propagate through the SwiftDitherKit motion system.
Motion and Transition Logic
The underlying motion system in SwiftDitherKit, which the Demo App exercises, utilizes a "Motion Decision" engine to determine the appropriate visual transition based on the difference between the previous and next state.
Motion Decisions
The system evaluates states based on a checksum and a transition key. If the replayToken changes, a .replay decision is made. If data changes (checksum differs) but the chart type remains the same (transition key matches), a .crossfade is triggered.
Sources: Sources/SwiftDitherKit/DitherMotion.swift:73-95
Animation Constants
The application uses specific timing curves and durations for different types of motion:
| Animation Type | Duration | Timing Curve / Logic |
|---|---|---|
| Default Entrance | 0.28s | .timingCurve(0.23, 1, 0.32, 1) |
| Update/Crossfade | 0.22s | .timingCurve(0.77, 0, 0.175, 1) |
| Reduced Motion | 0.14s | Opacity fade instead of movement |
| Slow Motion (Demo) | 1.2s | Custom override in Motion Lab |
Sources: Sources/SwiftDitherKit/DitherMotion.swift:7-22, Examples/MotionDemo/MotionDemo/MotionDemoView.swift:158-160
Visual Effects and Interaction
The Demo App highlights three primary visual feedback mechanisms:
1. Reveal Styles
Charts are masked using different reveal styles during their entrance:
- Leading: Used for Cartesian charts (Area/Line), revealing data from left to right.
- Angular: Used for Pie/Donut charts, revealing the "wedges" in a clockwise sweep.
- Radial: Used for Radar charts, often combined with a scale effect (scaling from 96% to 100%).
Sources: Sources/SwiftDitherKit/DitherRasterView.swift:5-9, Sources/SwiftDitherKit/DitherRasterView.swift:334-353
2. Idle Sparkles
Area, Line, and Sparkline charts feature "idle sparkles"—individual dithered pixels that wink or glint while the chart is stationary. In the Demo App, these sparkles respond to Reduce Motion by becoming steady (non-blinking) to avoid distracting movement.
3. Interaction Layers
The application demonstrates interactive scrubbing and selection. Tapping a mark or legend item updates the selectedID binding.
- Cartesian: Supports
DragGesturefor scrubbing andSpatialTapGesturefor mark selection. - Polar: Uses angular calculations (
atan2) to determine which slice or axis is under the user's touch.
Sources: Sources/SwiftDitherKit/DitherCartesianCharts.swift:396-419, Sources/SwiftDitherKit/DitherPolarCharts.swift:273-294
Accessibility Integration
The Motion Demo specifically handles the accessibilityReduceMotion environment value. When enabled:
- Entrance animations are replaced with a short opacity fade.
- Transition blurs are removed (set to 0).
- Idle sparkles stop blinking and maintain a steady alpha of 0.595.
- Scaling effects (like the Radar chart's 96% -> 100% entrance) are disabled.
Sources: Sources/SwiftDitherKit/DitherMotion.swift:25-30, Sources/SwiftDitherKit/DitherRasterView.swift:165-175, Sources/SwiftDitherKit/DitherSparkles.swift:120-134
Summary
The Motion Demo Application serves as a reference implementation for the SwiftDitherKit library's dynamic features. By centralizing the controls for animation duration, data updates, and accessibility settings, it provides a comprehensive tool for validating the library's performance and visual fidelity across various interactive scenarios. It demonstrates that dithered textures can support modern UI expectations, such as smooth crossfades and responsive interaction, while maintaining their retro aesthetic.