Transform widget in Flutter

Transform widget in Flutter

Animations are important in the software world. They help to emphasize important things or actions and make them more attractive. But today we will talk about a widget called Transform which is often used with Animations. It helps to change the shape, position or rotation of the child widget.

Transform widget has 4 main constructors:

  1. rotate(…)
  2. scale(…)
  3. translate(…)
  4. transform(…)

Rotate

As the name suggests Transform.rotate simply rotates the child widget by the given angle. Secondary parameter is the origin. By default, the widget rotates around its center – default origin. This parameter accepts Offset which defines the distance from the center of the widget.

Here is Container rotated by 45 degrees angle.

 

 

Transform.rotate(
  angle: pi / 4,
  child: Container(
    color: Colors.amber,
    width: 100,
    height: 100,
  ),
)

Watch a video to see the result of applying origin parameter in action. Variable _value is updating by animation from 0 to 1.

 


Transform.rotate(
  origin: Offset(-50, -50),
  angle: pi * 2 * _value,
  child: Container(
    color: Colors.amber,
    width: 100,
    height: 100,
  ),
)

Container size is 100×100 and Offset is (-50, -50). This code rotates a container around the top left corner.

 

Scale

Scale constructor scales the child by the given factor. We set animation _value from 0.5 to 1. Scale parameter = 0.5 means reducing the size of the child by half.

See what happens:

<iframe src=”https://drive.google.com/file/d/172AmdmfrtsJoG_w1HvuV9QDix3PeczP5/preview” width=”640″ height=”480″></iframe>

 

Transform.scale(
 scale: _value,
 child: Container(
   color: Colors.amber,
   width: 100,
   height: 100,
 ),
)

 

This constructor also has origin parameter. Like the last example, let’s also set Offset to the top left corner and see what happens:

 

 

Transform.scale(
 scale: _value,
 origin: Offset(-50, -50),
 child: Container(
   color: Colors.amber,
   width: 100,
   height: 100,
 ),
)

 

Translate

Transform.translate moves the child widget by Offset in X and Y direction. There is no origin parameter in this constructor.

Here we move a container from one screen side to another by supplying X coordinate and animating it.

 

 

final containerWidth = 100;
final translateOffset = MediaQuery.of(context).size.width - containerWidth;

Transform.translate(
 offset: Offset(translateOffset * _value, 0),
 child: Container(
   color: Colors.amber,
   width: 100,
   height: 100,
 ),
)

 

Default constructor

This type of transform allows us to do multiple transformations at once.  It takes a 4×4 matrix in the transform parameter also called transformation matrix.

 

Below we can see an example, which skews our Container around the Y axis by 0.3 and origin in the center of the widget.

 

 

Transform(
 transform: Matrix4.skewY(0.3),
 origin: Offset(0, 0),
 child: Container(
   width: 200,
   height: 200,
   color: Colors.amber,
 ),
)

 

Here is what we can achieve with multiple Matrix transformations.

 


Transform(
 transform: Matrix4.identity()
   ..setEntry(3, 2, 0.003)
   ..rotateX(pi * 2 * _value),
 origin: Offset(50, 50),
 child: Container(
   color: Colors.red,
   width: 100,
   height: 100,
   child: Center(
     child: _value <= 0.25 || _value >= 0.75
         ? Text(
             'Sceel.io',
             style: TextStyle(
                 color: Colors.white,
                 fontWeight: FontWeight.w500,
                 fontSize: 18
             ),
           )
         : SizedBox(),
   ),
 ),
)

 

Parameter _value is changing between 0 and 1. By calling the identity() function we initialize our matrix with ones on the main diagonal and zeroes elsewhere. The next step is setting entry on the third row and second column to implement perspective. Perspective makes objects that are farther away appear smaller. It is hard to say what means 0.003, you should play with this number to see different results. Then we apply rotation around the X axis. Despite previous constructors, the origin is located in the top left corner by default, so we set Offset(50, 50) for Transform to move it to the center.

 

Obviously, there are 2 other functions for Y and Z axis: rotateY() and rotateZ(). Furthermore, Matrix4 has such functions:

  • scale(x, [y, z]) – where x parameter is required but other axis are optional. With this method we can scale our widget separately by each axis;
  • translate(x, [y, z]) moves the widget, as we did with translate(…) constructor, but allows to manipulate in 3 dimensions.

 

One thing to remember – in Flutter everything is a widget. Therefore, you can Transform them all, even the whole app. This gives developers the ability to create beautiful and powerful effects, especially if Transform widget with Animation combined.