huahua_motion
简体中文 | English
Composable, focus-driven motion primitives for Flutter interfaces.
huahua_motion is a collection of small widgets that translate application
state into coordinated motion. The package owns reusable visual and interaction
primitives; the application keeps control of data, scrolling policy, navigation,
timing, and feedback.
Features
- Drive scale, opacity, and translation with one normalized focus value.
- Calculate focus automatically for items in a fixed-extent scrolling list.
- Add an interactive edge timeline with discrete and continuous selection.
- Import the complete collection, a motion domain, or one primitive.
- Use any widget as content without adopting a package-specific data model.
- Run on Android, iOS, Web, Windows, macOS, and Linux.
Installation
Add the package from pub.dev:
flutter pub add huahua_motion
Or declare it directly:
dependencies:
huahua_motion: ^0.0.2
The current package requires Dart ^3.12.2 and Flutter >=1.17.0.
Choose an import
Import the complete collection when a feature uses primitives from several domains:
import 'package:huahua_motion/huahua_motion.dart';
Import one domain when related primitives are used together:
import 'package:huahua_motion/focus.dart';
import 'package:huahua_motion/timeline.dart';
Import an individual primitive to make a file's dependency explicit:
import 'package:huahua_motion/focus_transform.dart';
import 'package:huahua_motion/scroll_focus_transform.dart';
import 'package:huahua_motion/timeline_scrubber.dart';
Do not import files under lib/src/; they are implementation details and may
change without notice. Import granularity controls API visibility, not release
binary size: Flutter's tree shaker can remove unused code even when the complete
collection entrypoint is imported.
Motion primitives
HuahuaFocusTransform
HuahuaFocusTransform maps a normalized progress value to scale, opacity,
and translation. A value of 0 applies the unfocused state and 1 applies the
focused state. Values outside the range are clamped before the curve is applied.
import 'package:flutter/widgets.dart';
import 'package:huahua_motion/focus_transform.dart';
HuahuaFocusTransform(
progress: progress,
minScale: 0.88,
maxScale: 1,
minOpacity: 0.25,
maxOpacity: 1,
unfocusedOffset: const Offset(0, 12),
focusedOffset: Offset.zero,
curve: Curves.easeOutCubic,
child: card,
)
The caller owns progress, so it can come from an animation, gesture, scroll
measurement, sensor, or any other state source.
HuahuaScrollFocusTransform
HuahuaScrollFocusTransform measures a fixed-extent list item against a focus
point in the viewport. Only its lightweight transform wrappers rebuild during
scrolling; the supplied child is retained by AnimatedBuilder.
import 'package:huahua_motion/scroll_focus_transform.dart';
HuahuaScrollFocusTransform(
controller: scrollController,
itemOffset: leadingPadding + index * itemExtent,
itemExtent: itemExtent,
viewportExtent: viewportHeight,
focusAlignment: 0.5,
focusDistanceFactor: 1.2,
minScale: 0.82,
minOpacity: 0.22,
child: RepaintBoundary(child: itemBuilder(context, index)),
)
itemOffset is the item's leading position in scroll-content coordinates and
must include leading list padding. This primitive is intended for lists whose
main-axis item extent is known and fixed. It does not add snapping or change the
list's ScrollPhysics.
HuahuaTimelineScrubber
HuahuaTimelineScrubber is a transient, edge-aligned selector for a vertical
list. Provide one entry per list item so a timeline position maps directly to a
list index.
import 'package:huahua_motion/timeline_scrubber.dart';
final entries = <HuahuaTimelineEntry>[
const HuahuaTimelineEntry(label: 'Sep 10', isImportant: true),
const HuahuaTimelineEntry(),
const HuahuaTimelineEntry(label: 'Aug 28', isImportant: true),
];
HuahuaTimelineScrubber(
entries: entries,
currentIndex: currentIndex,
currentPosition: currentPosition,
onIndexChanged: handleIndexChanged,
onPositionChanged: handlePositionChanged,
onDragStart: handleDragStart,
onDragEnd: handleDragEnd,
)
The callbacks serve different integration needs:
onIndexChangedreports the nearest discrete node and is suitable for selection state or haptic feedback.onPositionChangedreports a fractional position during direct manipulation and is suitable for driving a list continuously.onDragEndreports velocity in item positions per second, which can seed a spring simulation.
Sparse timelines are centered. Dense timelines keep a fixed node spacing and
move a window through the full set instead of compressing every node. Important
entries may show a short label. Set reverseDragDirection when the controlled
content uses the opposite index direction.
Backdrop blur is enabled by default. Disable it on performance-sensitive screens:
HuahuaTimelineScrubber(
// ...
enableBackdropBlur: false,
)
HuahuaFixedExtentScrollTimeline
Use HuahuaFixedExtentScrollTimeline when you want the complete interaction
shown by the example. This high-level core widget combines focus transforms,
bidirectional timeline synchronization, fixed-extent snapping, automatic
visibility, and optional selection haptics.
import 'package:huahua_motion/fixed_extent_scroll_timeline.dart';
HuahuaFixedExtentScrollTimeline(
entries: timelineEntries,
itemExtent: 288,
itemBuilder: (context, index) => MyMomentWidget(
moment: moments[index],
),
)
itemBuilder accepts any Widget. The core package neither requires nor loads
images: image cards, text, editors, and other application widgets can all take
part in the focus interaction. Items must share one main-axis extent.
See the fixed-extent scroll timeline guide for controller ownership, focus customization, and integration constraints.
Package boundary
The package provides both low-level primitives and an optional high-level composition for fixed-extent lists.
Provided by huahua_motion |
Owned by the application |
|---|---|
| Focus interpolation | Focus progress source |
| Fixed-extent scroll measurement | List data and Widget content |
| Fixed-extent snapping and elastic physics | Variable-height geometry mapping |
| Timeline painting, gestures, and bidirectional synchronization | Grouping, pagination, and business selection state |
| Optional haptics and automatic visibility | Sound and route transitions |
| Optional backdrop blur | Image loading and error states |
The high-level widget still receives application content through itemBuilder,
so it imposes no image, navigation, state-management, or data architecture.
Compose the lower-level primitives directly for custom or variable-height
geometry.
Performance guidance
- Keep scrolling children stable; avoid constructing a new expensive subtree on every scroll tick.
- Wrap image-heavy or paint-heavy cards in
RepaintBoundarywhen profiling shows repaint cost. - Disable timeline backdrop blur when composition cost is more important than the glass effect.
- When composing primitives yourself, throttle timeline-to-scroll writes to one
update per frame.
HuahuaFixedExtentScrollTimelinedoes this internally. - Profile on representative physical devices before choosing final effects.
Example
The example opens with a catalog of independently runnable demos:
- An isolated focus-transform playground.
- A composed fixed-extent gallery with focus transforms, an edge timeline, snapping physics, haptics, and deterministic Picsum images.
The scrolling demo uses the core HuahuaFixedExtentScrollTimeline; its network
images and card content still come from the example's itemBuilder.
cd example
flutter run
The scrolling gallery requires an internet connection for images. Loading and failure placeholders preserve card dimensions and scroll geometry.
API status
The package is currently at 0.0.2. Public entrypoints are available, but the
API should still be treated as early-stage.
License
See LICENSE.
Libraries
- fixed_extent_scroll_timeline
- A coordinated fixed-extent focus list and edge timeline.
- focus
- Focus-driven motion primitives.
- focus_transform
- A focus-driven scale, opacity, and translation transform.
- huahua_motion
- All composable motion primitives provided by huahua_motion.
- scroll_focus_transform
- A focus transform driven by a fixed-extent scroll position.
- timeline
- Timeline motion primitives.
- timeline_scrubber
- An edge-aligned timeline selector for vertically scrolling content.