// lottie in shape
Lottie in shape
Fiber3DWidgetTexture renders any Flutter widget off-screen and copies it into a texture many times a second. Put that texture on a shape and the shape shows the widget live. This is how you put a Lottie animation, a video player, a chart or an animated counter onto a 3D surface.
flutter_fiber has no Lottie dependency. Your app brings whichever package produces the widget. This page uses the lottie package, but any widget works the same way.
// demo
Demo
A Lottie animation playing live on a Fiber3DPlane.
// how to use it
How to use it
Replace your_animation.json with your own Lottie file.
1. Add the Lottie package and your animation file:
flutter pub add lottieflutter:
assets:
- assets/lottie/your_animation.json2. Create a placeholder texture and load the file. The texture starts as one white pixel and is replaced by the real animation as soon as the first frame is captured. In a State class:
import 'dart:typed_data';
import 'package:flutter/services.dart' show rootBundle;
import 'package:flutter_fiber/flutter_fiber.dart';
import 'package:lottie/lottie.dart';
// A 1x1 white placeholder, shown until the first frame is captured.
final Fiber3DTexture _texture = Fiber3DTexture.raw(
Uint8List.fromList([255, 255, 255, 255]),
1,
1,
);
Uint8List? _lottieBytes;
@override
void initState() {
super.initState();
rootBundle.load('assets/lottie/your_animation.json').then((data) {
if (!mounted) return;
setState(() {
_lottieBytes = data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
});
});
}3. Build the scene. Put a Stack around the canvas and add Fiber3DWidgetTexture as its sibling, with the animation as its child. The mesh that shows it uses the same texture as its map:
// A Stack holds the canvas and the widget texture side by side.
Stack(
children: [
Fiber3DCanvas(
// camera, lights, orbitEnabled ... as usual
children: [
Fiber3DMesh(
geometry: Fiber3DPlane(width: 2, height: 2),
material: Fiber3DStandardMaterial(
map: _texture,
roughness: 1.0,
metalness: 0.0,
),
showEdges: false,
// Keeps the canvas rendering so it keeps re-reading the texture.
onFrame: (elapsed, delta, transform) {},
),
],
),
if (_lottieBytes != null)
Fiber3DWidgetTexture(
texture: _texture,
child: Lottie.memory(_lottieBytes!),
),
],
)// parameters
Parameters
Parameters of Fiber3DWidgetTexture:
child
default requiredThe widget to capture (here, the Lottie animation).
texture
default requiredThe Fiber3DTexture that is updated with each captured frame.
width
default 256Off-screen render width in logical pixels. Larger = sharper, but slower.
height
default 256Off-screen render height in logical pixels.
fps
default 30How often the widget is captured, independent of the child's own animation rate.
// tips & limits
Tips & limits
Fiber3DWidgetTexturemust be a direct child of aStack. It keeps the widget painted off-screen, out of sight, so it can be captured.- Give the mesh an
onFrame, even an empty one. Without any registeredonFramethe canvas stops rendering after one frame and never picks up the texture's updates. - A larger
width/heightgives a sharper texture but costs more per capture. Match the aspect ratio of the surface you map it on (the default 256 x 256 suits a square plane). fpsonly controls how often the widget is sampled. A lower value saves work; the animation itself keeps its own speed.- Only
Fiber3DStandardMaterialaccepts textures, and the texture is lit like any surface. - For text that never changes, use Text in shape instead: it rasterizes once, with no per-frame cost.