Allow overflow container more than screen - flutter

I have AnimatedContainer inside a Stack widget. I want to change the scale of the MyAnimatedContainer and make it bigger than screen, like image below :
How can I do that ?
Code:
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
fit: StackFit.expand,
children: [
AnimatedContainer(
height: _width,
width: _height,
duration: const Duration(milliseconds: 500),
child: Image.asset('assets/Asset 2.png'),
),
],
),
);
}
I try to change width/height but it doesn't work.

The constraints passed into theStack from its parent are tightened using stackfit.expand,
So I want you to use stackfit.loose and than change the width and height .
Just try if it works for you.
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
fit: StackFit.loose,
children: [
AnimatedContainer(
height: _width,
width: _height,
duration: const Duration(milliseconds: 500),
child: Image.asset('assets/Asset 2.png'),
),
],
),
);
}

#manishyadav solution didn't work for me. My animation was always constrained by the device size. Nonetheless, I achieved what #mohammadsadra-kafiri depicted in the question:
Allow overflow container more than screen
I used CustomPainter with AnimationController. Container is actually RippleBackground and here's full example:
import 'package:flutter/material.dart';
class RippleBackground extends StatefulWidget {
const RippleBackground({required this.rippleColor, super.key});
final Color rippleColor;
#override
RippleBackgroundState createState() => RippleBackgroundState();
}
class RippleBackgroundState extends State<RippleBackground> with SingleTickerProviderStateMixin {
late AnimationController _controller;
#override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(milliseconds: 400),
vsync: this,
)..forward();
}
#override
void dispose() {
_controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return CustomPaint(
size: const Size(double.infinity, double.infinity),
painter: _RipplePainter(
animation: _controller,
rippleColor: widget.rippleColor,
),
);
}
}
class _RipplePainter extends CustomPainter {
final Animation<double> animation;
_RipplePainter({required this.animation, required this.rippleColor})
: _path = Path(),
_paint = Paint(),
super(repaint: animation);
final Color rippleColor;
final Path _path;
final Paint _paint;
#override
void paint(Canvas canvas, Size size) {
_paint
..color = rippleColor
..style = PaintingStyle.fill;
var centralPoint = Offset(size.width / 2, size.height / 2);
var radiusOfCircumscribedCircle = centralPoint.distance;
var value = animation.value;
if (value >= 0.0 && value <= 1.0) {
canvas.drawPath(
_path
..addOval(
Rect.fromCircle(
center: centralPoint,
radius: radiusOfCircumscribedCircle * value,
),
),
_paint,
);
}
}
#override
bool shouldRepaint(_RipplePainter oldDelegate) => false;
}

Related

How to set wave effect for a button when taps on it in Flutter

Hi, I was trying to build this ui, but i couldnt implement the wave effect as shown in the image.
i got some code for the wave effect but it does not fit well. I made the ui code very complex. so i made a similar ui for sharing .
///////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
class Test extends StatefulWidget {
const Test({Key key}) : super(key: key);
#override
_TestState createState() => _TestState();
}
class _TestState extends State<Test> {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: AppColors.mainBg3,
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
buttonView(0),
buttonView(1),
buttonView(2),
buttonView(4),
],
),
),
);
}
var selectedIndex = 0;
Widget buttonView(int i) {
return Container(
margin: EdgeInsets.only(bottom: 30),
child: InkWell(
onTap: () {
selectedIndex = i;
setState(() {
});
},
child: selectedIndex == i ? WaveAnimation(child: button()) : button(),
),
);
}
Widget button() {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CircleAvatar(
radius: 12,
backgroundColor: Colors.white,
child: Container(
height: 13,
width: 13,
decoration: BoxDecoration(
shape: BoxShape.circle,
gradient: LinearGradient(
colors: [Color(0xffD053A3), Color(0xff842990)])),
),
),
],
);
}
}
And heres the code of wave animation
class WaveAnimation extends StatefulWidget {
const WaveAnimation({
this.size = 80.0,
#required this.child,
});
final double size;
final Widget child;
#override
_WaveAnimationState createState() => _WaveAnimationState();
}
class _WaveAnimationState extends State<WaveAnimation>
with TickerProviderStateMixin {
AnimationController _controller;
#override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(milliseconds: 2000),
vsync: this,
);
}
#override
void dispose() {
_controller.dispose();
super.dispose();
}
Color _color = Color(0xffB05CA1);
#override
Widget build(BuildContext context) {
return Center(
child: CustomPaint(
painter: CirclePainter(
_controller,
color: _color.withOpacity(0.1),
),
child: SizedBox(
width: widget.size * 2,
height: widget.size * 2,
child: _button(),
),
),
);
}
Widget _button() {
return Center(
child: ClipRRect(
borderRadius: BorderRadius.circular(widget.size),
child: DecoratedBox(
decoration: BoxDecoration(
gradient: RadialGradient(
colors: <Color>[_color, Color.lerp(_color, Colors.black, 0.05)],
),
),
child: ScaleTransition(
scale: Tween(begin: 0.95, end: 1.0).animate(
CurvedAnimation(
parent: _controller,
curve: CurveWave(),
),
),
),
),
),
);
}
}
class CurveWave extends Curve {
const CurveWave();
#override
double transform(double t) {
if (t == 0 || t == 1) {
return 0.01;
}
return math.sin(t * math.pi);
}
}
class CirclePainter extends CustomPainter {
CirclePainter(
this._animation, {
#required this.color,
}) : super(repaint: _animation);
final Color color;
final Animation<double> _animation;
void circle(Canvas canvas, Rect rect, double value) {
final double opacity = (1.0 - (value / 4.0)).clamp(0.0, 0.2);
final Color _color = color.withOpacity(opacity);
final double size = rect.width / 2;
final double area = size * size;
final double radius = math.sqrt(area * value / 4);
final Paint paint = Paint()..color = _color;
canvas.drawCircle(rect.center, radius, paint);
}
#override
void paint(Canvas canvas, Size size) {
final Rect rect = Rect.fromLTRB(0.0, 0.0, size.width, size.height);
for (int wave = 3; wave >= 0; wave--) {
circle(canvas, rect, wave + _animation.value);
}
}
#override
bool shouldRepaint(CirclePainter oldDelegate) => true;
}
To fit this effect you will use customBorder inside the inkwell.
customBorder:StadiumBorder()

How to animate the rotation and size of a container/image to be full screen (manual portrait to landscape)

struggling with a Flutter animation issue...
I am trying to animate the rotation of a container 1/4 turn and then resize the container by swapping width and height to achieve full screen.
I created a small app to illustrate. The goal is for the red container to take up the
whole screen but it is being constrained. Any idea what I am doing wrong or how to remove that constraint?
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: FlutterAnimations(),
);
}
}
class FlutterAnimations extends StatefulWidget {
#override
_FlutterAnimationsState createState() => _FlutterAnimationsState();
}
class _FlutterAnimationsState extends State<FlutterAnimations>
with SingleTickerProviderStateMixin {
AnimationController _controller;
#override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 1600),
);
_controller.addListener(() {
setState(() {});
});
_controller.forward();
}
#override
void dispose() {
super.dispose();
_controller.dispose();
}
#override
Widget build(BuildContext context) {
timeDilation = 3.0;
var screenWidth = MediaQuery.of(context).size.width;
var screenHeight = MediaQuery.of(context).size.height;
return RotationTransition(
turns: Tween(begin: 0.0, end: .25).animate(_controller),
child: Center(
child: Container(
color: Colors.red,
width: _controller.value * screenHeight,
height: _controller.value * screenWidth,
child: FlutterLogo()),
),
);
}
}
animation rotation
You can study the constraints here: Understanding constraints
The problem of your case is that The original Width constraints is screenWidth
That means you can only use screenWidth as your child widget height after it rotated 90 degree
The original code will be similar to:
return ConstrainedBox(
constraints: BoxConstraints(
maxHeight:MediaQuery.of(context).size.height,
maxWidth: MediaQuery.of(context).size.width,
),
child: RotationTransition(
...
You can always break the constraints rule by using OverflowBox
return OverflowBox(
maxWidth: screenHeight,
child: RotationTransition(
...

Flutter add animation small to big

Need to know how can i add some animation on my splash screen. I just need to add when app open the center image will show small to large.
My code
class _MyHomePageState extends State<MyHomePage> {
#override
void initState() {
super.initState();
Timer(
Duration(seconds: 3),
() => Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (BuildContext context) => HomeScreen())));
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/bg#3x.png"),
fit: BoxFit.cover,
),
),
child: Center(
child: Image.asset("assets/logo#2x.png"),
) /* add child content here */,
),
);
}
}
You can use Tween AnimationController with AnimatedBuilder to for this purpose. Here's an example you just need to replace Container with your Image or you can also wrap the Image with a Container.
Since, you want the image to increase the size at splash screen so use forward() property of AnimationController in initState.
Then replace the height and width property of your image with _animationSize.value. Adjust the size according to your need here:
Size:
_tweenSize = Tween(begin: 50, end: 200);
Duration:
_animationController = AnimationController(vsync: this, duration: Duration(milliseconds: 400));
Replace:
AnimatedBuilder(
animation: _animationSize,
builder: (context, child) {
// Put your image here and replace height, width of image with _animationSize.value
return Container(
color: Colors.red,
height: _animationSize.value,
width: _animationSize.value,
);
}),
class HomeScreen extends StatefulWidget {
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen>
with SingleTickerProviderStateMixin {
Tween<double> _tweenSize;
Animation<double> _animationSize;
AnimationController _animationController;
#override
void initState() {
_animationController =
AnimationController(vsync: this, duration: Duration(milliseconds: 400));
_tweenSize = Tween(begin: 50, end: 200);
_animationSize = _tweenSize.animate(_animationController);
_animationController.forward();
super.initState();
}
#override
void dispose() {
_animationController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: AnimatedBuilder(
animation: _animationSize,
builder: (context, child) {
// Put your image here and replace height, width of image with _animationSize.value
return Container(
color: Colors.red,
height: _animationSize.value,
width: _animationSize.value,
);
}),
),
);
}
}

flutter moving container from outside of screen to on screen with container size

in this sample code i want to make container with for example 100.0 size of height and move that into screen by animation to show that, like with simple bottom sheet, this sample code work but its not what i want to have
problem is moving that into screen with size of container witch that
is 100.0 on our sample
start animation from bottom height of container into screen
for example:
in this sample code animate move container to top of screen not size of that
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Page(),
);
}
}
class Page extends StatefulWidget {
#override
State<StatefulWidget> createState() => _PageState();
}
class _PageState extends State<Page> with SingleTickerProviderStateMixin {
Tween<Offset> tween = Tween<Offset>(
begin: Offset(0.0, 10000.0),
end: Offset(0.0, 0.0),
);
Animation<Offset> animation;
AnimationController animationController;
GlobalKey _widgetKey = GlobalKey();
#override
void initState() {
super.initState();
animationController = AnimationController(
vsync: this,
duration: Duration(seconds: 2),
);
animation = tween.animate(animationController);
Future<void>.delayed(Duration(seconds: 1), () {
final Size screenSize = MediaQuery.of(context).size;
final RenderBox widgetRenderBox =
_widgetKey.currentContext.findRenderObject();
final Size widgetSize = widgetRenderBox.size;
final double offset = (screenSize.height / 2 / widgetSize.height).ceilToDouble();
tween = Tween<Offset>(
begin: Offset(0.0, offset),
end: Offset(0.0, 0.0),
);
animation = tween.animate(animationController);
this.setState((){
animationController.forward();
});
});
}
#override
void dispose() {
animationController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('ddddddd'),),
body: Stack(
alignment: Alignment.center,
fit: StackFit.loose,
children: <Widget>[
SlideTransition(
position: animation,
child: Container(
key: _widgetKey,
height:100.0,
width: 300.0,
color:Colors.indigo,
child:Center(
child:Text('ddddddddddddd'),
)
)
),
],
),
);
}
}
I hope I did not misunderstood your question.
The Stack should have the size of the whole screen. Wrap it with SizedBox for example.
No need to center the text. You should rather align it inside the Container itself.
The container should have the width of the screen.
The height of the container is not necessary and therefore we don't need to figure it out.
This works for me:
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return const MaterialApp(
home: Page(),
);
}
}
class Page extends StatefulWidget {
const Page({Key? key}) : super(key: key);
#override
State<StatefulWidget> createState() => _PageState();
}
class _PageState extends State<Page> with SingleTickerProviderStateMixin {
late final AnimationController _animationController =
AnimationController(vsync: this, duration: const Duration(seconds: 2));
late final Animation<Offset> _animation =
Tween<Offset>(begin: const Offset(0, 1), end: const Offset(0, 0))
.animate(_animationController);
#override
void initState() {
super.initState();
delayedStart();
}
void delayedStart() async {
await Future.delayed(const Duration(seconds: 2), () {
_animationController.forward();
});
}
#override
void dispose() {
_animationController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('ddddddd'),
),
body: SizedBox(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: Stack(
alignment: Alignment.bottomCenter,
fit: StackFit.loose,
children: <Widget>[
SlideTransition(
position: _animation,
child: Container(
alignment: Alignment.center,
height: 100,
width: MediaQuery.of(context).size.width,
color: Colors.indigo,
child: const Text('ddddddddddddd')
)
),
],
),
),
);
}
}

Ripple animation flutter

I want to create ripple animation using flutter. I already know ripple effect but this is not what I want , I want something which is here in the link
Output
AnimationController _controller;
#override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
lowerBound: 0.5,
duration: Duration(seconds: 3),
)..repeat();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Title")),
body: _buildBody(),
);
}
Widget _buildBody() {
return AnimatedBuilder(
animation: CurvedAnimation(parent: _controller, curve: Curves.fastOutSlowIn),
builder: (context, child) {
return Stack(
alignment: Alignment.center,
children: <Widget>[
_buildContainer(150 * _controller.value),
_buildContainer(200 * _controller.value),
_buildContainer(250 * _controller.value),
_buildContainer(300 * _controller.value),
_buildContainer(350 * _controller.value),
Align(child: Icon(Icons.phone_android, size: 44,)),
],
);
},
);
}
Widget _buildContainer(double radius) {
return Container(
width: radius,
height: radius,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.blue.withOpacity(1 - _controller.value),
),
);
}
Here is another version using CustomPaint
import 'dart:math' as math show sin, pi, sqrt;
import 'package:flutter/animation.dart';
import 'package:flutter/material.dart';
class Ripples extends StatefulWidget {
const Ripples({
Key key,
this.size = 80.0,
this.color = Colors.pink,
this.onPressed,
#required this.child,
}) : super(key: key);
final double size;
final Color color;
final Widget child;
final VoidCallback onPressed;
#override
_RipplesState createState() => _RipplesState();
}
class _CirclePainter extends CustomPainter {
_CirclePainter(
this._animation, {
#required this.color,
}) : super(repaint: _animation);
final Color color;
final Animation<double> _animation;
void circle(Canvas canvas, Rect rect, double value) {
final double opacity = (1.0 - (value / 4.0)).clamp(0.0, 1.0);
final Color _color = color.withOpacity(opacity);
final double size = rect.width / 2;
final double area = size * size;
final double radius = math.sqrt(area * value / 4);
final Paint paint = Paint()..color = _color;
canvas.drawCircle(rect.center, radius, paint);
}
#override
void paint(Canvas canvas, Size size) {
final Rect rect = Rect.fromLTRB(0.0, 0.0, size.width, size.height);
for (int wave = 3; wave >= 0; wave--) {
circle(canvas, rect, wave + _animation.value);
}
}
#override
bool shouldRepaint(_CirclePainter oldDelegate) => true;
}
class _RipplesState extends State<Ripples> with TickerProviderStateMixin {
AnimationController _controller;
#override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(milliseconds: 2000),
vsync: this,
)..repeat();
}
#override
void dispose() {
_controller.dispose();
super.dispose();
}
Widget _button() {
return Center(
child: ClipRRect(
borderRadius: BorderRadius.circular(widget.size),
child: DecoratedBox(
decoration: BoxDecoration(
gradient: RadialGradient(
colors: <Color>[
widget.color,
Color.lerp(widget.color, Colors.black, .05)
],
),
),
child: ScaleTransition(
scale: Tween(begin: 0.95, end: 1.0).animate(
CurvedAnimation(
parent: _controller,
curve: const _PulsateCurve(),
),
),
child: widget.child,
),
),
),
);
}
#override
Widget build(BuildContext context) {
return CustomPaint(
painter: _CirclePainter(
_controller,
color: widget.color,
),
child: SizedBox(
width: widget.size * 2.125,
height: widget.size * 2.125,
child: _button(),
),
);
}
}
class _PulsateCurve extends Curve {
const _PulsateCurve();
#override
double transform(double t) {
if (t == 0 || t == 1) {
return 0.01;
}
return math.sin(t * math.pi);
}
}