In Flutter, there are several options available to rotate an image, including:
Transform
Widget: The Transform widget is used to apply a transformation to its child widget. You can use this widget to rotate an image by setting the rotation property in a Matrix4 object.RotatedBox
Widget: The RotatedBox widget rotates its child by a given number of quarter turns. This widget is useful if you need to rotate an image by a specific number of turns.TweenAnimationBuilder
Widget: The TweenAnimationBuilder widget that allows you to perform animations by specifying the start and end values.AnimatedBuilder
Widget: The AnimatedBuilder widget can be used to animate the rotation of an image. You can use this widget to rotate an image by changing the value of the transform property.
What is the Flutter Transform.rotate widget
The Transform.rotate
widget in Flutter is used to rotate a child widget by a given angle. It’s a part of the Transform
widget family, which are used to apply transformations to widgets, such as translation, scaling, and rotation.
Here’s a simple example of how you could use the Transform.rotate
widget to rotate a Container
widget with an image:
double _angle = 30;
Transform.rotate(
angle: _angle,
child: Container(
width: 200,
height: 200,
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(
'https://via.placeholder.com/200x200',
),
),
),
),
)
In this example, the angle
property of the Transform.rotate
widget is set to a value stored in a variable _angle
. The Container
widget is the child of the Transform.rotate
widget and will be rotated by the angle specified in the angle
property.
It’s important to note that the rotation angle is specified in radians, not degrees. To convert degrees to radians, you can use the radians
function from the dart:math
library.
What is the Flutter RotatedBox widget
The RotatedBox
widget in Flutter is a simple widget that rotates its child widget by a specified number of degrees. It allows you to change the orientation of a widget without affecting its layout, as the child widget is rotated inside the constraints of the RotatedBox
widget.
RotatedBox(
quarterTurns: 1, // rotation in 90 degree increments
child: Container(
width: 100,
height: 100,
color: Colors.blue,
),
)
In this example, the child Container
widget is rotated by 90 degrees (one quarterTurn
) inside the RotatedBox
widget. The RotatedBox
widget takes care of rotating the child widget while preserving its original dimensions and layout.
It’s important to note that RotatedBox
rotates the child widget in its own coordinate system, not in the parent’s coordinate system. So, if you have multiple RotatedBox
widgets, the rotation of each RotatedBox
is independent of the others.
What is the Flutter AnimatedBuilder widget
The AnimatedBuilder
widget in Flutter is a widget that allows you to build and animate other widgets in response to changes in an animation. It’s a widget that provides a convenient way to animate widgets in Flutter by automatically animating the widgets whenever the animation changes.
Here’s an example of how to use the AnimatedBuilder
widget in Flutter:
AnimatedBuilder(
animation: _animation,
child: Container(width: 100, height: 100),
builder: (context, child) {
return Transform.rotate(
angle: _animation.value,
child: child,
);
},
)
In this example, the AnimatedBuilder
widget takes an animation
and a builder
function. The builder
function is called whenever the animation changes and builds the widget tree. The child
parameter in the builder
function is the child passed to the AnimatedBuilder
. In this case, it’s a Container
widget.
The builder
function returns a Transform.rotate
widget, which rotates the child Container
widget. The rotation angle is determined by the current value of the animation. Whenever the animation changes, the builder
function is called again and the child widget is rebuilt and animated.
The AnimatedBuilder
widget can simplify the process of animating widgets in Flutter, as it takes care of updating the widget whenever the animation changes and provides a convenient way to build the widget tree for the animation.
What is the Flutter TweenAnimationBuilder widget
The TweenAnimationBuilder
is a widget in Flutter that allows you to build an animation between two values over a specified duration. The TweenAnimationBuilder
widget uses a Tween
object to specify the values to animate between, and it automatically updates the animation whenever the animation value changes.
Here’s an example of how to use the TweenAnimationBuilder
widget in Flutter:
TweenAnimationBuilder(
duration: Duration(seconds: 1),
tween: Tween(begin: 0.0, end: 1.0),
builder: (context, value, child) {
return Container(
width: 100 + value * 100,
height: 100 + value * 100,
color: Colors.blue,
);
},
)
In this example, the TweenAnimationBuilder
takes a duration
, a tween
, and a builder
function. The duration
specifies the length of time the animation should take. The tween
specifies the values to animate between. In this case, the Tween
object animates between 0.0 and 1.0.
The builder
function is called whenever the animation value changes, and it builds the widget tree for the animation. The value
parameter in the builder
function is the current value of the animation, and the child
parameter is the child passed to the TweenAnimationBuilder
widget.
In this example, the builder
function returns a Container
widget with its width and height increasing based on the animation value. The animation runs for 1 second and the Container
widget grows from 100×100 to 200×200.
The TweenAnimationBuilder
widget is a convenient way to animate between values in Flutter, as it automatically updates the animation and provides a simple way to build the widget tree for the animation.
Image random rotation in Flutter with Transform.rotate
Here’s an example of how you can rotate a Container
widget with an Image
randomly with the press of an ElevatedButton
using the Transform
widget.
In order for the code to work you also need to import the math
package.
import 'dart:math';
double _rotation = 0;
void _onPressed() {
setState(() {
_rotation = _rotation + (pi / 4 + new Random().nextInt(100));
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('flutterassets.com'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Transform.rotate(
angle: _rotation,
child: Container(
height: 200,
width: 200,
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(
"https://picsum.photos/200/300"),
fit: BoxFit.cover,
),
),
),
),
ElevatedButton(
onPressed: _onPressed,
child: Text("Rotate"),
),
],
),
),
);
}
This code shows how to rotate a Container
widget with an image using a Transform
widget in Flutter. The current rotation angle is stored in a variable called _rotation
. When the ElevatedButton
is pressed, the _onPressed
method is triggered. This method updates the rotation angle by adding (pi / 4 + new Random().nextInt(100))
to the current angle. The updated angle is then used to rotate the Container
widget using the Transform.rotate
widget.
So, every time you press the button, the image inside the container will be rotated randomly. The rotation angle is updated every time the button is pressed, so the image will be rotated differently each time.
Animated Image random rotation in Flutter with AnimatedBuilder
You can add animation to the rotation using the AnimationController
class and the Tween
class in Flutter. The rotation duration can be set as an additional variable, for example _duration
. Here’s an updated example:
import 'dart:math';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation _animation;
double _rotation = 0;
int _duration = 1;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: Duration(seconds: _duration),
vsync: this,
);
_animation = Tween<double>(begin: 0, end: pi / 4 + new Random().nextInt(100))
.animate(_controller);
}
void _onPressed() {
_controller.reset();
_animation = Tween<double>(begin: _rotation, end: _rotation + pi / 4 + new Random().nextInt(100))
.animate(_controller);
_controller.forward();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('flutterassets.com'),
),
body: Center(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
AnimatedBuilder(
animation: _animation,
builder: (context, child) {
return Transform.rotate(
angle: _animation.value,
child: Container(
height: 200,
width: 200,
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(
"https://picsum.photos/200/300"),
fit: BoxFit.cover,
),
),
),
);
},
),
ElevatedButton(
onPressed: _onPressed,
child: Text("Rotate"),
),
],
),
),
),
);
}
}
Here is the explanation each section of the code:
Variables:
In the code, a few variables are defined to make the rotation work:
AnimationController _controller;
Animation _animation;
double _rotation = 0;
int _duration = 1;
_controller
is an instance of theAnimationController
class. It’s used to control the animation with a duration of_duration
seconds._animation
is an instance of theAnimation
class and represents the animation between the start and end rotation angles._rotation
is a variable that holds the current rotation angle in radians. It starts with a value of 0._duration
is an integer variable that determines the duration of the animation in seconds.
void initState()
:
This method is called when the widget is created for the first time. In this method, the _controller
is initialized and the _animation
is defined:
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: Duration(seconds: _duration),
vsync: this,
);
_animation = Tween<double>(begin: 0, end: pi / 4 + new Random().nextInt(100))
.animate(_controller);
}
void _onPressed
:
This method is called when the ElevatedButton
is pressed. It updates the rotation angle by adding (pi / 4 + new Random().nextInt(100))
to the current angle and starts the animation:
void _onPressed() {
_controller.reset();
_animation = Tween<double>(begin: _rotation, end: _rotation + pi / 4 + new Random().nextInt(100))
.animate(_controller);
_controller.forward();
}
build
:
The build
method returns the visual elements of the widget. In this code, it contains a Scaffold
widget with a Center
widget inside. The Center
widget contains a Column
widget with two children: an AnimatedBuilder
widget and an ElevatedButton
widget.
The AnimatedBuilder
widget is used to rebuild the Transform.rotate
widget with the updated rotation angle during the animation:
AnimatedBuilder(
animation: _animation,
builder: (context, child) {
return Transform.rotate(
angle: _animation.value,
child: Container(
height: 200,
width: 200,
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(
"https://picsum.photos/200/300"),
fit: BoxFit.cover,
),
),
),
);
},
)
The Transform.rotate
widget is used to rotate the Container
widget with the updated rotation angle. The ElevatedButton
widget is used to trigger the _onPressed
method and start the animation.
ElevatedButton(
onPressed: _onPressed,
child: Text('Rotate'),
)
In summary, this code demonstrates how to rotate a Container
widget with an image in Flutter using the Transform
widget, an AnimationController
, and an ElevatedButton
. The _onPressed
method is called when the button is pressed and updates the rotation angle, while the AnimatedBuilder
widget is used to rebuild the Transform.rotate
widget with the updated angle during the animation.
What is the Flutter RotatedBox widget
The RotatedBox
widget in Flutter is used to rotate its child widget by a given number of quarter turns. The number of quarter turns can be any integer value, both positive and negative. A quarter turn is equal to 90 degrees.
Here’s a simple example of how you could use the RotatedBox
widget to rotate a Container
widget with an image:
RotatedBox(
quarterTurns: 1,
child: Container(
width: 200,
height: 200,
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(
'https://via.placeholder.com/200x200',
),
),
),
),
)
In this example, the quarterTurns
property of the RotatedBox
widget is set to 1
, which means that the Container
widget will be rotated by 90 degrees (1 quarter turn). The Container
widget is the child of the RotatedBox
widget and will be rotated by the number of quarter turns specified in the quarterTurns
property.
It’s important to note that the RotatedBox
widget can only rotate its child in increments of 90 degrees, so it’s not possible to rotate it by a specific angle like in the case of the Transform.rotate
widget.
Rotate an Image with Flutter RotatedBox widget
Here’s an example of how you can use the RotatedBox
widget to rotate a Container
widget with an image when an ElevatedButton
is pressed in Flutter:
import 'dart:math';
int _turns = 0;
void _onPressed() {
setState(() {
_turns += 1;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
RotatedBox(
quarterTurns: _turns % 4,
child: Container(
width: 200,
height: 200,
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(
'https://via.placeholder.com/200x200',
),
),
),
),
),
ElevatedButton(
onPressed: _onPressed,
child: Text('Rotate'),
),
],
),
),
);
}
In this example, we use the RotatedBox
widget to rotate the Container
widget by a given number of quarter turns. The _turns
variable holds the number of turns that the container should rotate, and the _onPressed
method is called when the ElevatedButton
is pressed. It increments the _turns
variable by 1, and the build
method is called, updating the display with the rotated container.
The RotatedBox
widget takes an integer quarterTurns
parameter, which determines the number of quarter turns that the child should be rotated. In this case, we use the modulo operator %
to ensure that the rotation only goes from 0 to 3 turns.
Random Image Rotation with Flutter RotatedBox widget
You can modify the above code to rotate the container to a random angle. Here’s an example:
import 'dart:math';
int _quarters = 0;
void _onPressed() {
setState(() {
_quarters = Random().nextInt(4);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
RotatedBox(
quarterTurns: _quarters,
child: Container(
width: 200,
height: 200,
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(
'https://via.placeholder.com/200x200',
),
),
),
),
),
ElevatedButton(
onPressed: _onPressed,
child: Text('Rotate'),
),
],
),
),
);
}
In this example, the _angle
variable holds the rotation angle in radians. The _onPressed
method is called when the ElevatedButton
is pressed and updates the rotation angle with a random value between 0 and 2 * pi (0 to 360 degrees). The Transform.rotate
widget is used to rotate the Container
widget with the updated rotation angle.
I think is worth mentioning that the Flutter RenderBox doesn’t support animations. I tried to create an animation but I couldn’t.
Image random rotation with TweenAnimationBuilder in Flutter
Here is an example of how you can randomly rotate a Container with a network image using the TweenAnimationBuilder widget in Flutter:
import 'dart:math';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin{
double _angle = 0;
double _speed = 6.0;
Duration _duration = Duration(milliseconds: 2000);
late AnimationController _controller;
@override
void initState() {
_controller = AnimationController(
vsync: this,
duration: _duration,
);
super.initState();
}
void _onPressed() {
setState(() {
_controller.reset();
_controller.forward();
_angle = 2 * pi * new Random().nextDouble();
});
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('flutterassets.com'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TweenAnimationBuilder(
tween: Tween<double>(begin: 0, end: _angle * _speed),
duration: _duration,
curve: Curves.easeInOut,
builder: (BuildContext context, double angle, Widget? child) {
return Transform.rotate(
angle: angle,
child: child,
);
},
child: Image.network(
'https://via.placeholder.com/200x200',
),
),
ElevatedButton(
onPressed: _onPressed,
child: Text('Rotate'),
),
],
),
),
);
}
}
Variables:
double _angle = 0;
double _speed = 6.0;
Duration _duration = Duration(milliseconds: 2000);
late AnimationController _controller;
speed
: This is a double variable that represents the speed of the animation. The greater the value ofspeed
, the faster the animation will rotate._angle
is a double that represents the angle of rotation for the image._duration
is aDuration
that represents the length of time it takes for the rotation animation to complete._controller
is anAnimationController
that controls the animation.
void initState()
:
This method is called when the state of the widget is first created. It initializes the _controller
with a vsync
of this
and a duration
of _duration
.
@override
void initState() {
_controller = AnimationController(
vsync: this,
duration: _duration,
);
super.initState();
}
void _onPressed()
:
This method is called when the “Rotate” button is pressed. It sets the state, resets the _controller
, starts the animation with _controller.forward()
, and sets a new random value for _angle
.
void _onPressed() {
setState(() {
_controller.reset();
_controller.forward();
_angle = 2 * pi * new Random().nextDouble();
});
}
void dispose()
:
This method is called when the widget is no longer in use. It disposes of the _controller
to free up resources.
@override
void dispose() {
_controller.dispose();
super.dispose();
}
build
:
TweenAnimationBuilder
is a Flutter widget that enables you to perform animations in a simple and efficient manner. It achieves this by specifying a tween that maps the initial and final values of the animation.
The tween
property of the TweenAnimationBuilder
takes a Tween
object that defines the initial and final values of the animation. In this case, the initial value is 0 and the final value is the _angle
variable. The duration
property sets the length of time for which the animation should run. In this code, the duration is set to the value of the _duration
variable.
The curve
property is used to set the rate at which the animation progresses. The Curves.easeInOut
value is used to give the animation a smooth start and finish. The builder
property takes a callback function that will be called every time the animation updates. This function takes the current animation value (angle
) and returns a widget with the updated animation. In this case, the Transform.rotate
widget is returned.
Finally, the child
property takes a widget that will be the child of the widget returned by the builder. In this code, it is an Image widget. The TweenAnimationBuilder, in combination with the other properties, creates a smooth and elegant animation that is easy to understand and customize.
TweenAnimationBuilder(
tween: Tween<double>(begin: 0, end: _angle * _speed),
duration: _duration,
curve: Curves.easeInOut,
builder: (BuildContext context, double angle, Widget? child) {
return Transform.rotate(
angle: angle,
child: child,
);
},
child: Image.network(
'https://via.placeholder.com/200x200',
),
),
ElevatedButton is used to trigger the animation by calling the _onPressed function. The button takes a child property that displays the text “Rotate” on the button. The onPressed property is set to the _onPressed function, which updates the animation whenever the button is pressed. This allows the user to manually control the rotation of the image.
ElevatedButton(
onPressed: _onPressed,
child: Text('Rotate'),
),
Another example of Flutter AnimatedBuilder to rotate an Image
The code below is another example of how to use the AnimatedBuilder widget to rotate the container with an image:
import 'dart:math';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin{
double _angle = 0;
Duration _duration = Duration(seconds: 1);
late AnimationController _controller;
@override
void initState() {
_controller = AnimationController(
vsync: this,
duration: _duration,
);
super.initState();
}
void _onPressed() {
setState(() {
_controller.reset();
_controller.forward();
_angle = 2 * pi * new Random().nextDouble();
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('flutterassets.com'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
AnimatedBuilder(
animation: _controller,
builder: (context, child) => Transform.rotate(
angle: _angle * _controller.value,
child: child,
),
child: Image.network(
'https://via.placeholder.com/200x200',
),
),
ElevatedButton(
onPressed: _onPressed,
child: Text('Rotate'),
),
],
),
),
);
}
}
Variables:
In the code, there are three variables:
double _angle = 0;
Duration _duration = Duration(seconds: 1);
late AnimationController _controller;
_angle
is a double variable that holds the angle of rotation._duration
is aDuration
variable that holds the duration of the animation. It’s set to 1 second._controller
is anAnimationController
object. This class controls the animation of a widget.
void initState():
@override
void initState() {
_controller = AnimationController(
vsync: this,
duration: _duration,
);
super.initState();
}
initState
is a method that is called when the widget is created. In this method, we initialize _controller
object and set its vsync
property to the widget and duration
property to _duration
(1 second).
void _onPressed():
void _onPressed() {
setState(() {
_controller.reset();
_controller.forward();
_angle = 2 * pi * new Random().nextDouble();
});
}
_onPressed
is a method that is called when the button is pressed. In this method, we use setState
to reset the animation controller, start the animation and set the angle of rotation to a random value between 0 and 2 * pi.
build:
In the build
method, we return a Scaffold
widget. The Scaffold
is the basic layout structure in Flutter that provides a default AppBar, body, and floating action button. We set the title of the app bar to flutterassets.com
. The body of the Scaffold
is a Center
widget that holds a Column
widget. The Column
widget contains two children: an AnimatedBuilder
and an ElevatedButton
.
AnimatedBuilder(
animation: _controller,
builder: (context, child) => Transform.rotate(
angle: _angle * _controller.value,
child: child,
),
child: Image.network(
'https://via.placeholder.com/200x200',
),
),
The AnimatedBuilder
widget is used to animate its child. In the AnimatedBuilder
, animation
property is set to _controller
so the child will be animated based on the _controller
. In the builder
property, we return a Transform.rotate
widget. The Transform.rotate
widget rotates its child by an angle given in the angle
property.
The value of the angle is set as _angle * _controller.value. This means that the angle of rotation is equal to the product of _angle and _controller.value. The child of Transform.rotate widget is set to the child of AnimatedBuilder which is an Image widget with an image loaded from a URL.
ElevatedButton(
onPressed: _onPressed,
child: Text('Rotate'),
),
The ElevatedButton widget is a Material Design button that is used to trigger the animation. When the button is pressed, the _onPressed
function is executed. This function resets the _controller
and starts it again by calling _controller.forward()
. It also calculates a random angle _angle
that the image will be rotated by. Finally, it calls the setState
function, which tells Flutter to re-render the widget tree and display the rotated image.
In summary, this code rotates an image in response to a button press by using an AnimationController and the AnimatedBuilder widget.