Flutter - blurRadius strange behaviour - flutter

So I have a rotating container
Here is the working code:
#override
void initState() {
_controller = AnimationController(
vsync: this,
duration: Duration(seconds: 32),
)..repeat();
super.initState();
}
....
#override
Widget build(BuildContext context) {
double screenHeight = MediaQuery.of(context).size.height;
double screenWidth = MediaQuery.of(context).size.width;
return Container(
child: Column(
children: <Widget>[
SizedBox(
height: screenHeight,
child: Stack(
children: [
Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
],
),
Divider(),
Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Center(
child: AnimatedBuilder(
animation: _controller,
builder: (_, child) {
return Transform(
alignment: FractionalOffset.center,
transform: Matrix4.identity()
..setEntry(3, 2, 0.002)
..rotateY(0.5 * -math.pi)
..rotateZ(-0.1 * math.pi)
..rotateY((_controller.value - 0.6) * -math.pi)
..rotateX(0.5 * math.pi),
child: child,
);
},
child: Container(
//color: Colors.yellow.withOpacity(0.5),
height: 300,
width: 200,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(40),
boxShadow: [
BoxShadow(
color: Colors.yellow.withOpacity(0.5),
spreadRadius: 40,
//UNCOMMENTING THIS LINE CAUSES STRANGE BEHAVIOUR
//blurRadius: 50,
//offset: const Offset(0, 0),
),
],
),
),
//),
),
),
SizedBox(
height: 170,
)
],
),
],
),
),
],
),
);
}
However, when I uncomment the blurRadius line of code, it behaves strangely. Look how the container kind of gets distorted when it comes perpendicular to the screen.
I want it to be consistently blurred. This is something strange.

Shadows are very expensive for Flutter to draw, so it's bad to animate them like this because Flutter has to keep repainting the shadow. Since the shadow is also causing your transform problem, you should try to make the shadow you want in GIMP/Adobe or screenshot it in flutter, then add it to your project.
You should have an assets or images folder in your project directory, i.e, YOUR_FLUTTER_PROJECT/images. Put the shadow image in there.
Then, in the pubspec.yaml file, there should be a field for your assets. Add the path to the shadow file there, e.g.:
assets:
- images/a_dot_burr.jpeg
- images/a_dot_ham.jpeg
- images/YOUR_SHADOW_FILE
Run flutter pub get
In your code, replace your Container with this:
Image.asset('images/YOUR_SHADOW_FILE', height: 300, width: 200),
I haven't tested it, but I reckon it should still work.

I don't know the reasons behind it but removing the line ..setEntry(3, 2, 0.002) will remove the issues. However, there is a slight dimension issue during the animation which I thinks because of relativity. With the above line, it seems like animation decrease the blur effect with the increase of animation completion factor and reset to provided value when it reaches the starting point of animation.

Related

How to implement the animation of the circle expanding in flutter

![enter image description here][1]
This is my first post.
I would like to implement an animation of a circle spreading out like in the image link, how should I implement it?
First of all, we wanted to make the entire screen blue, so we changed the code as follows
LayoutBuilder(
builder: (context, constrains) {
return Stack(
children: [
Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
]
),
Positioned(
right: -constrains.maxWidth * 0.1,
bottom: constrains.maxHeight * 0.2,
child: ClipOval(
child: AnimatedContainer(
duration: const Duration(milliseconds: 1000),
color: isSwipeEnd
? theme.appColors.primary
: Colors.transparent,
width: isSwipeEnd ? constrains.maxWidth * 2 : 200,
height: isSwipeEnd ? constrains.maxHeight * 1.5 : 200,
),
),
)
],
);
},
),
However, this doesn't cover the entire screen in blue. Also, why does the center of the circle move from the bottom right to the top left? Why is this? Also, how do I stop the center of the circle from moving?

Flutter many aligned buttons in a stack don't work

Hi I'm currently stacking buttons in flutter using
Transform.scale(
scale: 0.5,
child: Stack(
children: List.generate(data.length, (int index) {
Alignment alignment = alignments[index];
String message = messages[index];
return Align(
alignment: Alignment(
alignment.x,
alignment.y
),
child: SizedBox(
key: UniqueKey(),
width: 100.0,
height: 100.0,
child: MaterialButton(
key: UniqueKey(),
onPressed: () {
print("Specific message: "+message.toString());
},
child: Container(
width: 100.0,
height: 100.0,
color: Colors.pink,
child: Text("message: "+message.toString()),
),
),
),
);
}),
),
)
However this only works for the first few handful of widgets, the later widgets no longer print the message or register the click.
====
Side note I have just tested where alignment is Alignment(0.0, 0.0) and the top button works. However, when it has alignment away from the centre it doesn't work.
====
I have a suspicion if a button is built initially off screen you won't be able to press it even if you scale the whole screen.
To fix the problem all the buttons need to be on the screen at scale: 1.0

Flutter "Catch up" animation on drag

I'm currently building a flutter app where a user can drag a circle around the screen. I use a Listener widget to get the current pointer position, then use a transform widget to position it accordingly.
class _DraggingExample extends State<VelocityAnimations>{
var offset = Offset(0, 0);
#override
Widget build(BuildContext context) {
return Scaffold(
// I get pointer-events here.
body: Listener(
onPointerMove: (e) {
setState(() {
// - 50 to center the container
offset = e.localPosition - Offset(50, 50);
});
},
behavior: HitTestBehavior.opaque,
child: SizedBox.expand(
child: Stack(
children: [
Center(child: Text('Hello, World!')),
// I transform the container here.
Transform.translate(
offset: offset,
child: Container(
width: 100,
height: 100,
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.circular(50),
),
),
)
],
),
),
),
);
}
}
It works perfectly. But it's very bland. It would be much nicer if when I move my pointer/finger, the container gradually catches up to the finger. The effect I'm looking for can be seen in this codepen. Here, the black circle gradually catches up with the mouse as you move it along.
I've tried using a Physics Simulation and plain animations, but I can't figure out how to do it.
You can try to use AnimatedPositioned which animates its position implicitly.
The animation can be configured with duration and Curves as you want.
AnimatedPositioned(
left: offset.dx,
top: offset.dy,
curve: Curves.easeOutCirc,
duration: Duration(milliseconds: 400),
child: Container(
// ...
),
),

Weird animation behaviour of AnimatedContainer when wrapped in IntrinsicHeight

I have created a container in which two AnimatedContainers are located. When i press the down button i would like the TextFieldContainer (The content with the white TextField in the middle) to disappear by decreasing it size to 0. Simountanesly i want to make the ToolbarContainer appear by increasing its size. So far this is what i get:
It looks like only one of the AnimatedContainers can animate its properties one at a time, which creates the werid behaviour as shown, where one of the AnimatedContainers animate quickly, then slowly and then quickly once again.
How do i make the animation smooth so the overall size of the main container does not change because the two AnimatedContainers animate their size equally quick and simountanesly?
Here is the code for the main container:
class _MessageToolbarContainerState extends State<MessageToolbarContainer> {
bool toggleToolbar = false;
#override
Widget build(BuildContext context) {
return Container(
width: widget.availableWidth - 75,
margin: EdgeInsets.only(bottom: 25.0),
constraints: BoxConstraints(minHeight: 50.0),
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.all(Radius.circular(25.0)),
border: Border.all(
color: Colors.grey,
width: 2.0,
),
),
child: Material(
borderRadius: BorderRadius.all(Radius.circular(25.0)),
elevation: 5.0,
clipBehavior: Clip.antiAlias,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
AnimatedContainer(
duration: Duration(seconds: 1),
constraints: BoxConstraints(
minHeight: toggleToolbar ? 0.0 : 50.0,
maxHeight: toggleToolbar ? 0.0 : 100.0,
),
child: IntrinsicHeight(
child: TextFieldContent(
onDownPressed: () {
setState(() {
toggleToolbar = !toggleToolbar;
print(toggleToolbar);
});
},
),
),
),
AnimatedContainer(
duration: Duration(seconds: 1),
constraints: BoxConstraints(
minHeight: !toggleToolbar ? 0.0 : 50.0,
maxHeight: !toggleToolbar ? 0.0 : 100.0,
),
child: IntrinsicHeight(
child: ToolbarContent(
onUpPressed: () {
setState(() {
toggleToolbar = !toggleToolbar;
print(toggleToolbar);
});
},
),
),
),
],
),
),
);
}
}
EDIT:
I have boiled the problem down to one widget. I have wraped my AnimatedContainers in two IntrinsicHeight widgets to keep their content from expanding to much. If i remove the IntrinsicHeight widgets i get the following output:
As it is clearly shown the AnimatedContainers now animate smoothly. Sadly that does not fix my problem. I added the IntrinsicHeight widgets to make the content expand as the user typed in the TextField. If i remove the IntrinsicHeight widgets the content of the AnimatedContainers are not displayed properly.
The original question still stands. How do I make the 2 AnimatedContainers animate properly when they are wrapped in an IntrinsicHeight widget?

OnPressed not working inside Stack widget after Transforming a widget

In the given code,onPressed on the raised button works and translate FlatButton to the top. But onPressed on FlatButton is not working
#override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
Transform(
transform: Matrix4.translationValues(
0.0,
_translateButton.value,
0.0,
),
child: FlatButton(
onPressed: () {
print('tapped Flat button');
},
child: Text('upper'),
),
),
RaisedButton(
onPressed: () {
animate();
print('tapped Raised button');
},
child: Text('lower'))
],
);
}
Here _translatebutton value changes from 0 to -60 when animate() is called
_animationController = AnimationController(vsync: this, duration: Duration(milliseconds: 500))
..addListener(() {
setState(() {});
});
_translateButton = Tween<double>(
begin: 0,
end: -60,
).animate(CurvedAnimation(
parent: _animationController,
curve: Interval(
0.0,
0.75,
curve: _curve,
),
));
Wrap the Transform widget in a SizedBox (expanded or from size, depending on your requirement.
I came across this problem last week and in my case, the composition was like this:
Stack(
children: [
Widget0,
Widget1,
Opacity(
opacity: sth,
child: Transform.translate(
offset: Offset(sth),
child: Transform.rotate(
angle:sth,
child: FlatButton(
onPressed: (){sth},
child: Text("sth"),
),
),
),
),
],
)
Based on the suggestion of rahulthakur319 on the issue number
27587
I wrapped my Transform.translate composition inside a new Stack and I wrapped the stack inside a Container. Remember that the new Container should have enough width and height to show its child. I personally used MediaQuery.of(context).size.
it's working even during the complex series of animations.
The final code:
Stack(
children: [
Widget0,
Widget1,
Opacity(
opacity: sth,
child: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: Stack(
children: [
Transform.translate(
offset: Offset(sth),
child: Transform.rotate(
angle: sth,
child: FlatButton(
onPressed: (){sth},
child: Text("sth"),
),
),
),
],
),
),
),
],
)
If your translation moves the button outside the area of the stack, the button no longer reacts to clicks. A simple way to test this is to wrap your Stack widget in a container and color it blue (or anything obvious), and if your button is moved outside the blue area, you know it's losing its clickability because it's outside of the Stack.
If this indeed is the issue, the solution is to keep the Stack inside the container, and then either set the container dimensions such that the button still stays within the border after translation, or reposition widgets relative to the container such that the translation stays within the border.
If someone is still trying to solve this issue, I solved it by wrapping the widget with IgnorePointer widget on which I don't want the pointer to reach.
reference from here
The answer I got was that in a View if an element is translated then the animation works correct but the click property is altered in someway that we can't use it after translating the element
I had this same issue my Switch widget was not working in the Stack.
The solution i found was to include it in SizeBox or Container with fixed width and height.
if your switch widget is in Row try to add Constraints on Row with SizeBox rather than adding it in every widget.