flutter_device_preview
flutter_device_preview copied to clipboard
Flutter web frame problem
Using DevicePreview to run on chrome shows the following error, no device frame is shown:
══════╡ EXCEPTION CAUGHT BY RENDERING LIBRARY The following UnimplementedError was thrown during paint(): UnimplementedError The relevant error-causing widget was: CustomPaint
When the exception was thrown, this was the stack:
dart-sdk/lib/internal/js_dev_runtime/private/ddc_runtime/errors.dart 216:49 throw
lib/ui/src/ui/path.dart 281:5 combine
packages/device_preview/src/frames/mobile_device_frame.dart 212:14 paint
packages/flutter/src/rendering/custom_paint.dart 531:12 [_paintWithPainter]
packages/flutter/src/rendering/custom_paint.dart 572:7 paint
packages/flutter/src/rendering/object.dart 2264:7 [_paintWithContext]
packages/flutter/src/rendering/object.dart 184:12 paintChild
packages/flutter/src/rendering/proxy_box.dart 129:14 paint
packages/flutter/src/rendering/object.dart 2264:7 [_paintWithContext]
packages/flutter/src/rendering/object.dart 184:12 paintChild
packages/flutter/src/rendering/box.dart 2515:14 defaultPaint
packages/flutter/src/rendering/stack.dart 602:5 paintStack
packages/flutter/src/rendering/stack.dart 610:7 paint
packages/flutter/src/rendering/object.dart 2264:7 [_paintWithContext]
packages/flutter/src/rendering/object.dart 184:12 paintChild
packages/flutter/src/rendering/shifted_box.dart 70:14 paint
packages/flutter/src/rendering/object.dart 2264:7 [_paintWithContext]
packages/flutter/src/rendering/object.dart 184:12 paintChild
packages/flutter/src/rendering/proxy_box.dart 129:14 paint
packages/flutter/src/rendering/object.dart 2264:7 [_paintWithContext]
packages/flutter/src/rendering/object.dart 135:10 _repaintCompositedChild
packages/flutter/src/rendering/object.dart 95:5 repaintCompositedChild
packages/flutter/src/rendering/object.dart 201:7 [_compositeChild]
packages/flutter/src/rendering/object.dart 182:7 paintChild
packages/flutter/src/rendering/proxy_box.dart 129:14 paint
packages/flutter/src/rendering/object.dart 391:12 pushLayer
packages/flutter/src/rendering/object.dart 572:7 pushTransform
packages/flutter/src/rendering/proxy_box.dart 2389:21 [_paintChildWithTransform]
packages/flutter/src/rendering/proxy_box.dart 2406:17 paint
packages/flutter/src/rendering/object.dart 2264:7 [_paintWithContext]
packages/flutter/src/rendering/object.dart 184:12 paintChild
packages/flutter/src/rendering/proxy_box.dart 129:14 paint
packages/flutter/src/rendering/proxy_box.dart 2040:11 paint
packages/flutter/src/rendering/object.dart 2264:7 [_paintWithContext]
packages/flutter/src/rendering/object.dart 184:12 paintChild
packages/flutter/src/rendering/box.dart 2515:14 defaultPaint
packages/flutter/src/rendering/flex.dart 950:7 paint
packages/flutter/src/rendering/object.dart 2264:7 [_paintWithContext]
packages/flutter/src/rendering/object.dart 184:12 paintChild
packages/flutter/src/widgets/overlay.dart 737:14 paintStack
packages/flutter/src/widgets/overlay.dart 747:7 paint
packages/flutter/src/rendering/object.dart 2264:7 [_paintWithContext]
packages/flutter/src/rendering/object.dart 184:12 paintChild
packages/flutter/src/rendering/view.dart 213:14 paint
packages/flutter/src/rendering/object.dart 2264:7 [_paintWithContext]
packages/flutter/src/rendering/object.dart 135:10 _repaintCompositedChild
packages/flutter/src/rendering/object.dart 95:5 repaintCompositedChild
packages/flutter/src/rendering/object.dart 980:29 flushPaint
packages/flutter/src/rendering/binding.dart 404:19 drawFrame
packages/flutter/src/widgets/binding.dart 865:13 drawFrame
packages/flutter/src/rendering/binding.dart 284:5 [_handlePersistentFrameCallback]
packages/flutter/src/scheduler/binding.dart 1074:15 [_invokeFrameCallback]
packages/flutter/src/scheduler/binding.dart 1013:9 handleDrawFrame
packages/flutter/src/scheduler/binding.dart 822:7
════════ Exception caught by rendering library The following UnimplementedError was thrown during paint(): UnimplementedError
The relevant error-causing widget was
DevicePreview
When the exception was thrown, this was the stack
dart-sdk/lib/internal/js_dev_runtime/private/ddc_runtime/errors.dart 216:49 throw
lib/ui/src/ui/path.dart 281:5 combine
packages/device_preview/src/frames/mobile_device_frame.dart 212:14 paint
packages/flutter/src/rendering/custom_paint.dart 531:12 [_paintWithPainter]
packages/flutter/src/rendering/custom_paint.dart 572:7 paint
...
The following RenderObject was being processed when the exception was fired: RenderCustomPaint#b1dd0
RenderObject: RenderCustomPaint#b1dd0
parentData:
════════ Exception caught by rendering library UnimplementedError The relevant error-causing widget was DevicePreview ═══════════
Yes, paths aren't implemented yet with css based engine.
In the meantime, you can build against the skia based engine instead (that's what I did for the demo).
To do this build with the following command :
flutter build web --dart-define=FLUTTER_WEB_USE_SKIA=true
Ouch bummer path issue here too, yes I noticed as well when I just tested this on Web and run into Path() issue in another case as well.
I just tried to build the example app with the master channel (that I have to use to be able to build for Windows), this version to be exact:
Flutter 1.19.0-2.0.pre.145 • channel master • https://github.com/flutter/flutter.git
Framework • revision af9b6a6efa (6 hours ago) • 2020-05-26 09:17:55 -0700
Engine • revision 9ce1e5c5c7
Tools • Dart 2.9.0 (build 2.9.0-10.0.dev 7706afbcf5)
I get a crash on the path there now too, oh wait, this looks like DomCanvas build. If I instead build for SKIA in release mode with:
flutter run --release --dart-define=FLUTTER_WEB_USE_SKIA=true -d Chrome
Is SKIA builds supposed to work without release mode? Earlier I read it only works in --release mode.
Now building it on master in --release mode, now it does not crash, but no deviceFrames either:
Now I am trying beta channel that is more official for Web builds:
Flutter 1.18.0-11.1.pre • channel beta • https://github.com/flutter/flutter.git
Framework • revision 2738a1148b (13 days ago) • 2020-05-13 15:24:36 -0700
Engine • revision ef9215ceb2
Tools • Dart 2.9.0 (build 2.9.0-8.2.beta)
Same result when building for SKIA, it crashes if not building in release mode with the additional flag --release, but that happens because it actually create a DomCanvas build then. With the --release mode flag added it does not crash, but no device frames are drawn either, like in the above image. So same result on master and beta channel.
These builds were done a Windows 10 machine, maybe it works when building on a Mac or Linux?
Also at the moment SKIA builds can really only be used for dev / experimental test builds, because at least on Windows 10 when you build for SKIA the fonts looks really bad. See this issue for more info: https://github.com/flutter/flutter/issues/56319
I can confirm that it builds and doesn't crash but there are not frames with Skia.
Not much to be done about until Flutter Web supports it, imo. Fixing it would require using some other APIs in CustomPaint that are currently supported that could be used to achieve the same end result, so probably quite a bit of work, if doable at all.
Does anybody know or have found if there is a ticket about this unsupported API open on Flutter issues already? If not, I think we should open one.
It is a bit frustrating when there is no documentation whatsoever on what APIs are currently supported or not supported on Flutter WEB and they also differ on DomCanvas and CanvasKit, not only that, in some cases where they both work, the DomCanvas can produce output that deviates significantly from the CanvasKit (and device SKIA) renderings.
But yeah, I guess there is a reason why Flutter Web is still in beta, so there is that too :)
The relevant issue is https://github.com/flutter/flutter/issues/44572
Thanks, I'll will go and up-vote it too, and say some supporting words. 😀
During my last tests it worked only with CanvasKit in release mode (https://flutter-device-preview.firebaseapp.com/#/).
Maybe a regression with latest versions?
I think so too, at least it no longer seems to work even with CanvasKit and no channel that I tried, I tried with beta and master, but not with dev.
If you have not, maybe you could consider dropping some comments/info on the issue too.
I made a workaround to make it work on Flutter web for now. I don't display the notch if is on web (it has a lot of Path.combined) and instead of Path.combined between the body and screen, I use blendMode
Code starting at mobile_frame.dart#L386
if (!kIsWeb) {
if (device.notch != null && device.notch.width > 0) {
final notchPath = _createNotchPath(size);
screen = Path.combine(
PathOperation.difference,
screen,
notchPath,
);
}
}
final bodyWithoutScreen =
kIsWeb ? body : Path.combine(PathOperation.difference, body, screen);
canvas.drawPath(
bodyWithoutScreen,
Paint()
..style = PaintingStyle.fill
..color = style.bodyColor);
if (kIsWeb) {
canvas.drawPath(
screen,
Paint()
..style = PaintingStyle.fill
..blendMode = BlendMode.dstOut);
}
@aloisdeniel I run locally your example app from device_preview package on web and device preview is working correctly only for devices that have notches. For those without notch black screen is displayed. I run an app with command: flutter run --release --dart-define=FLUTTER_WEB_USE_SKIA=true -d Chrome
. The demo you provided is working properly for all devices. Do you know what can be a cause of that?
IPHONE XS
IPHONE 5
@aloisdeniel I run locally your example app from device_preview package on web and device preview is working correctly only for devices that have notches. For those without notch black screen is displayed. I run an app with command:
flutter run --release --dart-define=FLUTTER_WEB_USE_SKIA=true -d Chrome
. The demo you provided is working properly for all devices. Do you know what can be a cause of that? IPHONE XSIPHONE 5
I fix it by add this code at mobile_device_frame.dart (Line 216) by this code.
if (device.notch != null && device.notch.width > 0) { // line 154
// [dart code]
} else { // line 216
screen = Path.combine( PathOperation.difference, screen, Path()..addRect(Offset(0, 0) & Size(0, 0),));
}// line 218