Animate the elevation of flutter widget - dart

I want to animate the elevation of the widget, without the two hands(:
i`ve tried to change the elevation of material widget but nothing changed

To animate the elevation you'd need to handle the animation yourself, using an AnimationController. Heres a full example:
import 'package:flutter/material.dart';
void main() => runApp(App());
class App extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: AnimatedElevationButton(),
),
),
);
}
}
class AnimatedElevationButton extends StatefulWidget {
#override
_AnimatedElevationButtonState createState() =>
_AnimatedElevationButtonState();
}
class _AnimatedElevationButtonState extends State<AnimatedElevationButton>
with SingleTickerProviderStateMixin {
AnimationController _animationController;
Animation<double> _animationTween;
#override
void initState() {
super.initState();
_animationController = AnimationController(
duration: Duration(milliseconds: 30),
vsync: this,
);
_animationTween =
Tween(begin: 20.0, end: 0.0).animate(_animationController);
_animationController.addListener(() {
setState(() {});
});
}
#override
Widget build(BuildContext context) {
return GestureDetector(
onTapDown: _onTapDown,
onTapUp: _onTapUp,
child: Material(
color: Colors.red,
borderRadius: BorderRadius.circular(8.0),
elevation: _animationTween.value,
child: SizedBox(
width: 100,
height: 50,
),
),
);
}
void _onTapDown(TapDownDetails details) {
_animationController.forward();
}
void _onTapUp(TapUpDetails details) {
_animationController.reverse();
}
}

Related

Flutter - My animation is only playing once

I wanted to animate text and I put a nice animation. So I've made a statefull widget called AnimatedText() and I use it in an other stateful widget that use this AnimatedText and refresh the text every time you clic the screen. However, when I change this text with a setState(), the animation doesn't play again if it had already played...
Here is my code, the AnimatedText() :
class AnimatedText extends StatefulWidget {
double textSize;
String text;
AnimatedText(this.text, {this.textSize = 20});
#override
_AnimatedTextState createState() => _AnimatedTextState();
}
class _AnimatedTextState extends State<AnimatedText> with SingleTickerProviderStateMixin {
Animation _fontSizeAnimation;
AnimationController _controller;
#override
void initState() {
_controller = AnimationController(duration: Duration(milliseconds: 250), vsync: this);
_fontSizeAnimation = CurvedAnimation(parent: _controller, curve: Curves.bounceOut);
_fontSizeAnimation.addListener(() => setState(() {}));
_controller.forward();
super.initState();
}
#override
void dispose() {
_controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Text(widget.text, textAlign: TextAlign.center, style: GoogleFonts.rubik(color: Colors.white, fontSize: _fontSizeAnimation.value*ResponsiveSize().responsiveSizeSmall(widget.textSize)));
}
}
And here is the class that use the AnimatedText():
class BasicDisplay extends StatefulWidget {
Question question;
VoidCallback onTap;
VoidCallback onPressed;
BasicDisplay(this.question, this.onTap, this.onPressed);
#override
_BasicDisplayState createState() => _BasicDisplayState();
}
class _BasicDisplayState extends State<BasicDisplay> with SingleTickerProviderStateMixin {
#override
Widget build(BuildContext context) {
return GamePageBackground(
onTap: widget.onTap,
question: widget.question,
children: <Widget>[
Expanded(
child: Container(
alignment: Alignment.topRight,
child: IconButton(
onPressed: widget.onPressed,
icon: Icon(Icons.clear, color: Color(0xaaffffff), size: ResponsiveSize().responsiveSize(quitIconButtonSize),),
),
),
),
AnimatedText(widget.question.category, textSize: questionCategoryTextSize,),
AnimatedText(widget.question.question, textSize: questionTextSize,),
Expanded(
child: Container(
padding: EdgeInsets.only(bottom: ResponsiveSize().responsiveSize(10)),
alignment: Alignment.bottomCenter,
child: Text(widget.question.explanation, textAlign: TextAlign.center ,style: GoogleFonts.rubik(color: Colors.white, fontSize: ResponsiveSize().responsiveSize(bottomExplanationTextSize))),
),
),
],
);
}
}
The onPressed call back call the Game class that will refresh the text.
Any one know how to solve this problem ?
I found a solution based on #HBS idea !
I took his function and changed it a little bit :
#override
void didUpdateWidget(AnimatedText oldWidget) {
if(oldWidget.text != widget.text) {
_controller.reset();
_controller.forward();
}
super.didUpdateWidget(oldWidget);
}
You can override the didUpdateWidget in your AnimatedText class:
#override
void didUpdateWidget(AnimatedText oldWidget) {
if(oldWidget.text != widget.text) {
_controller.reset();
_controller.forward();
}
super.didUpdateWidget(oldWidget);
}

Animation Of Container using Offset - Flutter

I am trying to move the container on the screen by giving begin and end offset like from Offset(0.0,0.0) to Offset(400.0,300.0). I am using Slide Transition to animate the container I am using Tween<Offset>(begin: const Offset(3.0, 4.0), end: Offset(0.0, 0.0)) to move it on the screen I want to pass these Offset(400.0,300.0) and animate it.
Here is my code
class MoveContainer extends StatefulWidget {
MoveContainer({Key key, }) : super(key: key);
#override
State<StatefulWidget> createState() {
return new _MyMoveContainer();
}
}
class _MyMoveContainer extends State<MoveContainer>
with TickerProviderStateMixin {
GlobalKey _globalKey = new GlobalKey();
AnimationController _controller;
Animation<Offset> _offset;
Offset local;
#override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: const Duration(seconds: 3),
);
_offset =
Tween<Offset>(begin: const Offset(3.0, 4.0), end: Offset(0.0, 0.0))
.animate(_controller);
_offset.addListener(() {
setState(() {});
});
_controller.forward();
}
#override
void dispose() {
_controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return SlideTransition(
position: _offset,
child: GestureDetector(
onPanStart: (start) {
RenderBox getBox = context.findRenderObject();
local = getBox.localToGlobal(start.globalPosition);
print('point are $local');
},
child: Container(
color: Colors.cyan,
height: 200.0,
width: 200.0,
child: Text("hello ")),
),
);
}
}
Probably this question is not actual for the author. (Asked 7 months ago).
But maybe my answer will help someone else.
Usually Slide Transition is used for transitions between pages. That is why, one unit of position value here is the size of one page. When you put there Offset(400.0,300.0) it's equal 400 screen right, and 300 pages down.
For your case it better to use AnimatedPositioned Widget.
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
backgroundColor: Colors.blue,
body: MoveContainer(),
),
);
}
}
class MoveContainer extends StatefulWidget {
#override
_MoveContainerState createState() => _MoveContainerState();
}
class _MoveContainerState extends State<MoveContainer> {
Offset offset = Offset.zero;
final double height = 200;
final double width = 200;
#override
Widget build(BuildContext context) {
return GestureDetector(
onPanStart: (details) {
RenderBox getBox = context.findRenderObject();
setState(() {
offset = getBox.localToGlobal(details.globalPosition);
});
},
child: Stack(
children: <Widget>[
AnimatedPositioned(
duration: Duration(milliseconds: 300),
top: offset.dy - (height / 2),
left: offset.dx - (width / 2),
child: Container(
color: Colors.cyan,
height: height,
width: width,
child: Text("hello "),
),
),
],
),
);
}
}

Flutter - How to get a semitransparent blurring layer with a hole with soft edges

I want to create a screen for the coach mark. Idea is to blur and make darker everything except the region where is my icon located.
I could cut a circle with feather edges. But the icon on the background is also blurred.
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatefulWidget {
#override
State<StatefulWidget> createState() => MyAppState();
}
class MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
home: HomeScreen(),
);
}
}
class HomeScreen extends StatefulWidget {
#override
_HomeScreenState createState() => new _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
#override
Widget build(BuildContext context) {
return Stack(children: <Widget>[
_buildScaffold(),
CustomPaint(
child: Container(
constraints: BoxConstraints.expand(),
child: BackdropFilter(
filter: new ui.ImageFilter.blur(sigmaX: 2.0, sigmaY: 2.0),
child: Container(
decoration: new BoxDecoration(
color: Colors.grey[900].withOpacity(0.7)),
))),
foregroundPainter: CoachMarksPainter(),
),
]);
}
Widget _buildScaffold() {
return Scaffold(
appBar: AppBar(
title: Text("Hello"),
actions: <Widget>[
new IconButton(
onPressed: () => print("press"),
icon: new Icon(Icons.calendar_today),
),
PopupMenuButton<String>(
itemBuilder: (BuildContext context) {},
),
],
),
body: new Container(
decoration: new BoxDecoration(
image: new DecorationImage(
image: new NetworkImage(
"http://www.mobileswall.com/wp-content/uploads/2015/03/640-Sunset-Beach-2-l.jpg"),
fit: BoxFit.cover))));
}
}
class CoachMarksPainter extends CustomPainter {
void paint(Canvas canvas, Size size) {
print("Paint size=$size canvas=${canvas.getSaveCount()}");
canvas.save();
Path path = Path()
..addOval(Rect.fromCircle(center: Offset(287.0, 52.0), radius: 25.0))
..addRect(new Rect.fromLTWH(
-10.0, -10.0, size.width + 20.0, size.height + 20.0))
//to have rect a bit larger than screen, so blurred edges won't be seen
..fillType = PathFillType.evenOdd;
Paint paint = Paint()
..blendMode = BlendMode.dstOut
..color = Colors.white.withOpacity(0.4)
..maskFilter = new MaskFilter.blur(
BlurStyle.normal, 2.0); //BoxShadow.convertRadiusToSigma(25.0)
canvas.drawPath(path, paint);
canvas.restore();
}
#override
bool shouldRepaint(CoachMarksPainter oldDelegate) => false;
#override
bool shouldRebuildSemantics(CoachMarksPainter oldDelegate) => false;
}
blurred background with a highlighted icon in a circle
Is it possible to use ImageFilter.blur for Canvas? I use MaskFilter, but it does not blur canvas as much as ImageFilter for BackdropFilter widget.
Ideally, I want to get a semitransparent blurring layer with a hole with soft edges.
P.S. I read this question but I need to invert it.
#Marica Hopefully this is doing what you want.
https://gist.github.com/slightfoot/76043f8f3fc4a8b20fc24c5a6f22b0a0
import 'dart:async';
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
State<StatefulWidget> createState() => MyAppState();
}
class MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Coach Mark Demo',
home: HomeScreen(),
);
}
}
class HomeScreen extends StatefulWidget {
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
final GlobalKey<ScaffoldState> _scaffold = GlobalKey();
final GlobalKey<CoachMarkState> _calendarMark = GlobalKey();
#override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffold,
appBar: AppBar(
title: Text("Hello"),
actions: <Widget>[
CoachMark(
key: _calendarMark,
id: 'calendar_mark',
text: 'Tap here to use the Calendar!',
child: GestureDetector(
onLongPress: () => _calendarMark.currentState.show(),
child: IconButton(
onPressed: () => print('calendar'),
icon: Icon(Icons.calendar_today),
),
),
),
PopupMenuButton<String>(
itemBuilder: (BuildContext context) {
return <PopupMenuEntry<String>>[
PopupMenuItem<String>(
value: 'reset',
child: Text('Reset'),
),
];
},
onSelected: (String value) {
if (value == 'reset') {
_calendarMark.currentState.reset();
_scaffold.currentState.showSnackBar(SnackBar(
content: Text('Hot-restart the app to see the coach-mark again.'),
));
}
},
),
],
),
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage("http://www.mobileswall.com/wp-content/uploads/2015/03/640-Sunset-Beach-2-l.jpg"),
fit: BoxFit.cover),
),
),
);
}
}
class CoachMark extends StatefulWidget {
const CoachMark({
Key key,
#required this.id,
#required this.text,
#required this.child,
}) : super(key: key);
final String id;
final String text;
final Widget child;
#override
CoachMarkState createState() => CoachMarkState();
}
typedef CoachMarkRect = Rect Function();
class CoachMarkState extends State<CoachMark> {
_CoachMarkRoute _route;
String get _key => 'mark_${widget.id}';
#override
void initState() {
super.initState();
test().then((bool seen) {
if (seen == false) {
show();
}
});
}
#override
void didUpdateWidget(CoachMark oldWidget) {
super.didUpdateWidget(oldWidget);
_rebuild();
}
#override
void reassemble() {
super.reassemble();
_rebuild();
}
#override
void dispose() {
dismiss();
super.dispose();
}
#override
Widget build(BuildContext context) {
_rebuild();
return widget.child;
}
void show() {
if (_route == null) {
_route = _CoachMarkRoute(
rect: () {
final box = context.findRenderObject() as RenderBox;
return box.localToGlobal(Offset.zero) & box.size;
},
text: widget.text,
padding: EdgeInsets.all(4.0),
onPop: () {
_route = null;
mark();
},
);
Navigator.of(context).push(_route);
}
}
void _rebuild() {
if (_route != null) {
WidgetsBinding.instance.addPostFrameCallback((_) {
_route.changedExternalState();
});
}
}
void dismiss() {
if (_route != null) {
_route.dispose();
_route = null;
}
}
Future<bool> test() async {
return (await SharedPreferences.getInstance()).getBool(_key) ?? false;
}
void mark() async {
(await SharedPreferences.getInstance()).setBool(_key, true);
}
void reset() async {
(await SharedPreferences.getInstance()).remove(_key);
}
}
class _CoachMarkRoute<T> extends PageRoute<T> {
_CoachMarkRoute({
#required this.rect,
#required this.text,
this.padding,
this.onPop,
this.shadow = const BoxShadow(color: const Color(0xB2212121), blurRadius: 8.0),
this.maintainState = true,
this.transitionDuration = const Duration(milliseconds: 450),
RouteSettings settings,
}) : super(settings: settings);
final CoachMarkRect rect;
final String text;
final EdgeInsets padding;
final BoxShadow shadow;
final VoidCallback onPop;
#override
final bool maintainState;
#override
final Duration transitionDuration;
#override
bool didPop(T result) {
onPop();
return super.didPop(result);
}
#override
Widget buildPage(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) {
Rect position = rect();
if (padding != null) {
position = padding.inflateRect(position);
}
position = Rect.fromCircle(center: position.center, radius: position.longestSide * 0.5);
final clipper = _CoachMarkClipper(position);
return Material(
type: MaterialType.transparency,
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTapDown: (d) => Navigator.of(context).pop(),
child: IgnorePointer(
child: FadeTransition(
opacity: animation,
child: Stack(
children: <Widget>[
ClipPath(
clipper: clipper,
child: BackdropFilter(
filter: ui.ImageFilter.blur(sigmaX: 2.0, sigmaY: 2.0),
child: Container(
color: Colors.transparent,
),
),
),
CustomPaint(
child: SizedBox.expand(
child: Center(
child: Text(text,
style: const TextStyle(
fontSize: 22.0,
fontStyle: FontStyle.italic,
color: Colors.white,
)),
),
),
painter: _CoachMarkPainter(
rect: position,
shadow: shadow,
clipper: clipper,
),
),
],
),
),
),
),
);
}
#override
bool get opaque => false;
#override
Color get barrierColor => null;
#override
String get barrierLabel => null;
}
class _CoachMarkClipper extends CustomClipper<Path> {
final Rect rect;
_CoachMarkClipper(this.rect);
#override
Path getClip(Size size) {
return Path.combine(PathOperation.difference, Path()..addRect(Offset.zero & size), Path()..addOval(rect));
}
#override
bool shouldReclip(_CoachMarkClipper old) => rect != old.rect;
}
class _CoachMarkPainter extends CustomPainter {
_CoachMarkPainter({
#required this.rect,
#required this.shadow,
this.clipper,
});
final Rect rect;
final BoxShadow shadow;
final _CoachMarkClipper clipper;
void paint(Canvas canvas, Size size) {
final circle = rect.inflate(shadow.spreadRadius);
canvas.saveLayer(Offset.zero & size, Paint());
canvas.drawColor(shadow.color, BlendMode.dstATop);
canvas.drawCircle(circle.center, circle.longestSide * 0.5, shadow.toPaint()..blendMode = BlendMode.clear);
canvas.restore();
}
#override
bool shouldRepaint(_CoachMarkPainter old) => old.rect != rect;
#override
bool shouldRebuildSemantics(_CoachMarkPainter oldDelegate) => false;
}
I'm not sure I understand the question. It seems that what you want would be achievable by using 3 layers in a stack. Lowest is your background, second is the darker frosted blur and put your icon on top.
Am I misunderstanding something?

Flutter - Effect of flip card

I'm trying to make a flip card, what would be the best way to get the effect
I would use an AnimatedBuilder or AnimatedWidget to animate the values of a Transform widget. ScaleTransition almost does this for you, but it scales both directions, and you only want one.
import 'package:flutter/material.dart';
void main() {
runApp(new MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
home: new MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePageState createState() => new MyHomePageState();
}
class MyCustomCard extends StatelessWidget {
MyCustomCard({ this.colors });
final MaterialColor colors;
Widget build(BuildContext context) {
return new Container(
alignment: FractionalOffset.center,
height: 144.0,
width: 360.0,
decoration: new BoxDecoration(
color: colors.shade50,
border: new Border.all(color: new Color(0xFF9E9E9E)),
),
child: new FlutterLogo(size: 100.0, colors: colors),
);
}
}
class MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
AnimationController _controller;
Animation<double> _frontScale;
Animation<double> _backScale;
#override
void initState() {
super.initState();
_controller = new AnimationController(
vsync: this,
duration: const Duration(seconds: 1),
);
_frontScale = new Tween(
begin: 1.0,
end: 0.0,
).animate(new CurvedAnimation(
parent: _controller,
curve: new Interval(0.0, 0.5, curve: Curves.easeIn),
));
_backScale = new CurvedAnimation(
parent: _controller,
curve: new Interval(0.5, 1.0, curve: Curves.easeOut),
);
}
#override
void dispose() {
_controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
ThemeData theme = Theme.of(context);
return new Scaffold(
appBar: new AppBar(),
floatingActionButton: new FloatingActionButton(
child: new Icon(Icons.flip_to_back),
onPressed: () {
setState(() {
if (_controller.isCompleted || _controller.velocity > 0)
_controller.reverse();
else
_controller.forward();
});
},
),
body: new Center(
child: new Stack(
children: <Widget>[
new AnimatedBuilder(
child: new MyCustomCard(colors: Colors.orange),
animation: _backScale,
builder: (BuildContext context, Widget child) {
final Matrix4 transform = new Matrix4.identity()
..scale(1.0, _backScale.value, 1.0);
return new Transform(
transform: transform,
alignment: FractionalOffset.center,
child: child,
);
},
),
new AnimatedBuilder(
child: new MyCustomCard(colors: Colors.blue),
animation: _frontScale,
builder: (BuildContext context, Widget child) {
final Matrix4 transform = new Matrix4.identity()
..scale(1.0, _frontScale.value, 1.0);
return new Transform(
transform: transform,
alignment: FractionalOffset.center,
child: child,
);
},
),
],
),
),
);
}
}
I used simple approach, rotated it on X axis. Here is the full code.
void main() => runApp(MaterialApp(home: HomePage()));
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> with SingleTickerProviderStateMixin {
AnimationController _controller;
bool _flag = true;
Color _color = Colors.blue;
#override
void initState() {
super.initState();
_controller = AnimationController(vsync: this, duration: Duration(seconds: 1), value: 1);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.crop_rotate),
onPressed: () async {
if (_flag) {
await _controller.reverse();
setState(() {
_color = Colors.orange;
});
await _controller.forward();
} else {
await _controller.reverse();
setState(() {
_color = Colors.blue;
});
await _controller.forward();
}
_flag = !_flag;
},
),
body: Center(
child: AnimatedBuilder(
animation: _controller,
builder: (context, child) {
return Transform(
transform: Matrix4.rotationX((1 - _controller.value) * math.pi / 2),
alignment: Alignment.center,
child: Container(
height: 100,
margin: EdgeInsets.symmetric(horizontal: 20),
padding: EdgeInsets.symmetric(vertical: 12),
alignment: Alignment.center,
decoration: BoxDecoration(color: _color.withOpacity(0.2), border: Border.all(color: Colors.grey)),
child: FlutterLogo(colors: _color, size: double.maxFinite),
),
);
},
),
),
);
}
}
You can use the flip_card Flutter package. It lets you define a front and back widget and can be flipped horizontally or vertically.

Flutter - Set the scale of a widget

I am trying to create an animation that "pops" the widget to the front and returns to it
import "package:flutter/material.dart";
class ScoreCounter extends StatefulWidget {
#override
_ScoreCounter createState() => new _ScoreCounter();
}
class _ScoreCounter extends State<ScoreCounter> with SingleTickerProviderStateMixin{
AnimationController _controller;
#override
void initState() {
super.initState();
_controller = new AnimationController(
duration: const Duration(seconds: 10),
vsync: this,
)..forward();
}
#override
build(BuildContext context){
return new AnimatedBuilder(
animation: _controller,
child: new Container(width: 200.0, height: 200.0, color: Colors.green),
builder: (BuildContext context, Widget child) {
//What to return that scales the element
},
);
}
}
For rotating, I would use a Transform and return a Matrix. But what should I return to accomplish the scaling animation?
Thanks in advance
Just as a alternative, to set just scale for a specific Widget.
Transform.scale(
scale: 1.0,
child: Container(
height: 200.0,
width: 200.0,
color: Colors.pink,
),
),
If you're going to size your contents manually you could just read controller.value in your builder function and use that to set the size of the container.
Alternatively, you could consider a pair of SizeTransitions for each axis. The Align class may also be useful because you can set a sizeFactor in each dimension.
import 'package:flutter/material.dart';
void main() {
runApp(new MaterialApp(
home: new HomePage(),
));
}
class HomePage extends StatefulWidget {
HomePageState createState() => new HomePageState();
}
class HomePageState extends State<HomePage> {
#override
Widget build(BuildContext context) {
return new Scaffold(
floatingActionButton: new FloatingActionButton(
child: new Icon(Icons.sort),
onPressed: () {},
),
body: new Center(
child: new ScoreCounter(),
),
);
}
}
class ScoreCounter extends StatefulWidget {
#override
_ScoreCounter createState() => new _ScoreCounter();
}
class _ScoreCounter extends State<ScoreCounter>
with SingleTickerProviderStateMixin {
AnimationController _controller;
#override
void initState() {
super.initState();
_controller = new AnimationController(
duration: const Duration(seconds: 1),
vsync: this,
)
..forward();
}
#override
build(BuildContext context){
return new AnimatedBuilder(
animation: _controller,
builder: (BuildContext context, Widget child) {
double size = _controller.value * 200.0;
return new Container(width: size, height: size, color: Colors.green);
},
);
}
}
Another Approach is to create generalized Scale Transformation.
Simply add this method to your component
Matrix4 scaleXYZTransform({
double scaleX = 1.00,
double scaleY = 1.00,
double scaleZ = 1.00,
}) {
return Matrix4.diagonal3Values(scaleX, scaleY, scaleZ);
}
Now you can easily Scale any widget by wrapping it:
Transform(
transform: scaleXYZTransform(scaleX: .5, scaleY: .5),
child: Container(
child: myAwesomeWidget(),
));

Resources