Lottie not working in web since 3.1.2
After updating from 3.1.1 to 3.1.2 I cannot use it in my web view anymore I get the following error:
The following UnsupportedError was thrown during paint():
Unsupported operation: toImageSync is not supported on the HTML backend. Use drawPicture instead, or toImage.
The relevant error-causing widget was:
RawLottie RawLottie:file://.pub-cache/hosted/pub.dev/lottie-3.1.2/lib/src/lottie.dart:442:16
When the exception was thrown, this was the stack:
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 296:3 throw_
lib/_engine/engine/picture.dart 90:5 toImageSync
packages/lottie/src/render_cache/store_raster.dart 123:24 imageForProgress
packages/lottie/src/render_cache/store_raster.dart 144:23 draw
packages/lottie/src/render_cache/store_raster.dart 59:17 draw
packages/lottie/src/lottie_drawable.dart 219:30 draw
packages/lottie/src/render_lottie.dart 268:5 paint
packages/flutter/src/rendering/object.dart 3239:7 [_paintWithContext]
packages/flutter/src/rendering/object.dart 250:12 paintChild
packages/flutter/src/rendering/proxy_box.dart 130:12 paint
packages/flutter/src/rendering/object.dart 3239:7 [_paintWithContext]
packages/flutter/src/rendering/object.dart 166:10 _repaintCompositedChild
packages/flutter/src/rendering/object.dart 109:5 repaintCompositedChild
packages/flutter/src/rendering/object.dart 1182:31 flushPaint
packages/flutter/src/rendering/object.dart 1192:14 flushPaint
packages/flutter/src/rendering/binding.dart 579:5 drawFrame
packages/flutter/src/widgets/binding.dart 1138:13 drawFrame
packages/flutter/src/rendering/binding.dart 443:5 [_handlePersistentFrameCallback]
packages/flutter/src/scheduler/binding.dart 1392:7 [_invokeFrameCallback]
packages/flutter/src/scheduler/binding.dart 1313:9 handleDrawFrame
packages/flutter/src/scheduler/binding.dart 1171:5 [_handleDrawFrame]
lib/_engine/engine/platform_dispatcher.dart 1404:5 invoke
lib/_engine/engine/platform_dispatcher.dart 307:5 invokeOnDrawFrame
lib/_engine/engine/initialization.dart 187:36 <fn>
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 426:37 _checkAndCall
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 431:39 dcall
The following RenderObject was being processed when the exception was fired: RenderLottie#51e5b relayoutBoundary=up5
... parentData: <none> (can use size)
... constraints: BoxConstraints(0.0<=w<=399.0, 0.0<=h<=1142.0)
... size: Size(100.0, 100.0)
... composition: LottieComposition:
Ebene 4/n loader Konturen
Shapes:
ShapeGroup{name: 'Gruppe 1' Shapes: [ShapePath{name=Pfad 1, index=0}, ShapeFill{color=, fillEnabled=false}, Instance of 'AnimatableTransform']}
ShapeGroup{name: 'Gruppe 2' Shapes: [ShapePath{name=Pfad 1, index=0}, ShapeFill{color=, fillEnabled=false}, Instance of 'AnimatableTransform']}
ShapeGroup{name: 'Gruppe 3' Shapes: [ShapePath{name=Pfad 1, index=0}, ShapeFill{color=, fillEnabled=false}, Instance of 'AnimatableTransform']}
... width: 100.0
... height: 100.0
... fit: contain
... alignment: Alignment.center
RenderObject: RenderLottie#51e5b relayoutBoundary=up5
parentData: <none> (can use size)
constraints: BoxConstraints(0.0<=w<=399.0, 0.0<=h<=1142.0)
size: Size(100.0, 100.0)
composition: LottieComposition:
Ebene 4/n loader Konturen
Shapes:
ShapeGroup{name: 'Gruppe 1' Shapes: [ShapePath{name=Pfad 1, index=0}, ShapeFill{color=, fillEnabled=false}, Instance of 'AnimatableTransform']}
ShapeGroup{name: 'Gruppe 2' Shapes: [ShapePath{name=Pfad 1, index=0}, ShapeFill{color=, fillEnabled=false}, Instance of 'AnimatableTransform']}
ShapeGroup{name: 'Gruppe 3' Shapes: [ShapePath{name=Pfad 1, index=0}, ShapeFill{color=, fillEnabled=false}, Instance of 'AnimatableTransform']}
width: 100.0
height: 100.0
fit: contain
alignment: Alignment.center
@konsultaner can you show how you configure the lottie widget? Do you use the renderCache property?
@xvrh sorry, totally rushed that issue. This is my file including the lottie asset.
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:lottie/lottie.dart';
class QRCodeLoginNoScan extends StatelessWidget {
const QRCodeLoginNoScan({super.key});
@override
Widget build(BuildContext context) {
var lottieDelegates = [
if (Theme.of(context).brightness == Brightness.dark)
ValueDelegate.colorFilter(
const [ '**'],
value: ColorFilter.mode(Theme.of(context).colorScheme.onSurface, BlendMode.src),
),
if (Theme.of(context).brightness == Brightness.light)
ValueDelegate.colorFilter(
const [ '**', 'scan', '**'],
value: ColorFilter.mode(Theme.of(context).primaryColor, BlendMode.src),
),
if (Theme.of(context).brightness == Brightness.light)
ValueDelegate.colorFilter(
const [ '**', 'phone', 'Group 1', '**'],
value: ColorFilter.mode(Theme.of(context).primaryColor, BlendMode.src),
)
];
return Padding(
padding: const EdgeInsets.symmetric(vertical: 200, horizontal: 20),
child: Center(
child: FittedBox(
fit: BoxFit.contain,
child: Lottie.asset(
width: max(MediaQuery.of(context).size.width,MediaQuery.of(context).size.height),
height: max(MediaQuery.of(context).size.width,MediaQuery.of(context).size.height),
fit: BoxFit.contain,
'assets/lottie/qr_code_animation.json',
renderCache: RenderCache.raster,
delegates: LottieDelegates(values: lottieDelegates),
),
),
),
);
}
}
I think you should drop the renderCache: RenderCache.raster. It's not supported in the web with the html-renderer.
Alternatively, you can also try the canvaskit renderer.
I think you should drop the renderCache: RenderCache.raster. It's not supported in the web with the html-renderer.
Maybe the package should add a debug warning and have a kIsWeb check on the renderCache so nobody else will have to face this issue?
I think it works with the canvaskit renderer so kIsWeb is not enough. We need to detect the web-renderer used and I don't know if it's possible.
And this library works poorly with the html-renderer anyway, they are a lot of limitations.
Furthermore it's likely that the html-renderer will go away: https://github.com/flutter/flutter/issues/145954
I changed my code to:
import 'dart:math';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:lottie/lottie.dart';
class QRCodeLoginNoScan extends StatelessWidget {
const QRCodeLoginNoScan({super.key});
@override
Widget build(BuildContext context) {
var lottieDelegates = [
if (Theme.of(context).brightness == Brightness.dark)
ValueDelegate.colorFilter(
const [ '**'],
value: ColorFilter.mode(Theme.of(context).colorScheme.onSurface, BlendMode.src),
),
if (Theme.of(context).brightness == Brightness.light)
ValueDelegate.colorFilter(
const [ '**', 'scan', '**'],
value: ColorFilter.mode(Theme.of(context).primaryColor, BlendMode.src),
),
if (Theme.of(context).brightness == Brightness.light)
ValueDelegate.colorFilter(
const [ '**', 'phone', 'Group 1', '**'],
value: ColorFilter.mode(Theme.of(context).primaryColor, BlendMode.src),
)
];
return Padding(
padding: const EdgeInsets.symmetric(vertical: 200, horizontal: 20),
child: Center(
child: Lottie.asset(
width: max(MediaQuery.of(context).size.width,MediaQuery.of(context).size.height),
height: max(MediaQuery.of(context).size.width,MediaQuery.of(context).size.height),
//fit: BoxFit.contain,
'assets/lottie/qr_code_animation.json',
renderCache: kIsWeb ? null : RenderCache.raster,
delegates: LottieDelegates(values: lottieDelegates),
),
),
);
}
}
on first load eveything works great but on hot-reload I get this error:
The following PersistedSurfaceException was thrown during a scheduler callback:
PersistedScene: is in an unexpected state.
Expected one of: PersistedSurfaceState.active, PersistedSurfaceState.pendingUpdate
But was: PersistedSurfaceState.released
When the exception was thrown, this was the stack:
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 296:3 throw_
lib/_engine/engine/html/surface.dart 181:3 debugAssertSurfaceState
lib/_engine/engine/html/surface.dart 705:12 update
lib/_engine/engine/html/scene_builder.dart 506:9 <fn>
lib/_engine/engine/profiler.dart 41:18 timeAction
lib/_engine/engine/html/scene_builder.dart 502:12 build
packages/flutter/src/rendering/layer.dart 1138:35 buildScene
packages/flutter/src/rendering/view.dart 304:30 compositeFrame
packages/flutter/src/rendering/binding.dart 582:19 drawFrame
packages/flutter/src/widgets/binding.dart 1138:13 drawFrame
packages/flutter/src/rendering/binding.dart 443:5 [_handlePersistentFrameCallback]
packages/flutter/src/scheduler/binding.dart 1392:7 [_invokeFrameCallback]
packages/flutter/src/scheduler/binding.dart 1313:9 handleDrawFrame
packages/flutter/src/scheduler/binding.dart 1171:5 [_handleDrawFrame]
lib/_engine/engine/platform_dispatcher.dart 1404:5 invoke
lib/_engine/engine/platform_dispatcher.dart 307:5 invokeOnDrawFrame
lib/_engine/engine/initialization.dart 187:36 <fn>
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 426:37 _checkAndCall
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 431:39 dcall
Is that lottie related? Never seen anything like this.