kinetic_gallery 0.1.2 copy "kinetic_gallery: ^0.1.2" to clipboard
kinetic_gallery: ^0.1.2 copied to clipboard

Gesture-driven Flutter galleries featuring dynamic hero carousels and virtualized, zoomable infinite masonry spaces.

Kinetic Gallery #

English · 简体中文

Interactive card layouts for Flutter: a dynamically sized Hero Carousel and a zoomable infinite masonry space. Content is supplied by your widgets; the core package depends only on Flutter.

0.1.2 · Flutter ≥ 3.44.5 · Dart ≥ 3.12.2, < 4.0.0

Preview #

Kinetic Gallery home

Hero Carousel Infinite Gallery
Hero Carousel Infinite Gallery
Zoom, photo focus, and mobile
Zoom out · 60% Zoom in · 180%
Infinite Gallery at 60% zoom Infinite Gallery at 180% zoom
Photo focus Return to gallery
Expanded photo Gallery after closing a photo
Infinite Gallery on mobile

Get started #

Repository · Issues · MIT License

Usage #

After the first pub.dev release, install with flutter pub add kinetic_gallery. Before publication, use the local path setup in the integration guide.

import 'package:flutter/material.dart';
import 'package:kinetic_gallery/kinetic_gallery.dart';

Widget carouselExample() => HeroCarousel.builder(
  itemCount: 12,
  height: 260,
  viewportFraction: 0.56,
  borderRadius: BorderRadius.circular(20),
  itemBuilder: (context, index) => ColoredBox(
    color: Colors.primaries[index % Colors.primaries.length],
    child: Center(child: Text('Card $index')),
  ),
);

Widget infiniteExample() => SizedBox(
  height: 500,
  child: InfiniteCardSpace.builder(
    cardSize: const Size(180, 230),
    spacing: 24,
    heightPattern: const [0.76, 1.22, 0.94, 1.48, 1.06],
    itemBuilder: (context, column, row) => ColoredBox(
      color: Colors.primaries[(column + row) % Colors.primaries.length],
      child: Center(child: Text('$column, $row')),
    ),
  ),
);

Place these widgets inside a MaterialApp / Scaffold. Supply your own images or interactive widgets through itemBuilder; network loading is not part of the package. Give both layouts a bounded width and the infinite canvas a bounded height.

Main APIs #

HeroCarousel #

Use HeroCarousel.builder for indexed content or HeroCarousel(children: [...]) for an existing widget list.

Parameter Default Purpose
itemCount, itemBuilder Required for .builder Number of cards and (context, index) => Widget
height 240 Carousel height
viewportFraction 0.56 Active slot width relative to viewport; (0, 1]
spacing 8 Gap between cards
activeScale, inactiveScale 1, 0.78 Active and inactive card scale
activeOpacity, inactiveOpacity 1, 0.58 Active and inactive card opacity
loop, snap false, true Looping and snapping
duration, curve 380 ms, Curves.easeOutCubic Transition timing
controller null Programmatic navigation
itemKeyBuilder null Stable Key Function(int index) for reorderable data
borderRadius null Optional card clipping radius
onIndexChanged null Receives the active logical index
transformBuilder null Custom visual wrapper using GalleryItemMetrics

KineticCarouselController #

Create the controller once in State, pass it to one carousel, and dispose it when the state is disposed. Call navigation methods only after attachment.

final controller = KineticCarouselController(initialIndex: 0);

// Pass controller: controller to HeroCarousel.builder.
// Inside a button callback after the carousel has mounted:
if (controller.isAttached) {
  await controller.next();
}

// Inside State.dispose(): controller.dispose();
Member Purpose
next(), previous() Animate one card forward or backward
animateTo(index) Animate to a logical index
jumpTo(index) Move immediately
currentIndex Read the active index
isAttached Check whether a carousel is connected
addListener, removeListener Observe index changes

InfiniteCardSpace #

Parameter Default Purpose
itemBuilder Required (context, column, row) => Widget; coordinates may be negative
cardSize Size(180, 230) Base card width and height
spacing 24 Nonnegative gap between cards
heightPattern [1.0] Immutable repeating positive height factors; multiple factors create masonry columns
minScale, maxScale 0.6, 1.8 Zoom limits
initialScale 1.0 Initial zoom, within the limits; not a controlled value
onScaleChanged null Receives the updated zoom factor

Only visible cards and a surrounding buffer are mounted. There is no itemCount; map signed coordinates to your own data. Reset the canvas by changing its widget key. Pan by dragging, scrolling, or arrow keys; zoom with a pinch, Ctrl+wheel, or the plus/minus keys while focused.

PhotoPreview #

PhotoPreview opens an image-focused Hero route without coupling that behavior to InfiniteCardSpace. It uses the nearest Navigator, so each visible tag must be unique in that navigator. The destination is built separately from the thumbnail; use it for images and visual content, not for a guaranteed single state instance of a player, platform view, or GlobalKey widget.

Widget buildPhoto() => ClipRRect(
  borderRadius: BorderRadius.circular(20),
  child: Image.network(url, fit: BoxFit.cover),
);

PhotoPreview(
  tag: 'gallery:$id',
  aspectRatio: 0.8,
  previewBuilder: (_) => buildPhoto(),
  child: buildPhoto(),
)

Use enabled or canOpen to gate taps during a parent gesture. For custom tap handling, wrap the source in PhotoPreviewHero and call showPhotoPreview with the same tag and style. PhotoPreviewStyle configures the light backdrop, target size, transition, drag threshold, and close control. Defaults preserve the example's 420ms easeOutCubic transition, 80% safe-area size, and vertical dismissal behavior.

Custom transforms and other exports #

GalleryTransformBuilder receives (context, child, metrics). GalleryItemMetrics exposes index, signed distance, progress (max(0, 1 - abs(distance))), and isActive. Return a visual wrapper such as Transform.rotate; the wrapper does not change the layout slot.

DepthCarousel and MorphGallery remain exported for compatibility. MorphGalleryController provides focus(index), unfocus(), toggle(index), focusedIndex, and isAttached. See the additional API reference. The infinite canvas does not expose focus methods; compose it with PhotoPreview when cards should open a preview.

What is included #

  • HeroCarousel: dynamic card widths, snapping, optional looping, controller navigation, custom visual transforms.
  • InfiniteCardSpace: virtualized signed-coordinate layout, periodic masonry heights, four-direction panning, focal pinch zoom (60%–180% by default), desktop zoom input.
  • PhotoPreview: configurable Hero image preview route with tap, keyboard, backdrop, button, system-back, and drag dismissal.

The current example has two entries. MorphGallery, its controller, and DepthCarousel remain exported for compatibility. See historical API notes.

Verification #

See validation records for executed tests and platform limitations, and architecture notes for implementation context. Browser screenshots use real network photos; regression tests use deterministic content. Simulated touch checks are not physical-device certification.

5
likes
160
points
128
downloads

Documentation

API reference

Publisher

verified publisherleewei0923.com

Weekly Downloads

Gesture-driven Flutter galleries featuring dynamic hero carousels and virtualized, zoomable infinite masonry spaces.

Repository (GitHub)
View/report issues

Topics

#gallery #carousel #animation #image #ui

License

MIT (license)

Dependencies

flutter

More

Packages that depend on kinetic_gallery