huahua_motion 0.0.3
huahua_motion: ^0.0.3 copied to clipboard
Composable, focus-driven motion primitives for Flutter interfaces.
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 fixed- or varied-extent scrolling lists.
- 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.flutter-io.cn:
flutter pub add huahua_motion
Or declare it directly:
dependencies:
huahua_motion: ^0.0.3
The current package requires Dart ^3.12.2 and Flutter >=3.44.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 type. The core package neither requires nor
loads images, but every item in this fixed component is constrained to the same
itemExtent.
See the fixed-extent scroll timeline guide for controller ownership, focus customization, and integration constraints.
Varied and measured scroll timelines #
Use HuahuaVariedExtentScrollTimeline when item heights are known but differ:
HuahuaVariedExtentScrollTimeline(
controller: controller,
itemCount: items.length,
itemExtentBuilder: (index) => items[index].layoutExtent,
itemKeyBuilder: (index) => ValueKey(items[index].id),
entries: timelineEntries,
onIndexChanged: onIndexChanged,
itemBuilder: buildItem,
)
It maps item centers with extent prefix sums and snaps by center rather than by
index * itemExtent. If heights are not known, the experimental
HuahuaMeasuredScrollTimeline measures visible children and uses
estimatedItemExtent for items not yet laid out. See the
varied-extent guide.
Package boundary #
The package provides both low-level primitives and high-level fixed, varied, and experimental measured list compositions.
Provided by huahua_motion |
Owned by the application |
|---|---|
| Focus interpolation | Focus progress source |
| Fixed and varied center geometry | List data and Widget content |
| Fixed and varied snapping physics | Item height estimates and business layout |
| 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.
The measured timeline remains experimental because offscreen items initially
use estimated 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 varied-extent gallery with irregular image, mixed-media, and text-only cards, plus an edge timeline, snapping physics, and haptics.
The scrolling demo uses the core HuahuaVariedExtentScrollTimeline; 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.3. Public entrypoints are available, but the
API should still be treated as early-stage.
License #
See LICENSE.