huahua_motion 0.0.3 copy "huahua_motion: ^0.0.3" to clipboard
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:

  • onIndexChanged reports the nearest discrete node and is suitable for selection state or haptic feedback.
  • onPositionChanged reports a fractional position during direct manipulation and is suitable for driving a list continuously.
  • onDragEnd reports 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 RepaintBoundary when 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. HuahuaFixedExtentScrollTimeline does 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.

0
likes
160
points
51
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Composable, focus-driven motion primitives for Flutter interfaces.

Repository (GitHub)
View/report issues

Topics

#animation #motion #scroll #timeline #widget

License

MIT (license)

Dependencies

flutter

More

Packages that depend on huahua_motion