Using ContinuousRectangleBorder (AKA Squircle, Superellipse) as a mask in Flutter - flutter

Can a ContinuousRectangleBorder (AKA Squircle, Superellipse) shape be used as a template for masking another widget?
Context
I'm trying to mask a widget using ClipRRect but the customization options it offers only include traditional border radius which doesn't quite generate the same shape as a container decorated with ContinuousRectangleBorder
Example:
In this approach, the ClipRRect destroys completely the original shape of the ContinuousRectangleBorder if its radius is too big, if it is too small it won't clip both the filter and the container appropiately. I tried with elliptical radiuses but still it does not look as expected
ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(40)),
child: BackdropFilter(
// Filter
filter: ImageFilter.blur(
sigmaX: 20,
sigmaY: 20,
),
// Container with ContinuousRectangleBorder
child: Container(
constraints: BoxConstraints(maxWidth: 600),
decoration: ShapeDecoration(
color: Colors.blue,
shape: ContinuousRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(80)),
),
),
child: Padding(
padding: const EdgeInsets.all(30.0),
child: Text("Hola World"),
),
),
),
);
What I've Tried
I tried using an Stack with two layers:
Stack
|- Layer 1: BackdropFilter inside a traditional ClipRRect hoping to simulate the shape of the ContinuousRectangleBorder behind the real ContinuousRectangleBorder without affecting the real geometry of it.
|- Layer 2: ContinuousRectangleBorder decoration to the final Container.
The problem with this approach is that I could not find a way for the widget within the Layer 1 to occupy the entire width and height of its brother in Layer 2
Hypothesis
Stack: I think this is the closest I've been to solve this case, but it is not the best solution since it simulates the result. (And I'm still stuck where I can't make the Layer 1 container to fill all the space available in the stack.
I read about about the ClipPath widget but it takes a Path as an argument and I have not been able to convert the ShapeDecoration to that type and use it as a mask.
It may be another way to create the ContinuousRectangleBorder look in order to use it as a mask and a container? I found it is also called squircle / superellipse but the packages and solutions to recreate it use a ShapeDecoration just as ContinuousRectangleBorder does.
Maybe an alternative way to make a mask that takes the ContinuousRectangleBorder as an argument and wraps its child?
Open discussion
I'm aware the last 2 hypothesis are a bit far from the original question but I'm open to make things in other ways.
Thank you all for your help.

Thanks to #pskink advice, the correct way to achieve this is by using a ClipPath and passing the ContinuousRectangleBorder as a shape of a ShapeBorderClipper
Example:
ClipPath(
clipper: ShapeBorderClipper(
shape: ContinuousRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(80),
),
),
),
child: Text("Hola World"),
);

Related

Flutter signature 5.0.1 signature can extand outside the bounds of the widget

I am using this
Signature 5.0.1 package for flutter
https://pub.dev/packages/signature
To handle the signatures and I am trying to keep them inside a certain container, the signature itself has a defined width and height property but it doesn't contain the signature itself when you start drawing it, once the draw has started you can simply expand it down and left as much as you want, thank you for all of your answers.
presentation of the problem
code for the signature
extended presentation of the problem
Wrap your Signature widget with ClipRRect.
ClipRRect(
child: Signature(
height: 200, // Or any other height you would like your widget to be
controller: _signatureController,
backgroundColor: pogoGreyBgColor,
),
);
That will keep all of the drawings within this widget's bounds.
Use SizedBox() as parent of Signature(), and ClipRRect() as parent of SizedBox(),
This solves my problem.
ClipRRect(
child: SizedBox(
height: 280,
child: Signature(
controller: _controller,
height: 280,
backgroundColor: getNormalTextColor,
),
),
),

Connect a row of circles to a chain in Flutter

I have a rather easy problem, but which I cannot seem to solve efficiently.
So I have a row of a changing number of Containers with a centered Circle, for which I used a circle icon from the Font Awesome package. And what I want to do is to connect the sides of these circles so that they form a chain.
I though of creating a custom icon, a circle with a line to the side long enough to reach the next circle.
Another option would be to use Stack and manually place a line between the cirlces, but because the number of cicles is changing, I fear the that the line will overflow the circle boundries.
Any of ou have an idea how to solve this efficiently?
Edit:
So here is a picture of what I want it to be like:
Picture of the Chain
My Code right now is just
Row(
children: <Widget>[
Container(
child: Center( child: CircleIcon ),
),
Container(
child: Center( child: CircleIcon ),
), ...
You can just use Container for this. Really simple with Container.
Container{
height: 50, // give any height you need
width: 50, // give the same as height,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
color: Colors.black
),
),
}

Flutter: ClipRRect vs Container with BoxDecoration

I know that ClipRRect has additional options like custom clipper. But if I need just a simple border radius is there any performance difference? Which one is more recommended?
If your goal is to create a rounded border, you must use clippers only in the last situation, when containers may not help. For example, images can draw over rounded borders, so you have no other option unless clipping the image.
how about shape, shape vs cliprrect
RaisedButton(
onPressed: () {},
child: Text('Test'),
shape: RoundedRectangleBorder(
side: BorderSide.none,
borderRadius: BorderRadius.all(Radius.circular(50))
),
)

Flutter blur image edges are unaffected (iOS only)

When applying ImageFilter.blur to an image, the edges of the image are unchanged.
How can I extend the blur to the edges?
import 'dart:ui';
import 'package:flutter/material.dart';
class ExamplePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage("https://i.pinimg.com/236x/93/ca/59/93ca599d74b60b4e9b30cd9472f842b7--patterns-in-nature-beautiful-patterns.jpg"),
fit: BoxFit.cover,
),
),
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 20, sigmaY: 20),
child: Container(
decoration: BoxDecoration(color: Colors.white.withOpacity(0.0)),
),
),
);
}
}
This may not be what you want to hear, or it might be =D. The issue you're seeing is that Skia's software renderer has a problem with blurs. You won't see the same issue on the Android simulator unless you specifically turn on software rendering, nor on actual devices as they use hardware rendering.
This is on my iPhone:
If you really need blur to work properly in the simulator I'd recommend either adding a +1 to this issue or making a new issue in the flutter repo with the image above (as in the issue I linked to it seemed they were seeing inconsistency rather than exactly what you've observed, although I'd imagine the fix would fix what you're seeing as well).
A solution that wouldn't require that bug to be fixed for the simulator is possible I think.... You could theoretically use an overflow to make the blur go outside of the edge of the screen by at least the size of the blur, have the image then offset by the same amount as the overflow, and flip copies of the same image outside of the screen bounds so that the colouring on the blur is right.... but that seems a bit overkill =D.
The fix will be available soon in the stable version of Flutter SDK, until that if you need it, switch to the master channel by running this in terminal and rebuild your app:
flutter channel master
source: Backdrop filter is inconsistent on software rendering
If you replace you above mentioned code with
return Container(
decoration: BoxDecoration(
image: DecorationImage(
image: CachedNetworkImageProvider("https://i.pinimg.com/236x/93/ca/59/93ca599d74b60b4e9b30cd9472f842b7--patterns-in-nature-beautiful-patterns.jpg"),
fit: BoxFit.cover,
),
),
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5),
child: Container(
decoration: BoxDecoration(color: Colors.white.withOpacity(0.0)),
),
),
);
Then it look like this and edges issue resolved

SVG losing its curvature when in a Container

I have an svg as a child in a container. I'm using this package . The svg is curved at one side but it loses this curvature when rendered.
Padding(
padding: const EdgeInsets.only(left: 30,right: 30,bottom: 10),
child: ClipRRect(
child: Container(
alignment: Alignment.centerRight,
child: SvgPicture.asset('assets/img/mask_purple_energizer.svg',height: 200,width: 1000,),
color: Theme.of(context).cardColor),
borderRadius: BorderRadius.circular(15),
),
),
Here is the gist of the svg file:
https://gist.github.com/horgag1/66ef8ab683f26b9c19a318769a2cf3e9
I don't think clip rects are supported by the SVG plugin you're using, or at least not how they are in your SVG. The right-side corners aren't being cropped properly either, but you can't tell that because the ClipRRect takes care of it.
If the SVG editor you're using supports it, you may be able to apply the clip to each shape instead of having it separate. Otherwise, your options are to either raise a bug or add clipping to the plugin, or to use a ClipPath widget and manually define the clipping path (or copy it out of the svg).