{"id":33911619,"url":"https://github.com/darmie/kito","last_synced_at":"2026-05-26T20:02:01.556Z","repository":{"id":323145566,"uuid":"1092253576","full_name":"darmie/kito","owner":"darmie","description":"Declarative state machines \u0026 reactive animations for Dart/Flutter","archived":false,"fork":false,"pushed_at":"2025-11-10T11:51:04.000Z","size":8160,"stargazers_count":7,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-04T15:37:39.554Z","etag":null,"topics":["animation","dart","flutter","flutter-package","flutter-ui","interaction-design","interactive","keyframe-animation","ux-design"],"latest_commit_sha":null,"homepage":"https://darmie.github.io/kito/","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/darmie.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-11-08T09:36:59.000Z","updated_at":"2026-02-06T18:38:11.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/darmie/kito","commit_stats":null,"previous_names":["darmie/kito"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/darmie/kito","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/darmie%2Fkito","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/darmie%2Fkito/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/darmie%2Fkito/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/darmie%2Fkito/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/darmie","download_url":"https://codeload.github.com/darmie/kito/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/darmie%2Fkito/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33536659,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"ssl_error","status_checked_at":"2026-05-26T15:22:15.568Z","response_time":63,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["animation","dart","flutter","flutter-package","flutter-ui","interaction-design","interactive","keyframe-animation","ux-design"],"created_at":"2025-12-12T05:58:53.284Z","updated_at":"2026-05-26T20:02:00.882Z","avatar_url":"https://github.com/darmie.png","language":"Dart","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Kito Logo](https://raw.githubusercontent.com/darmie/kito/main/kito-logo.png)\n# Kito 🎬\n\n**Declarative state machines \u0026 reactive animations for Dart/Flutter**\n\nA comprehensive interaction design framework combining finite state machines, reactive primitives, and composable atomic patterns. Build powerful, type-safe UI interactions and animations from simple building blocks.\n\n## ✨ Features\n\n- 🔄 **Fine-grained Reactivity**: Built on reactive signals, computed values, and effects with automatic dependency tracking\n- 🤖 **State Machines**: Hierarchical FSMs with event bubbling, guards, and animation integration\n- 🎨 **Atomic Primitives**: 22+ pre-built motion, enter/exit, and timing animation primitives\n- 🎭 **UI Patterns**: Ready-to-use state machines for buttons, forms, drawers, modals, and more\n- 🤏 **Interactive Patterns**: Pull-to-refresh, drag-shuffle lists/grids with physics-based animations\n- 🎯 **Type-safe API**: Strongly-typed states, events, and contexts throughout\n- 🌊 **Flexible Easing**: 30+ built-in easing functions plus custom bezier curves\n- ⏱️ **Timeline Control**: Keyframes, sequences, chaining, and parallel animations\n- ⚡ **High Performance**: Optimized for 60fps with minimal overhead\n- 🎪 **Composable**: Mix and match primitives to create complex effects\n\n## 📦 Packages\n\nKito is organized into focused, composable packages:\n\n### Core Packages\n\n- **`kito`** - Core animation engine with timeline, keyframes, and easing\n- **`kito_reactive`** - Reactive primitives (signals, effects, computed values)\n- **`kito_fsm`** - Finite state machines with hierarchical states and event bubbling\n\n### Extension Packages\n\n- **`kito_patterns`** - Pre-built UI patterns and atomic animation primitives\n  - **Motion primitives**: elastic, bounce, shake, pulse, flash, swing, jello, heartbeat\n  - **Enter/exit primitives**: fade, slide, scale, zoom, flip, rotate, combinations\n  - **Timing primitives**: chain, parallel, spring, yoyo, ping-pong, stagger\n  - **UI state machines**: button, form, drawer, modal, pull-to-refresh\n  - **Interactive patterns**: drag-shuffle lists and grids with multiple reposition modes\n\n### Demo\n\n- **`demo`** - Interactive Flutter web app showcasing all Kito capabilities ([Live demo](https://darmie.github.io/kito) | [View docs](#-demo))\n\n## 🚀 Installation\n\nAdd to your `pubspec.yaml`:\n\n```yaml\ndependencies:\n  kito:\n    git:\n      url: https://github.com/darmie/kito.git\n      path: .\n  kito_reactive:\n    git:\n      url: https://github.com/darmie/kito.git\n      path: packages/kito_reactive\n  kito_fsm:\n    git:\n      url: https://github.com/darmie/kito.git\n      path: packages/kito_fsm\n  kito_patterns:\n    git:\n      url: https://github.com/darmie/kito.git\n      path: packages/kito_patterns\n```\n\nOr install from local path:\n\n```yaml\ndependencies:\n  kito:\n    path: ../kito\n  kito_patterns:\n    path: ../kito/packages/kito_patterns\n```\n\n## Quick Start\n\n### Using Atomic Primitives\n\nAtomic primitives are pure, composable animation functions you can apply to any component:\n\n```dart\nimport 'package:kito_patterns/kito_patterns.dart';\n\n// Create animatable property\nfinal scale = animatableDouble(1.0);\n\n// Apply elastic bounce primitive\nfinal animation = createElastic(\n  scale,\n  1.5,\n  config: ElasticConfig.strong,\n);\n\nanimation.play();\n\n// Use in widget\nTransform.scale(\n  scale: scale.value,\n  child: YourWidget(),\n)\n```\n\n### Motion Primitives\n\n```dart\n// Elastic rubber band effect\ncreateElastic(scale, 1.5, config: ElasticConfig.medium);\n\n// Bounce with gravity\ncreateBounce(translateY, -100, config: BounceConfig.heavy);\n\n// Shake for errors\ncreateShake(translateX, config: ShakeConfig.strong);\n\n// Pulse effect\ncreatePulse(scale, config: PulseConfig.medium);\n\n// Heartbeat\ncreateHeartbeat(scale);\n\n// Swing pendulum\ncreateSwing(rotation);\n\n// Jello wobble\ncreateJello(scale);\n\n// Flash opacity\ncreateFlash(opacity);\n```\n\n### Enter/Exit Primitives\n\n```dart\n// Fade transitions\nfadeIn(opacity);\nfadeOut(opacity);\n\n// Slide transitions (8 directions)\nslideInFromRight(translateX, distance: 200);\nslideInFromLeft(translateX, distance: 200);\nslideInFromTop(translateY, distance: 200);\nslideInFromBottom(translateY, distance: 200);\n\n// Scale transitions\nscaleIn(scale);\nscaleOut(scale);\n\n// Combination effects\nfadeScaleIn(opacity, scale);\nslideFadeIn(translateX, opacity, distance: 200);\nzoomIn(scale, opacity);  // Scale + fade with bounce\nflipIn(rotateY);  // 3D-like rotation\n```\n\n### Timing Primitives\n\n```dart\n// Chain animations sequentially\nchain([anim1, anim2, anim3], gap: 100);\n\n// Run animations in parallel\nparallel([anim1, anim2, anim3]);\n\n// Physics-based spring\nspring(\n  property: translateY,\n  target: 0,\n  stiffness: 180.0,\n  damping: 12.0,\n);\n\n// Ping-pong oscillation\npingPong(\n  property: rotation,\n  from: -0.1,\n  to: 0.1,\n  times: -1,  // infinite\n);\n\n// Stagger with delays\nstaggerStart([anim1, anim2, anim3], delayMs: 100);\n```\n\n### Basic Animation\n\n```dart\nimport 'package:kito/kito.dart';\n\n// Create animatable properties\nfinal props = AnimatedWidgetProperties(\n  scale: 1.0,\n  rotation: 0.0,\n  opacity: 1.0,\n);\n\n// Create and run animation\nfinal animation = animate()\n    .to(props.scale, 1.5, easing: Easing.easeOutBack)\n    .to(props.rotation, 3.14159)\n    .to(props.opacity, 0.5)\n    .withDuration(1000)\n    .build();\n\nanimation.play();\n\n// Use in a widget\nKitoAnimatedWidget(\n  properties: props,\n  child: YourWidget(),\n)\n```\n\n### Reactive State Management\n\n```dart\nimport 'package:kito_reactive/kito_reactive.dart';\n\n// Create a signal (reactive primitive)\nfinal count = signal(0);\n\n// Create computed values that automatically update\nfinal doubled = computed(() =\u003e count.value * 2);\nfinal message = computed(() =\u003e\n  count.value \u003e 10 ? 'High!' : 'Low'\n);\n\n// Create effects that run when dependencies change\nfinal dispose = effect(() {\n  print('Count is: ${count.value}');\n  print('Message: ${message.value}');\n});\n\n// Update the signal - effects run automatically\ncount.value = 5;  // Prints: Count is: 5, Message: Low\ncount.value = 15; // Prints: Count is: 15, Message: High\n\n// Clean up\ndispose();\n```\n\n### State Machines with Animations\n\n```dart\nimport 'package:kito_fsm/kito_fsm.dart';\nimport 'package:kito_patterns/kito_patterns.dart';\n\n// Use pre-built button state machine\nfinal buttonFsm = createButtonStateMachine(\n  scale: animatableDouble(1.0),\n  opacity: animatableDouble(1.0),\n);\n\n// Handle button interactions\nGestureDetector(\n  onTapDown: (_) =\u003e buttonFsm.dispatch(ButtonEvent.pressDown),\n  onTapUp: (_) =\u003e buttonFsm.dispatch(ButtonEvent.pressUp),\n  onTapCancel: () =\u003e buttonFsm.dispatch(ButtonEvent.pressCancel),\n  child: Transform.scale(\n    scale: buttonFsm.context.scale.value,\n    child: Opacity(\n      opacity: buttonFsm.context.opacity.value,\n      child: YourButton(),\n    ),\n  ),\n)\n```\n\n### Interactive Patterns\n\n```dart\nimport 'package:kito_patterns/kito_patterns.dart';\n\n// Pull-to-refresh\nfinal pullToRefreshFsm = createPullToRefreshStateMachine(\n  onRefresh: () async {\n    await fetchData();\n  },\n);\n\n// Drag-shuffle list with multiple reposition modes\nfinal items = ['Item 1', 'Item 2', 'Item 3', 'Item 4'];\nfinal positions = List.generate(items.length, (i) =\u003e\n  animatableOffset(Offset(0, i * 80.0))\n);\n\nfinal dragShuffleFsm = createDragShuffleListStateMachine(\n  items: items,\n  positions: positions,\n  repositionMode: RepositionMode.swap,  // or shift, push\n);\n```\n\n### Timeline Sequences\n\n```dart\n// Create multiple animations\nfinal anim1 = animate()\n    .to(box1.translateX, 100)\n    .withDuration(500)\n    .build();\n\nfinal anim2 = animate()\n    .to(box2.scale, 2.0)\n    .withDuration(800)\n    .build();\n\nfinal anim3 = animate()\n    .to(box3.rotation, 6.28)\n    .withDuration(1000)\n    .build();\n\n// Sequence them\nfinal tl = timeline()\n  ..add(anim1)\n  ..add(anim2)  // Plays after anim1\n  ..add(anim3, position: TimelinePosition.concurrent)  // Plays with anim2\n  ..play();\n```\n\n### Keyframe Animations\n\n```dart\nfinal colorProp = animatableColor(Colors.blue);\n\nfinal colorKeyframes = keyframes\u003cColor\u003e()\n    .at(0.0, Colors.blue)\n    .at(0.33, Colors.red, easing: Easing.easeInOut)\n    .at(0.66, Colors.yellow, easing: Easing.easeInOut)\n    .at(1.0, Colors.green)\n    .build();\n\nanimate()\n    .withKeyframes(colorProp, colorKeyframes)\n    .withDuration(3000)\n    .loopInfinitely()\n    .build()\n    .play();\n```\n\n### Flutter AnimationController Integration\n\nKito seamlessly integrates with Flutter's native animation system:\n\n```dart\nimport 'package:kito/kito.dart';\n\n// Option 1: Drive Kito properties with AnimationController\nfinal controller = AnimationController(\n  vsync: this,\n  duration: Duration(milliseconds: 500),\n);\n\nfinal scale = animatableDouble(1.0);\nfinal driver = AnimatableAnimationDriver(\n  property: scale,\n  animation: CurvedAnimation(parent: controller, curve: Curves.elasticOut),\n  startValue: 1.0,\n  endValue: 1.5,\n);\n\ncontroller.forward();\n\n// Option 2: KitoAnimationController (unified controller)\nfinal kitoController = KitoAnimationController.create(\n  vsync: this,\n  duration: Duration(milliseconds: 500),\n  curve: Curves.easeInOutBack,\n  properties: {\n    scale: 1.5,\n    opacity: 0.5,\n    rotation: 3.14159,\n  },\n);\n\nkitoController.forward();\nkitoController.reverse();\nkitoController.reset();\n\n// Option 3: Use Flutter Curves with Kito animations\nfinal animation = animate()\n    .to(scale, 1.5)\n    .withDuration(500)\n    .withEasing(Curves.bounceOut.toEasing())  // Convert Flutter Curve\n    .build();\n\n// Use Kito easing as Flutter Curve\nfinal curve = Easing.easeOutElastic.toCurve();\nfinal curvedAnimation = CurvedAnimation(\n  parent: controller,\n  curve: curve,\n);\n```\n\n**Why integrate with AnimationController?**\n- Use Flutter's built-in curves and animations with Kito's reactive system\n- Leverage existing Flutter widgets that expect AnimationController\n- Bidirectional conversion between Kito and Flutter animation systems\n- Access to both ecosystems' strengths\n\n### SVG Path Morphing\n\nMorph between any SVG paths with automatic normalization and interpolation:\n\n```dart\nimport 'package:kito/kito.dart';\n\n// Parse SVG path data strings\nfinal star = SvgPath.fromString(\n  'M 50,10 L 61,35 L 88,35 L 67,52 L 76,79 L 50,62 L 24,79 L 33,52 L 12,35 L 39,35 Z'\n);\nfinal pentagon = SvgPath.fromString(\n  'M 50,10 L 90,35 L 73,75 L 27,75 L 10,35 Z'\n);\n\n// Create properties for morphing\nfinal props = SvgAnimationProperties(\n  morphProgress: 0.0,\n  fillColor: Colors.blue,\n);\n\n// Create morphable SVG widget\nfinal widget = svgMorphPath(\n  startPath: star,\n  endPath: pentagon,\n  properties: props,\n);\n\n// Animate the morph\nanimate()\n  .to(props.morphProgress, 1.0)\n  .withDuration(1000)\n  .withEasing(Easing.easeInOutCubic)\n  .build()\n  .play();\n\n// Or use animatable SVG paths directly\nfinal animPath = animatableSvgPath(star);\nanimate()\n  .to(animPath, pentagon)\n  .withDuration(1000)\n  .build()\n  .play();\n```\n\n**Features:**\n- Automatic path normalization (converts all commands to cubic beziers)\n- Compatible path generation (handles different command counts)\n- Parse SVG path data strings (M, L, H, V, C, Q, A, Z commands)\n- Smooth interpolation between any shapes\n- Type-safe animatable SVG path property\n\n### Performance Profiling\n\nProfile animations to optimize performance and detect bottlenecks:\n\n```dart\nimport 'package:kito/kito.dart';\n\n// Enable automatic profiling\nAnimationProfiler().enableAutoProfiling();\n\n// Profile a specific animation\nfinal animation = animate()\n  .to(scale, 1.5)\n  .withDuration(1000)\n  .build()\n  .withProfiling('my-animation');\n\nanimation.onComplete(() {\n  final metrics = AnimationProfiler().getMetrics('my-animation');\n  print('Average FPS: ${metrics?.averageFps}');\n  print('Dropped frames: ${metrics?.droppedFrames}');\n  print('Is performant: ${metrics?.isPerformant}');\n});\n\nanimation.play();\n\n// Use performance overlay for real-time monitoring\nKitoPerformanceOverlay(\n  enabled: true,\n  position: PerformanceOverlayPosition.topRight,\n  child: YourApp(),\n);\n\n// View detailed metrics with stats widget\nPerformanceStats(metrics: metrics);\n\n// Visualize frame timings\nFrameTimeline(frameTimings: metrics.frameTimings);\n```\n\n**Features:**\n- Real-time FPS monitoring overlay with graph\n- Detailed per-animation metrics (FPS, frame times, dropped frames)\n- Automatic performance issue detection\n- Frame timeline visualization\n- Batch profiling for multiple animations\n- Performance thresholds and warnings\n- Zero overhead when disabled\n\n## 🎯 Showcase\n\nKito enables powerful interactive animations with minimal code:\n\n### Match-3 Game\n\n![Match-3 Game](https://raw.githubusercontent.com/darmie/kito/main/showcase/match-3-ezgif.com-video-to-gif-converter.gif)\n\nFully playable tile-matching game with cascades, combos, and win/loss detection:\n\n- Tile selection with adjacency validation\n- Invalid move swap-back animations\n- Match detection with combo multipliers\n- Gravity-based tile dropping with stagger\n- Particle effects for matched tiles\n\n### Card Stack (Tinder-style)\n\n![Card Stack](https://raw.githubusercontent.com/darmie/kito/main/showcase/tinder-ezgif.com-video-to-gif-converter.gif)\n\nGesture-driven card swiping with smooth animations:\n\n```dart\nvoid _onPanUpdate(DragUpdateDetails details) {\n  final delta = details.localPosition - dragStart!;\n  card.position.value = delta;\n  card.rotation.value = (delta.dx / 200).clamp(-0.26, 0.26);\n}\n\n// Threshold-based swipe completion\nif (card.position.value.dx.abs() \u003e swipeThreshold) {\n  _swipeCard(right: card.position.value.dx \u003e 0);\n} else {\n  _snapBack();\n}\n```\n\n### Photo Gallery\n\n![Photo Gallery](https://raw.githubusercontent.com/darmie/kito/main/showcase/gallery-ezgif.com-video-to-gif-converter.gif)\n\nShared element transitions with expand/collapse animations:\n\n```dart\nfinal expandAnim = animate()\n    .to(photo.position, targetPosition)\n    .to(photo.size, targetSize)\n    .withDuration(400)\n    .build();\n\n// Coordinated parallel animations\nfinal fadeAnims = otherPhotos.map((p) =\u003e\n  animate().to(p.opacity, 0.0).build()\n);\n\nparallel([expandAnim, ...fadeAnims]);\n```\n\n### Onboarding Flow\n\n![Onboarding Flow](https://raw.githubusercontent.com/darmie/kito/main/showcase/onboarding-ezgif.com-video-to-gif-converter.gif)\n\nMulti-step wizard with directional page transitions and smooth navigation.\n\n### Pull-to-Refresh \u0026 List Drag\n\n![Pull-to-Refresh \u0026 Drag List](https://raw.githubusercontent.com/darmie/kito/main/showcase/pull-refresh-list-drag-ezgif.com-video-to-gif-converter.gif)\n\nGesture-driven interactions with threshold detection and reorderable lists:\n\n- Pull-to-refresh with physics-based spring animations\n- Drag-shuffle list with swap/shift/push modes\n\n### Drag-Shuffle Grid \u0026 Swipe to Delete\n\n![Drag-Shuffle \u0026 Swipe Delete](https://raw.githubusercontent.com/darmie/kito/main/showcase/drag-shuffle-swipe-delete-ezgif.com-video-to-gif-converter.gif)\n\nAdvanced interactive patterns:\n\n- Drag-shuffle grid with wave/radial/row/column repositioning\n- Swipe-to-delete with progressive visual feedback\n\n```dart\n// Progressive visual feedback during swipe\nfinal swipeProgress = (offset.dx.abs() / threshold).clamp(0.0, 1.0);\n\n// Smooth delete animation\nanimate()\n  .to(item.swipeOffset, Offset(targetX, 0))\n  .to(item.opacity, 0.0)\n  .to(item.scale, 0.8)\n  .withDuration(300)\n  .build()\n  .play();\n```\n\n## 🎮 Demo\n\nThe interactive Flutter web demo showcases 30+ live examples organized by category:\n\n### Primitives Demos\n- **Motion Tab**: Elastic, Bounce, Shake, Pulse, Flash, Swing, Jello, Heartbeat\n- **Enter/Exit Tab**: Fade, Slide, Scale, FadeScale, SlideFade, Zoom, Flip, Rotate\n- **Timing Tab**: Chain, Parallel, Spring, Crossfade, Ping-Pong, Stagger\n\n### UI Patterns\n- **Button Pattern**: Press states with bouncy/elastic animations\n- **Form Pattern**: Multi-field validation with animated feedback\n- **Drawer Pattern**: Slide-in/out transitions with backdrop\n- **Modal Pattern**: Multiple animation types (fade, scale, slide, bounce)\n- **Toast Notifications**: Auto-dismissing notifications with slide animations\n\n### Interactive Patterns\n- **Pull-to-Refresh**: Gesture-driven refresh with threshold detection\n- **Drag-Shuffle List**: Reorderable list with swap/shift/push modes\n- **Drag-Shuffle Grid**: Reorderable grid with wave/radial/row/column repositioning\n- **Swipe to Delete**: List items with swipe-to-remove gesture\n\n### Complex Compositions\n- **Match-3 Game**: Fully playable tile-matching game with cascades and combos\n- **Card Stack**: Tinder-style swipeable cards with gesture-driven rotation\n- **Photo Gallery**: Shared element transitions with expand/collapse\n- **Onboarding Flow**: Multi-step wizard with directional page transitions\n\nRun the demo:\n\n```bash\ncd demo\nflutter run -d chrome\n```\n\n## Architecture\n\nKito is built on three core pillars:\n\n### 1. Reactive State Management\n\nFine-grained reactive primitives inspired by SolidJS:\n\n- **Signal**: Mutable reactive value\n- **Computed**: Derived reactive value with automatic dependency tracking\n- **Effect**: Side effect that runs when dependencies change\n- **Batch**: Group multiple updates to run effects only once\n\n```dart\nfinal x = signal(10);\nfinal y = signal(20);\nfinal sum = computed(() =\u003e x.value + y.value);\n\neffect(() {\n  print('Sum is: ${sum.value}');\n});\n\n// Batch multiple updates\nbatch(() {\n  x.value = 100;\n  y.value = 200;\n}); // Effect runs once: \"Sum is: 300\"\n```\n\n### 2. Finite State Machines\n\nHierarchical state machines with:\n\n- **Type-safe states and events**: Strongly-typed state definitions\n- **Event bubbling**: Child states can bubble events to parents\n- **Entry/exit callbacks**: Animations and side effects on transitions\n- **Guards**: Conditional transitions with validation\n- **Context**: Type-safe state-specific data\n\n```dart\nfinal fsm = StateMachine\u003cMyState, MyEvent, MyContext\u003e(\n  initialState: MyState.idle,\n  context: MyContext(),\n);\n\nfsm.defineState(\n  MyState.idle,\n  onEnter: (ctx) =\u003e print('Entering idle'),\n  onExit: (ctx) =\u003e fadeOut(ctx.opacity).play(),\n);\n\nfsm.addTransition(\n  from: MyState.idle,\n  to: MyState.active,\n  event: MyEvent.start,\n  guard: (ctx) =\u003e ctx.isValid,\n);\n```\n\n### 3. Animation Engine\n\nTimeline-based animation system with:\n\n- **Animatable Properties**: Type-safe animated values\n- **Easing Functions**: 30+ built-in easing functions\n- **Keyframes**: Multi-step animations with per-keyframe easing\n- **Direction Control**: Forward, reverse, alternate\n- **Loop Control**: Finite or infinite loops\n- **Callbacks**: onBegin, onUpdate, onComplete\n\n```dart\nanimate()\n    .to(property, endValue)\n    .withDuration(1000)\n    .withEasing(Easing.easeOutElastic)\n    .withLoop(3)\n    .onComplete(() =\u003e print('Done!'))\n    .build()\n    .play();\n```\n\n## Easing Functions\n\nKito includes 30+ easing functions:\n\n**Linear**: `linear`\n\n**Quadratic**: `easeInQuad`, `easeOutQuad`, `easeInOutQuad`\n\n**Cubic**: `easeInCubic`, `easeOutCubic`, `easeInOutCubic`\n\n**Quartic**: `easeInQuart`, `easeOutQuart`, `easeInOutQuart`\n\n**Quintic**: `easeInQuint`, `easeOutQuint`, `easeInOutQuint`\n\n**Sinusoidal**: `easeInSine`, `easeOutSine`, `easeInOutSine`\n\n**Exponential**: `easeInExpo`, `easeOutExpo`, `easeInOutExpo`\n\n**Circular**: `easeInCirc`, `easeOutCirc`, `easeInOutCirc`\n\n**Back**: `easeInBack`, `easeOutBack`, `easeInOutBack`\n\n**Elastic**: `easeInElastic`, `easeOutElastic`, `easeInOutElastic`\n\n**Bounce**: `easeInBounce`, `easeOutBounce`, `easeInOutBounce`\n\n**Custom**: `cubicBezier(x1, y1, x2, y2)`, `steps(count)`\n\n## API Reference\n\n### Atomic Primitives\n\n```dart\n// Motion primitives\ncreateElastic(property, target, {config})\ncreateBounce(property, target, {config})\ncreateShake(property, {config})\ncreatePulse(property, {config})\ncreateHeartbeat(property, {config})\ncreateSwing(property, {config})\ncreateJello(property, {config})\ncreateFlash(property, {config})\n\n// Enter/exit primitives\nfadeIn(opacity, {config})\nfadeOut(opacity, {config})\nslideInFrom[Direction](property, {distance, config})\nslideOutTo[Direction](property, {distance, config})\nscaleIn(scale, {config})\nscaleOut(scale, {config})\nfadeScaleIn(opacity, scale, {config})\nslideFadeIn(translate, opacity, {distance, config})\nzoomIn(scale, opacity, {config})\nflipIn(rotation, {config})\n\n// Timing primitives\nchain(animations, {gap})\nparallel(animations)\nspring({property, target, stiffness, damping})\npingPong({property, from, to, times})\nstaggerStart(animations, {delayMs})\n```\n\n### Animation Builder\n\n```dart\nanimate()\n    .to(property, endValue, {easing, duration, delay})\n    .withKeyframes(property, keyframes, {easing, duration, delay})\n    .withDuration(milliseconds)\n    .withDelay(milliseconds)\n    .withEasing(easingFunction)\n    .withLoop(count)  // or .loopInfinitely()\n    .withDirection(AnimationDirection.forward | reverse | alternate)\n    .withAutoplay()\n    .onBegin(callback)\n    .onUpdate(callback)\n    .onComplete(callback)\n    .build()\n```\n\n### Animation Control\n\n```dart\nanimation.play()       // Start or resume\nanimation.pause()      // Pause\nanimation.restart()    // Restart from beginning\nanimation.seek(0.5)    // Seek to 50%\nanimation.stop()       // Stop and reset\nanimation.dispose()    // Clean up\n```\n\n### Timeline\n\n```dart\ntimeline()\n  .add(animation, {offset, position})\n  .play()\n  .pause()\n  .restart()\n  .seek(milliseconds)\n  .stop()\n  .dispose()\n```\n\n### Reactive Primitives\n\n```dart\n// Signal\nfinal sig = signal(initialValue)\nsig.value = newValue\nfinal current = sig.value\nfinal peeked = sig.peek()  // Read without tracking\n\n// Computed\nfinal comp = computed(() =\u003e expression)\nfinal value = comp.value\n\n// Effect\nfinal dispose = effect(() =\u003e sideEffect)\ndispose()  // Stop the effect\n\n// Batch\nbatch(() {\n  signal1.value = value1\n  signal2.value = value2\n})  // Effects run once after batch\n```\n\n### State Machine Patterns\n\n```dart\n// Button with press animations\ncreateButtonStateMachine(scale, opacity, {config})\n\n// Form with validation\ncreateFormStateMachine(fields, {onValidationComplete})\n\n// Drawer with slide transition\ncreateDrawerStateMachine(position, {config})\n\n// Modal with multiple animation types\ncreateModalStateMachine(scale, opacity, {animationType})\n\n// Pull-to-refresh\ncreatePullToRefreshStateMachine({threshold, onRefresh})\n\n// Drag-shuffle list/grid\ncreateDragShuffleListStateMachine(items, positions, {repositionMode})\ncreateDragShuffleGridStateMachine(items, positions, {rows, cols, mode})\n```\n\n### Flutter AnimationController Integration\n\n```dart\n// Drive Kito properties with AnimationController\nAnimatableAnimationDriver\u003cT\u003e({\n  property: Animatable\u003cT\u003e,\n  animation: Animation\u003cdouble\u003e,\n  startValue: T,\n  endValue: T,\n})\n\n// Unified controller for multiple properties\nKitoAnimationController.create({\n  vsync: TickerProvider,\n  duration: Duration,\n  properties: Map\u003cAnimatable, dynamic\u003e,\n  curve: Curve,\n})\ncontroller.forward()\ncontroller.reverse()\ncontroller.reset()\ncontroller.dispose()\n\n// Convert between Kito and Flutter\nCurve.toEasing() → EasingFunction\nEasingFunction.toCurve() → Curve\n\n// Common Flutter curves as Kito easing functions\nFlutterCurves.linear\nFlutterCurves.easeIn / easeOut / easeInOut\nFlutterCurves.bounceIn / bounceOut / bounceInOut\nFlutterCurves.elasticIn / elasticOut / elasticInOut\nFlutterCurves.fastOutSlowIn\nFlutterCurves.decelerate\n```\n\n### SVG Path Morphing\n\n```dart\n// Parse SVG path data\nSvgPath.fromString(pathData)\n\n// Create animatable SVG path\nanimatableSvgPath(initialPath)\nanimatableSvgPathString(pathData)\n\n// SVG path operations\npath.normalize()          // Convert to cubic beziers\npath.toPath()             // Convert to Flutter Path\nSvgPathInterpolator.interpolate(from, to, t)\n\n// Create morph widgets\nsvgMorphPath({\n  startPath: SvgPath,\n  endPath: SvgPath?,\n  properties: SvgAnimationProperties,\n})\n\nsvgMorphPathString({\n  startPathData: String,\n  endPathData: String?,\n  properties: SvgAnimationProperties,\n})\n\n// SVG path commands supported:\n// M/m - Move\n// L/l - Line\n// H/h - Horizontal line\n// V/v - Vertical line\n// C/c - Cubic bezier\n// Q/q - Quadratic bezier\n// A/a - Arc\n// Z/z - Close path\n```\n\n### Performance Profiling\n\n```dart\n// Enable/disable profiling\nAnimationProfiler().enableAutoProfiling()\nAnimationProfiler().disableAutoProfiling()\n\n// Profile animations\nanimation.withProfiling(animationId)\nAnimationProfiler().startProfiling(animationId)\nAnimationProfiler().recordFrame(animationId, frameDuration)\nAnimationProfiler().stopProfiling(animationId)\n\n// Get metrics\nAnimationProfiler().getMetrics(animationId) → AnimationMetrics?\nAnimationProfiler().getAllMetrics() → Map\u003cString, AnimationMetrics\u003e\nAnimationProfiler().getSummary() → ProfilingSummary\n\n// Performance overlay\nKitoPerformanceOverlay({\n  child: Widget,\n  enabled: bool,\n  position: PerformanceOverlayPosition,\n})\n\n// Metrics widgets\nPerformanceStats(metrics: AnimationMetrics)\nFrameTimeline(frameTimings: List\u003cFrameTiming\u003e)\n\n// Batch profiling\nBatchProfiler.startBatch(animationIds)\nBatchProfiler.stopBatch() → List\u003cAnimationMetrics\u003e\nBatchProfiler.getSummary()\n\n// Performance thresholds\nPerformanceThresholds({\n  minFps: double,           // default: 55.0\n  maxDroppedFramePercent: double,  // default: 0.05\n  maxFrameTimeMs: double,   // default: 16.67\n})\n```\n\n## Examples\n\nThe `demo/` directory contains comprehensive examples organized by complexity:\n\n- **Primitives**: 22 interactive atomic primitive demos\n- **UI Patterns**: Common UI component state machines\n- **Interactive Patterns**: Drag-based interactions\n- **Complex Compositions**: Multi-step orchestrations\n\nRun the demo app:\n\n```bash\ncd demo\nflutter run -d chrome\n```\n\n## Performance Tips\n\n1. **Use `batch()`** when updating multiple signals\n2. **Dispose animations** when done to prevent memory leaks\n3. **Use `peek()`** to read signals without tracking dependencies\n4. **Prefer computed values** over manual calculations\n5. **Mark canvas painters** with `isComplex: true` for caching\n6. **Use atomic primitives** instead of building animations from scratch\n\n## Testing\n\nKito has comprehensive test coverage:\n\n- **kito**: 30/30 tests passing\n- **kito_reactive**: 15/15 tests passing\n- **kito_fsm**: 56/56 tests passing\n\nRun tests:\n\n```bash\n# Test all packages\nflutter test\n\n# Test specific package\ncd packages/kito_fsm\nflutter test\n```\n\n## Roadmap\n\n- [x] Core animation engine with timeline and keyframes\n- [x] Reactive primitives (signals, computed, effects)\n- [x] Hierarchical state machines with event bubbling\n- [x] Atomic animation primitives (22+ primitives)\n- [x] UI state machine patterns (button, form, drawer, modal, toast)\n- [x] Interactive drag patterns (pull-to-refresh, drag-shuffle, swipe-to-delete)\n- [x] Flutter web demo app with 30+ examples\n- [x] Gesture-driven animations (swipe, drag, pan gestures)\n- [x] Complex compositions (games, card stacks, galleries, onboarding)\n- [x] Spring physics animations (basic implementation complete)\n- [x] Integration with Flutter's AnimationController\n- [x] SVG path morphing (advanced)\n- [x] Performance profiling tools\n- [ ] Enhanced documentation and tutorials\n\n## Contributing\n\nContributions are welcome! Please read our contributing guidelines and submit pull requests to our repository.\n\n## License\n\nBSD 3-Clause License - see LICENSE file for details\n\n## Credits\n\nInspired by:\n- [anime.js](https://animejs.com/) - The amazing JavaScript animation library\n- [SolidJS](https://www.solidjs.com/) - Fine-grained reactive system\n- [Framer Motion](https://www.framer.com/motion/) - Declarative animations\n- [XState](https://xstate.js.org/) - State machine patterns\n\nBuilt with ❤️ for the Flutter community\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdarmie%2Fkito","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdarmie%2Fkito","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdarmie%2Fkito/lists"}