Repository navigation
Path.combine not implemented in the HTML backend #44572
Copy link
Copy link
Closed
Labels
P3Issues that are less important to the Flutter projectIssues that are less important to the Flutter projecta: imagesLoading, displaying, rendering imagesLoading, displaying, rendering imagesc: crashStack traces logged to the consoleStack traces logged to the consolecustomer: crowdAffects or could affect many people, though not necessarily a specific customer.Affects or could affect many people, though not necessarily a specific customer.customer: thrivecustomer: web10e: web_htmlHTML rendering backend for WebHTML rendering backend for Webfound in release: 3.13Found to occur in 3.13Found to occur in 3.13found in release: 3.17Found to occur in 3.17Found to occur in 3.17frameworkflutter/packages/flutter repository. See also f: labels.flutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onThe issue has been confirmed reproducible and is ready to work onplatform-webWeb applications specificallyWeb applications specificallyr: solvedIssue is closed as solvedIssue is closed as solvedteam-webOwned by Web platform teamOwned by Web platform teamteam: skip-testAn issue used to track tests that are skipped.An issue used to track tests that are skipped.triaged-webTriaged by Web platform teamTriaged by Web platform team
Description
this code below works fine on flutter mobile
but on web it throws an error
import 'package:flutter/material.dart';
void main() => runApp(App());
class App extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: SafeArea(
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
UnicornOutlineButton(
strokeWidth: 2,
radius: 24,
gradient: LinearGradient(colors: [Colors.black, Colors.redAccent]),
child: Text('OMG', style: TextStyle(fontSize: 16)),
onPressed: () {},
),
SizedBox(width: 0, height: 24),
UnicornOutlineButton(
strokeWidth: 4,
radius: 16,
gradient: LinearGradient(
colors: [Colors.blue, Colors.yellow],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
),
child: Text('Wow', style: TextStyle(fontSize: 16)),
onPressed: () {},
),
],
),
),
),
),
);
}
}
class UnicornOutlineButton extends StatelessWidget {
final _GradientPainter _painter;
final Widget _child;
final VoidCallback _callback;
final double _radius;
UnicornOutlineButton({
@required double strokeWidth,
@required double radius,
@required Gradient gradient,
@required Widget child,
@required VoidCallback onPressed,
}) : this._painter = _GradientPainter(strokeWidth: strokeWidth, radius: radius, gradient: gradient),
this._child = child,
this._callback = onPressed,
this._radius = radius;
@override
Widget build(BuildContext context) {
return CustomPaint(
painter: _painter,
child: GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: _callback,
child: InkWell(
borderRadius: BorderRadius.circular(_radius),
onTap: _callback,
child: Container(
constraints: BoxConstraints(minWidth: 88, minHeight: 48),
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
_child,
],
),
),
),
),
);
}
}
class _GradientPainter extends CustomPainter {
final Paint _paint = Paint();
final double radius;
final double strokeWidth;
final Gradient gradient;
_GradientPainter({@required double strokeWidth, @required double radius, @required Gradient gradient})
: this.strokeWidth = strokeWidth,
this.radius = radius,
this.gradient = gradient;
@override
void paint(Canvas canvas, Size size) {
// create outer rectangle equals size
Rect outerRect = Offset.zero & size;
var outerRRect = RRect.fromRectAndRadius(outerRect, Radius.circular(radius));
// create inner rectangle smaller by strokeWidth
Rect innerRect = Rect.fromLTWH(strokeWidth, strokeWidth, size.width - strokeWidth * 2, size.height - strokeWidth * 2);
var innerRRect = RRect.fromRectAndRadius(innerRect, Radius.circular(radius - strokeWidth));
// apply gradient shader
_paint.shader = gradient.createShader(outerRect);
// create difference between outer and inner paths and draw it
Path path1 = Path()..addRRect(outerRRect);
Path path2 = Path()..addRRect(innerRRect);
var path = Path.combine(PathOperation.difference, path1, path2);
canvas.drawPath(path, _paint);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) => oldDelegate != this;
}
here is full log
Performing hot restart...
Reloaded application in 423ms.
══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
The following UnimplementedError was thrown during paint():
UnimplementedError
The relevant error-causing widget was:
CustomPaint org-dartlang-app:///packages/mywebapp/main.dart:64:12
When the exception was thrown, this was the stack:
package:dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 194:49 throw_
package:build_web_compilers/lib/ui/src/ui/canvas.dart 2200:5 combine
package:mywebapp/main.dart 115:21 paint
package:flutter/src/rendering/custom_paint.dart 531:12 [_paintWithPainter]
package:flutter/src/rendering/custom_paint.dart 572:7 paint
package:flutter/src/rendering/object.dart 2211:7 [_paintWithContext]
package:flutter/src/rendering/object.dart 184:12 paintChild
package:flutter/src/rendering/box.dart 2508:14 defaultPaint
package:flutter/src/rendering/flex.dart 948:7 paint
package:flutter/src/rendering/object.dart 2211:7 [_paintWithContext]
package:flutter/src/rendering/object.dart 184:12 paintChild
package:flutter/src/rendering/shifted_box.dart 70:14 paint
package:flutter/src/rendering/object.dart 2211:7 [_paintWithContext]
package:flutter/src/rendering/object.dart 184:12 paintChild
package:flutter/src/rendering/shifted_box.dart 70:14 paint
package:flutter/src/rendering/object.dart 2211:7 [_paintWithContext]
package:flutter/src/rendering/object.dart 184:12 paintChild
package:flutter/src/rendering/box.dart 2508:14 defaultPaint
package:flutter/src/rendering/custom_layout.dart 396:5 paint
package:flutter/src/rendering/object.dart 2211:7 [_paintWithContext]
package:flutter/src/rendering/object.dart 184:12 paintChild
package:flutter/src/rendering/proxy_box.dart 123:14 paint
package:flutter/src/material/material.dart 530:11 paint
package:flutter/src/rendering/object.dart 2211:7 [_paintWithContext]
package:flutter/src/rendering/object.dart 184:12 paintChild
package:flutter/src/rendering/proxy_box.dart 123:14 paint
package:flutter/src/rendering/object.dart 384:12 pushLayer
package:flutter/src/rendering/proxy_box.dart 1757:14 paint
package:flutter/src/rendering/object.dart 2211:7 [_paintWithContext]
package:flutter/src/rendering/object.dart 184:12 paintChild
package:flutter/src/rendering/proxy_box.dart 123:14 paint
package:flutter/src/rendering/object.dart 2211:7 [_paintWithContext]
package:flutter/src/rendering/object.dart 184:12 paintChild
package:flutter/src/rendering/proxy_box.dart 123:14 paint
package:flutter/src/rendering/object.dart 2211:7 [_paintWithContext]
package:flutter/src/rendering/object.dart 135:10 _repaintCompositedChild
package:flutter/src/rendering/object.dart 95:5 repaintCompositedChild
package:flutter/src/rendering/object.dart 201:7 [_compositeChild]
package:flutter/src/rendering/object.dart 182:7 paintChild
package:flutter/src/rendering/proxy_box.dart 123:14 paint
package:flutter/src/rendering/object.dart 2211:7 [_paintWithContext]
package:flutter/src/rendering/object.dart 184:12 paintChild
package:flutter/src/rendering/proxy_box.dart 921:16 paint
package:flutter/src/rendering/object.dart 2211:7 [_paintWithContext]
package:flutter/src/rendering/object.dart 184:12 paintChild
package:flutter/src/rendering/proxy_box.dart 123:14 paint
package:flutter/src/rendering/proxy_box.dart 2464:13 paint
package:flutter/src/rendering/object.dart 2211:7 [_paintWithContext]
package:flutter/src/rendering/object.dart 184:12 paintChild
package:flutter/src/rendering/proxy_box.dart 123:14 paint
package:flutter/src/rendering/object.dart 2211:7 [_paintWithContext]
package:flutter/src/rendering/object.dart 135:10 _repaintCompositedChild
package:flutter/src/rendering/object.dart 95:5 repaintCompositedChild
package:flutter/src/rendering/object.dart 201:7 [_compositeChild]
package:flutter/src/rendering/object.dart 182:7 paintChild
package:flutter/src/rendering/proxy_box.dart 123:14 paint
package:flutter/src/rendering/object.dart 2211:7 [_paintWithContext]
package:flutter/src/rendering/object.dart 184:12 paintChild
package:flutter/src/rendering/proxy_box.dart 123:14 paint
package:flutter/src/rendering/proxy_box.dart 3174:11 paint
package:flutter/src/rendering/object.dart 2211:7 [_paintWithContext]
package:flutter/src/rendering/object.dart 184:12 paintChild
package:flutter/src/rendering/box.dart 2508:14 defaultPaint
package:flutter/src/rendering/stack.dart 589:5 paintStack
package:flutter/src/rendering/stack.dart 597:7 paint
package:flutter/src/rendering/object.dart 2211:7 [_paintWithContext]
package:flutter/src/rendering/object.dart 184:12 paintChild
package:flutter/src/rendering/proxy_box.dart 123:14 paint
package:flutter/src/rendering/object.dart 2211:7 [_paintWithContext]
package:flutter/src/rendering/object.dart 184:12 paintChild
package:flutter/src/rendering/proxy_box.dart 123:14 paint
package:flutter/src/rendering/object.dart 2211:7 [_paintWithContext]
package:flutter/src/rendering/object.dart 184:12 paintChild
package:flutter/src/rendering/proxy_box.dart 123:14 paint
package:flutter/src/rendering/object.dart 2211:7 [_paintWithContext]
package:flutter/src/rendering/object.dart 184:12 paintChild
package:flutter/src/rendering/proxy_box.dart 123:14 paint
package:flutter/src/rendering/object.dart 2211:7 [_paintWithContext]
package:flutter/src/rendering/object.dart 184:12 paintChild
package:flutter/src/rendering/proxy_box.dart 123:14 paint
package:flutter/src/rendering/object.dart 2211:7 [_paintWithContext]
package:flutter/src/rendering/object.dart 184:12 paintChild
package:flutter/src/rendering/proxy_box.dart 123:14 paint
package:flutter/src/rendering/object.dart 2211:7 [_paintWithContext]
package:flutter/src/rendering/object.dart 184:12 paintChild
package:flutter/src/rendering/view.dart 210:14 paint
package:flutter/src/rendering/object.dart 2211:7 [_paintWithContext]
package:flutter/src/rendering/object.dart 135:10 _repaintCompositedChild
package:flutter/src/rendering/object.dart 95:5 repaintCompositedChild
package:flutter/src/rendering/object.dart 937:29 flushPaint
package:flutter/src/rendering/binding.dart 346:19 drawFrame
package:flutter/src/widgets/binding.dart 774:13 drawFrame
package:flutter/src/rendering/binding.dart 283:5 [_handlePersistentFrameCallback]
package:flutter/src/scheduler/binding.dart 1101:15 [_invokeFrameCallback]
package:flutter/src/scheduler/binding.dart 1040:9 handleDrawFrame
package:flutter/src/scheduler/binding.dart 849:7 <fn>
package:dart-sdk/lib/_internal/js_dev_runtime/private/isolate_helper.dart 48:19 internalCallback
The following RenderObject was being processed when the exception was fired: RenderCustomPaint#dc268 relayoutBoundary=up4:
creator: CustomPaint ← UnicornOutlineButton ← Column ← Center ← MediaQuery ← Padding ← SafeArea ←
_BodyBuilder ← MediaQuery ← LayoutId-[<_ScaffoldSlot.body>] ← CustomMultiChildLayout ←
AnimatedBuilder ← ⋯
parentData: offset=Offset(0.0, 0.0); flex=null; fit=null (can use size)
constraints: BoxConstraints(0.0<=w<=1920.0, 0.0<=h<=Infinity)
size: Size(88.0, 48.0)
This RenderObject had the following descendants (showing up to depth 5):
child: RenderSemanticsGestureHandler#078b7 relayoutBoundary=up5 NEEDS-PAINT
child: RenderPointerListener#fd406 relayoutBoundary=up6 NEEDS-PAINT
child: RenderSemanticsAnnotations#9008b relayoutBoundary=up7 NEEDS-PAINT
child: RenderMouseRegion#dec56 relayoutBoundary=up8 NEEDS-PAINT
child: RenderSemanticsGestureHandler#cea3a relayoutBoundary=up9 NEEDS-PAINT
════════════════════════════════════════════════════════════════════════════════════════════════════
Another exception was thrown: UnimplementedError
if I commented this line, everything if ok and working fine, but I need subtract one path from another. Actually all path operations are throwing errors on flutter web.
var path = Path.combine(PathOperation.difference, path1, path2);
Tried on MAC Catalina and Windows 10.
flutter doctor -v
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
[✓] Android Studio (version 3.5)
• Android Studio at /Applications/Android Studio.app/Contents
• Flutter plugin version 40.2.2
• Dart plugin version 191.8593
• Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405)
[✓] Connected device (2 available)
• Chrome • chrome • web-javascript • Google Chrome 78.0.3904.97
• Web Server • web-server • web-javascript • Flutter Tools
• No issues found!
my original post on SO https://stackoverflow.com/questions/55395641/outlined-transparent-button-with-gradient-border-in-flutter/55638138
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
P3Issues that are less important to the Flutter projectIssues that are less important to the Flutter projecta: imagesLoading, displaying, rendering imagesLoading, displaying, rendering imagesc: crashStack traces logged to the consoleStack traces logged to the consolecustomer: crowdAffects or could affect many people, though not necessarily a specific customer.Affects or could affect many people, though not necessarily a specific customer.customer: thrivecustomer: web10e: web_htmlHTML rendering backend for WebHTML rendering backend for Webfound in release: 3.13Found to occur in 3.13Found to occur in 3.13found in release: 3.17Found to occur in 3.17Found to occur in 3.17frameworkflutter/packages/flutter repository. See also f: labels.flutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onThe issue has been confirmed reproducible and is ready to work onplatform-webWeb applications specificallyWeb applications specificallyr: solvedIssue is closed as solvedIssue is closed as solvedteam-webOwned by Web platform teamOwned by Web platform teamteam: skip-testAn issue used to track tests that are skipped.An issue used to track tests that are skipped.triaged-webTriaged by Web platform teamTriaged by Web platform team
Activity
iapicca commentedon Nov 11, 2019
Hi @eugene-kalaganov
could you please provide your complete
flutter doctor -vthank you
eugene-kalaganov commentedon Nov 11, 2019
I added it, please see at the end of my post
[-]Path.combine throws UNIMPLEMENTED ERROR[/-][+]Path.combine not implemented[/+][-]Path.combine not implemented[/-][+][web] Path.combine not implemented[/+]diegoveloper commentedon Jan 10, 2020
same issue here
diegoveloper commentedon Jan 13, 2020
This is a sample where you can find and replicate the issue : https://dartpad.dev/82a2a6fc764abb55503b164d181c4616
61 remaining items
reiko-dev commentedon Feb 7, 2024
@ferhatb
JaffaKetchup commentedon Jun 1, 2024
I feel like this could be a higher priority than P3. It's got 3 customers + crowd already, and has been open since 2019.
rydmike commentedon Jun 1, 2024
@JaffaKetchup I read somewhere that the html renderer is on a "potential" deprecation path. If so, maybe that is why it has not been addressed and probably wont be.
naychrist commentedon Sep 25, 2024
this issue is still present, with and without the wasm flag. As wasm is new I imagine this is not to be deprecated so would be great to see fixed.
JaffaKetchup commentedon Sep 25, 2024
The HTML renderer is indeed being deprecated, and I'm not sure this is possible to occur when running with Wasm. AFAIK Wasm uses skwasm and non-Wasm uses CanvasKit, both of which use WebGL, which implements the encessary methods (Wasm forces skwasm, it cannot use HTML rendering). Are you sure that this occurs in the latest Flutter versions when using CanvasKit or skwasm?
naychrist commentedon Sep 26, 2024
I can confirm that a simple path combine operation (cutting poly out of a rect) that works in macos desktop with flutter 3.24.3 does not work with the default web renderer, canvaskit renderer or wasm. On web the hole is not cut out and the rect is displayed solid.
I have had to use a workaround with the
polyboolpackage for web for now but keen to see this resolved.JaffaKetchup commentedon Sep 26, 2024
That sounds like a potentially different issue? This issue should throw
UnimplementedErroras in the original report, and is specifically about it not being implemented in the HTML renderer, not an issue with its implementation in any of the WebGL renderers.naychrist commentedon Sep 26, 2024
yeah true that no exception is thrown. just fails silently using the same method with all the web renderers.
JaffaKetchup commentedon Apr 3, 2025
This can probably be closed since HTML support is pretty much gone.
Path.combinehas other issues on the web as well.yjbanov commentedon May 27, 2025
As the HTML renderer has been deprecated and removed from the default Flutter SDK, we're now closing all issues that affect only the HTML renderer. For more information, please see:
github-actions commentedon Jun 11, 2025
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of
flutter doctor -vand a minimal reproduction of the issue.