depthlift 0.2.0 copy "depthlift: ^0.2.0" to clipboard
depthlift: ^0.2.0 copied to clipboard

Convert any 2D image into a live 3D parallax scene with on-device depth estimation. Inspired by iOS depth effects.

DepthLift #

pub package License: MIT

Transform any 2D image into a live, interactive 3D parallax scene with on-device depth estimation. Inspired by iPhone's depth wallpaper effect.

✨ What it does #

Tilt your phone → the image comes alive in 3D

  • iPhone-like gyro motion — damped, interpolated, zero jitter
  • On-device depth estimation — Depth Anything v2 via TFLite / Core ML
  • Real-time GPU rendering — OpenGL ES 3.0 (Android) / Metal (iOS) at 60 FPS
  • 3-tier input fallback — Gyroscope → Touch drag → Idle float animation
  • 4 motion presets — iOS Natural, Cinematic, Soft, Intense
  • Frame export — capture PNG stills

🚀 Quick Start #

dependencies:
  depthlift: ^0.2.0
import 'package:depthlift/depthlift.dart';

DepthLiftView(
  image: const AssetImage('assets/photo.jpg'),
  options: const DepthLiftOptions(
    effect: DepthEffect.parallax,
    useGyroscope: true,
  ),
);

That's it. The widget handles depth estimation, mesh construction, and rendering automatically.

🎬 Motion Presets #

// iPhone wallpaper feel — ultra-smooth, subtle, premium
DepthLiftOptions.fromPreset(DepthPreset.iosNatural)

// Cinematic parallax — moderate, dramatic
DepthLiftOptions.fromPreset(DepthPreset.cinematic)

// Gentle movement — good for portraits
DepthLiftOptions.fromPreset(DepthPreset.soft)

// Bold, aggressive parallax
DepthLiftOptions.fromPreset(DepthPreset.intense)

🎛️ Controller #

final ctrl = DepthLiftController();

DepthLiftView(
  image: const AssetImage('assets/photo.jpg'),
  controller: ctrl,
);

// Start the breathing animation
await ctrl.play();

// Switch effect on the fly
await ctrl.setEffect(DepthEffect.bokeh);

// Export a still frame
final Uint8List png = await ctrl.exportFrame();

// Listen to state changes
ctrl.stateStream.listen((state) {
  // DepthLiftState.loading | .ready | .error
});

// Always dispose when done
ctrl.dispose();

🎯 iPhone-Style Gyro Engine #

The IOSStyleGyroController is the secret sauce. Unlike raw gyro mapping, it uses:

Technique Purpose
Ticker-based updates Frame-synced at 60 FPS, not raw stream events
lerpDouble smoothing Interpolates toward target each frame
Decay factor Prevents drift, gently returns to centre
Low sensitivity 0.01–0.02 range for subtle motion
Clamped range Max ±0.25 offset — keeps motion premium

The result: motion that feels floating, damped, and slightly delayed — just like iOS.

// Use it standalone if you want
final gyro = IOSStyleGyroController.iosNatural();
await gyro.init(vsync);

gyro.offset.addListener(() {
  final o = gyro.offset.value;
  // o.dx, o.dy = smoothed tilt values
});

gyro.dispose();

⚙️ Options Reference #

Field Type Default Description
effect DepthEffect .parallax Active visual effect
depthModel DepthModel .depthAnythingV2 Depth estimation backend
depthScale double 0.6 Z-axis displacement (0.0–1.0)
parallaxFactor double 0.4 Motion multiplier (0.0–1.0)
meshResolution double 64 Grid subdivisions (16–256)
focusDepth double 0.5 Bokeh focal plane (0.0–1.0)
bokehIntensity double 0.5 Blur strength (0.0–1.0)
floatDuration Duration 3s Float animation cycle
useGyroscope bool true Enable gyroscope input
lowPowerMode bool false Halves mesh, disables bokeh

📱 Platform Setup #

Android #

Minimum SDK: 24 (Android 7.0)

android {
    defaultConfig {
        minSdkVersion 24
    }
}

The plugin declares android.hardware.sensor.gyroscope with required="false" — works on all devices including emulators and tablets without gyroscope.

iOS #

Deployment target: 14.0

Add to Info.plist:

<key>NSMotionUsageDescription</key>
<string>Used for parallax depth effect</string>

In ios/Podfile:

platform :ios, '14.0'

🔄 Input Fallback System #

The plugin automatically detects available input and falls back gracefully:

1. Gyroscope (if hardware available + useGyroscope: true)
   ↓ not available
2. Touch/Mouse drag (GestureDetector)
   ↓ finger lifted
3. Float animation (Lissajous idle breathing)

No configuration needed — it just works on every device.

🏗️ Architecture #

┌──────────────────────────────────────────────────┐
│  Flutter (Dart)                                  │
│  ┌──────────────┐  ┌──────────────────────────┐  │
│  │DepthLiftView │──│ DepthLiftController      │  │
│  └──────┬───────┘  └──────────────────────────┘  │
│         │                                        │
│  ┌──────▼───────────────────────────────────┐    │
│  │ DepthLiftInputManager                    │    │
│  │  ├─ IOSStyleGyroController (Ticker+Lerp) │    │
│  │  ├─ PointerController (touch drag)       │    │
│  │  └─ FloatAnimationController (idle)      │    │
│  └──────┬───────────────────────────────────┘    │
│         │                                        │
│  ┌──────▼──────────────────────────────────┐     │
│  │ MethodChannel (dev.depthlift/engine)    │     │
│  └──────┬──────────────────────────────────┘     │
├─────────┼────────────────────────────────────────┤
│  Native │                                        │
│  ┌──────▼──────┐  ┌──────────────────────────┐   │
│  │ Plugin      │──│ DepthRenderer            │   │
│  │ (Kt/Swift)  │  │ GLES 3.0 / Metal         │   │
│  └─────────────┘  └──────────────────────────┘   │
└──────────────────────────────────────────────────┘

🧪 Testing #

flutter test

📄 License #

MIT License — see LICENSE for details.

2
likes
120
points
34
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Convert any 2D image into a live 3D parallax scene with on-device depth estimation. Inspired by iOS depth effects.

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

flutter, sensors_plus, tflite_flutter

More

Packages that depend on depthlift

Packages that implement depthlift