perspective_space 0.1.0 copy "perspective_space: ^0.1.0" to clipboard
perspective_space: ^0.1.0 copied to clipboard

Buttery-smooth 3D perspective and parallax widgets for Flutter. Tilt, shake, and stack layers with depth — gesture-driven or auto-animated. Zero dependencies, works on every Flutter platform.

perspective_space #

Buttery-smooth 3D perspective and parallax widgets for Flutter — tilt, shake, and stack layers with depth. Gesture-driven or auto-animated.

pub package Flutter License: MIT Platforms

Basic tilt Gesture tilt Entry shake Parallax stack Dialog

perspective_space gives you depth on every Flutter platform with two primitives and three presets — and zero third-party dependencies.

中文文档 →


Features #

  • PerspectiveSpace + PerspectiveLayer — a tiny pair of widgets that publish a shared rotation/perspective and let descendant layers render with depth-aware parallax.
  • Gesture-driven tilt — drag to rotate, configurable sensitivity, clamped max angle, elastic spring-back on release.
  • Entry shake — one-shot 3D flip-and-settle when the widget mounts.
  • Presets for the 90% case:
    • PerspectiveTiltCard — single tilting card, one-line setup.
    • PerspectiveParallax — multi-layer parallax stack from a list.
    • PerspectiveShakeEntry — wrap any widget, play a shake on entry.
  • Controller for triggering shakes from outside the subtree.
  • Zero dependencies, pure Dart + Flutter SDK.

Install #

dependencies:
  perspective_space: ^0.1.0
flutter pub add perspective_space

Quick start #

A tilting card #

import 'package:perspective_space/perspective_space.dart';

PerspectiveTiltCard(
  child: Container(
    width: 280,
    height: 360,
    decoration: BoxDecoration(
      gradient: const LinearGradient(
        colors: [Color(0xFFFF5BAA), Color(0xFF8B5CF6)],
      ),
      borderRadius: BorderRadius.circular(28),
    ),
    alignment: Alignment.center,
    child: const Text('TILT'),
  ),
);

Drag it — every Flutter platform, no glue code.

Multi-layer parallax #

PerspectiveParallax(
  layers: [
    PerspectiveLayerSpec(elevation: 0,  child: backgroundCard),
    PerspectiveLayerSpec(elevation: 40, child: middleCard),
    PerspectiveLayerSpec(elevation: 90, child: foregroundContent),
  ],
)

Higher elevation = closer to the camera = stronger parallax offset.

One-shot entry shake #

PerspectiveShakeEntry(
  delay: const Duration(milliseconds: 200),
  child: yourRewardCard,
)

Hand-rolled with the primitives #

When you outgrow the presets, drop straight to PerspectiveSpace + PerspectiveLayer:

PerspectiveSpace(
  enableGesture: true,
  maxRotation: 30,
  child: Stack(
    children: [
      PerspectiveLayer(elevation: 0,  child: background),
      PerspectiveLayer(elevation: 50, child: card),
      PerspectiveLayer(elevation: 90, child: content),
    ],
  ),
);

Imperative shake #

final controller = PerspectiveSpaceController();

PerspectiveSpace(
  controller: controller,
  child: ...,
);

// Later, from a button handler:
controller.shake();

API at a glance #

Widget Purpose
PerspectiveSpace Root container; publishes rotation + perspective.
PerspectiveLayer Child layer; applies a depth-aware transform.
PerspectiveSpaceController Imperative handle (controller.shake()).
PerspectiveTiltCard Preset: a single tilting card.
PerspectiveParallax Preset: a parallax stack from PerspectiveLayerSpecs.
PerspectiveShakeEntry Preset: shake on first mount, then rest.

Useful PerspectiveSpace parameters #

Parameter Default Notes
rotateX, rotateY 0 Initial tilt, in radians.
perspective 0.0015 1 / cameraDistance; bigger = stronger foreshortening (0.0010.002 is the sweet spot).
enableGesture false Drag to tilt in real time.
sensitivity 0.005 Radians per logical pixel of drag.
maxRotation 60 Hard cap on the gesture-driven tilt, in degrees.
resetOnRelease true Spring back to (rotateX, rotateY) on pointer up.
resetDuration 800ms Spring-back duration.
resetCurve Curves.elasticOut Spring-back curve.
entryShake false Play a one-shot shake on first mount.

Platform support #

iOS Android Web macOS Windows Linux

perspective_space is pure Dart; everything renders through Flutter's own 3D Transform. There are no plugin channels and no native code.

FAQ #

Q. How does PerspectiveSpace differ from a plain Transform? It publishes its rotation to descendants and lets PerspectiveLayers contribute their own Z offset. The result is a single, coherent perspective camera with independent parallax depth per layer — instead of nested Transforms that double-stack matrices.

Q. Why does my nested PerspectiveLayer look subtle? By design — an inner PerspectiveLayer only contributes additional parallax offset, never re-applies the perspective + rotation matrices. Increase its elevation, or move it up to the same Stack as the outer layer if you want a stronger effect.

Q. Is the entry shake configurable? Today the shake amplitude and timing are fixed for snappy feel. PRs welcome if you need it tunable.

Example #

A full showcase app (the source of the GIFs above) lives in example/. To run it locally:

cd example
flutter run            # any platform

Contributing #

Issues and PRs welcome — particularly around new presets, platform-specific tuning, and golden tests. Run the test suite with:

flutter test
cd example && flutter test

License #

MIT © 2026 cccmax.

1
likes
150
points
109
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Buttery-smooth 3D perspective and parallax widgets for Flutter. Tilt, shake, and stack layers with depth — gesture-driven or auto-animated. Zero dependencies, works on every Flutter platform.

Repository (GitHub)
View/report issues

Topics

#ui #animation #transform #parallax #perspective

License

MIT (license)

Dependencies

flutter

More

Packages that depend on perspective_space