matrix4_transform 1.1.1

  • Readme
  • Changelog
  • Example
  • Installing
  • 84

pub package

matrix4_transform #

Have you noticed the transform parameter in the Container and Transform widgets, that let you move, rotate, resize and flip?

This package is a helper math class that makes it easy to create Matrix4 transformations.

alt text

Example:

// Rotates the Container 45 degrees and then
// translates 25 pixels to the right. 
Container(
   transform:
     Matrix4Transform()
       .rotateDegrees(45, origin: Offset(25, 25))
       .translate(x: 25)
       .matrix4,
   child: ...
);

To see it in action, run the example in the example tab.

How to use it #

Matrix4Transform is immutable (in contrast, Matrix4 is mutable).

First create a Matrix4Transform:

Matrix4Transform();

Then call the methods to transform it. For example:

Matrix4Transform()
   .scale(1.5)
   .upRight(35)
   .rotate(pi/2);
   

In the end, call matrix4:

Matrix4 myMatrix 
   = Matrix4Transform()
     .scale(1.5)
     .upRight(35)
     .rotate(pi/2)
     .matrix4;                        
   

Note: The transformations will be applied in order, and their order may change the end result.

If you already have a matrix4 and want to further transform it, you can use the from constructor:

Matrix4 myMatrix = ...;

var myTransform = Matrix4Transform.from(myMatrix);

Methods you can use #

  • rotate(double angleRadians, {Offset origin})
  • rotateDegrees(double angleDegrees, {Offset origin})
  • rotateByCenterDegrees(double angleDegrees, Size size)
  • rotateByCenter(_toRadians(angleDegrees), size)
  • translate({double x = 0, double y = 0})
  • translateOriginalCoordinates({double x = 0, double y = 0})
  • scale(double factor, {Offset origin})
  • scaleBy({double x = 1, double y = 1, Offset origin})
  • scaleHorizontally(double factor)
  • scaleVertically(double factor)
  • translateOffset(Offset offset)
  • up(double distance)
  • down(double distance)
  • right(double distance)
  • left(double distance)
  • direction(double directionRadians, double distance)
  • directionDegrees(double directionDegrees, double distance)
  • upRight(double distance)
  • upLeft(double distance)
  • downRight(double distance)
  • downLeft(double distance)
  • flipDiagonally({Offset origin})
  • flipHorizontally({Offset origin})
  • flipVertically({Offset origin})

And, of course:

  • Matrix4 toMatrix4

Tween #

A Matrix4TransformTween is provided in this package, and can be used in animations.

Animate it #

A Matrix4Transform can be used to animate:

  • AlignPositioned or AnimatedAlignPositioned widgets from the AlignPositioned package, that accept a Matrix4Transform directly. The center of rotation/scale can be defined by their alignment parameter.

  • Any widget that accepts a Matrix4 transformation parameter, like Container, or AnimatedContainer. Note: Since Matrix4Tween will not animate linearly as you'd expect, it's possible that the intermediary transformations will be "strange", although the start and end should be correct.


Special thanks to Martin Kamleithner and Simon Lightfoot.

The Flutter packages I've authored:

---
Marcelo Glasberg:
https://github.com/marcglasberg
https://twitter.com/glasbergmarcelo
https://stackoverflow.com/users/3411681/marcg
https://medium.com/@marcglasberg

[1.1.1] - 2019/09/23

  • FlipDiagonally, flipHorizontally, and flipVertically.

[1.1.0] - 2019/09/06

  • Fixed missing Offset in scale.

[1.0.9] - 2019/08/24

  • Matrix4TransformTween.

[1.0.4] - 2019/08/22

  • Docs change.

[1.0.0] - 2019/08/22

  • Initial commit.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:matrix4_transform/matrix4_transform.dart';

// Developed by Marcelo Glasberg (Aug 2019).
// For more info, see: https://pub.dartlang.org/packages/matrix4_transform

void main() async => runApp(MaterialApp(home: Demo()));

class Demo extends StatelessWidget {
  final boxes = [
    Box(null, "Original"),
    Box(Matrix4Transform().translate(x: 25).matrix4, ".translate(x: 25)"),
    Box(Matrix4Transform().rotateDegrees(20).matrix4, ".rotateDegrees(20)"),
    Box(Matrix4Transform().rotateDegrees(45).matrix4, ".rotateDegrees(45)"),
    Box(Matrix4Transform().rotateDegrees(20, origin: Offset(25, 25)).matrix4,
        ".rotateDegrees(20, origin: Offset(25, 25))"),
    Box(Matrix4Transform().rotateDegrees(45, origin: Offset(25, 25)).matrix4,
        ".rotateDegrees(45, origin: Offset(25, 25))"),
    Box(Matrix4Transform().rotateDegrees(45, origin: Offset(25, 25)).translate(x: 25).matrix4,
        ".rotateDegrees(45, origin: Offset(25, 25)).\ntranslate(x: 25)"),
    Box(Matrix4Transform().scaleBy(x: 2.0, y: 0.5).matrix4, ".scaleBy(x: 2.0, y: 0.5)"),
    Box(Matrix4Transform().scaleBy(x: 2.0, y: 0.5, origin: Offset(25, 25)).matrix4,
        ".scaleBy(x: 2.0, y: 0.5, origin: Offset(25, 25))"),
    Box(Matrix4Transform().scaleBy(x: 2, y: 0.5, origin: Offset(25, 25)).right(25).matrix4,
        ".scaleBy(x: 2, y: 0.5, origin: Offset(25, 25))\n.right(25)"),
    Box(
        Matrix4Transform()
            .scaleBy(x: 2, y: 0.5, origin: Offset(25, 25))
            .translateOriginalCoordinates(x: 25)
            .matrix4,
        ".scaleBy(x: 2, y: 0.5, origin: Offset(25, 25))\n.translateOriginalCoordinates(x: 25)"),
    //
    Box(Matrix4Transform().flipHorizontally().matrix4, ".flipHorizontally()"),
    Box(Matrix4Transform().flipHorizontally(origin: Offset(25, 25)).matrix4,
        ".flipHorizontally(origin: Offset(25, 25))"),
    Box(Matrix4Transform().flipVertically().matrix4, ".flipVertically()"),
    Box(Matrix4Transform().flipVertically(origin: Offset(25, 25)).matrix4,
        ".flipVertically(origin: Offset(25, 25))"),
    Box(Matrix4Transform().flipDiagonally().matrix4, ".flipDiagonally())"),
    Box(Matrix4Transform().flipDiagonally(origin: Offset(25, 25)).matrix4,
        ".flipDiagonally(origin: Offset(25, 25))"),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Matrix4Transform Example')),
      body: Stack(
        children: <Widget>[
          SingleChildScrollView(
            child: Container(
              color: Colors.grey[400],
              child: Column(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  for (var box in boxes) wrap(box),
                ],
              ),
            ),
          ),
          Center(
            child: Container(
              width: 50,
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  Container(width: 1.5, height: double.infinity, color: Colors.black),
                  Container(width: 0.75, height: double.infinity, color: Colors.black26),
                  Container(width: 1.0, height: double.infinity, color: Colors.black26),
                ],
              ),
            ),
          ),
        ],
      ),
    );
  }
}

Widget wrap(Box box) {
  return Column(
    children: <Widget>[
      if (box.description != null)
        Align(
          alignment: Alignment.centerLeft,
          child: Text(box.description.toString(), style: TextStyle(fontSize: 11)),
        ),
      Container(height: 1.5, width: double.infinity, color: Colors.black),
      Container(child: box, alignment: Alignment.center, height: 50, width: double.infinity),
      Container(height: 1.0, width: double.infinity, color: Colors.black26),
      SizedBox(height: 70.0),
    ],
  );
}

class Box extends StatelessWidget {
  final Matrix4 matrix;
  final String description;

  Box(
    Matrix4 matrix,
    this.description,
  ) : matrix = matrix ?? Matrix4.identity();

  @override
  Widget build(BuildContext context) {
    return Container(
      transform: matrix,
      color: Colors.red,
      width: 50,
      height: 50,
      child: Center(
        child: Stack(
          children: [
            Icon(Icons.cancel, color: Colors.yellow, size: 38),
            Icon(Icons.expand_less, color: Colors.yellow, size: 38),
            Icon(Icons.add_circle, color: Colors.yellow, size: 10),
          ],
        ),
      ),
    );
  }
}

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  matrix4_transform: ^1.1.1

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter pub get

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:matrix4_transform/matrix4_transform.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
68
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100
Overall:
Weighted score of the above. [more]
84
Learn more about scoring.

We analyzed this package on Oct 16, 2019, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.5.1
  • pana: 0.12.21
  • Flutter: 1.9.1+hotfix.4

Platforms

Detected platforms: Flutter

References Flutter, and has no conflicting libraries.

Health suggestions

Format lib/matrix4_transform.dart.

Run flutter format to format lib/matrix4_transform.dart.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.1.0 <3.0.0
flutter 0.0.0
Transitive dependencies
collection 1.14.11 1.14.12
meta 1.1.7
sky_engine 0.0.99
typed_data 1.1.6
vector_math 2.0.8
Dev dependencies
flutter_test