Flutter 44: 图解矩阵变换 Transform 类 (

作者: 阿策神奇 | 来源:发表于2019-05-14 23:53 被阅读26次

          小菜在学习矩阵变换时需要用到 Transform 类,可以实现子 Widgetscale 缩放 / translate 平移 / rotate 旋转 / skew 斜切 等效果,对应于 Canvas 绘制过程中的矩阵变换等;小菜今对此进行初步整理;

    scale 缩放

          scale 缩放 可以通过 Transform 提供的构造方法或 Matrix4 矩阵变化来实现;

    Transform.scale 构造方法

    Transform.scale({
        Key key,
        @required double scale,     // 缩放比例
        this.origin,    // 缩放原点
        this.alignment = Alignment.center,  // 对齐方式
        this.transformHitTests = true,
        Widget child,
    }) : transform = Matrix4.diagonal3Values(scale, scale, 1.0),
        super(key: key, child: child);
    

    Tips:

    1. 设置缩放比例后,水平/竖直方向按同比例缩放,z 轴方向不缩放;
    2. 对齐方式是与初始位置为准;
    Center(
        child: Transform.scale(
            scale: 1.2,
    //      origin: Offset(120.0, 120.0),
            alignment: Alignment.bottomRight,
            child: ClipOval(
                child: SizedBox(
                    width: 120.0,
                    height: 80.0,
                    child: Container(
                        color: Colors.blueAccent))))),
    

    Transform Matrix4 方式

    void scale(dynamic x, [double y, double z]) {}
    

          Matrix44D 矩阵,使用更灵活,可以分别设置 x / y / z 轴方向缩放比例;若只设置一个则水平/垂直方向同比例缩放;

    Center(
        child: Transform(
            transform: Matrix4.identity()
              ..scale(1.2, 1.0, 0.5),
            alignment: Alignment.bottomRight,
            child: ClipOval(
                child: SizedBox(
                    width: 120.0,
                    height: 80.0,
                    child: Container(
                        color: Colors.blueAccent)))))
    

    translate 平移

          translate 平移 可通过构造方法或 Matrix4 矩阵变化来实现;

    Transform.translate 构造方法

    Transform.translate({
        Key key,
        @required Offset offset,
        this.transformHitTests = true,
        Widget child,
    }) : transform = Matrix4.translationValues(offset.dx, offset.dy, 0.0),
        origin = null,
        alignment = null,
        super(key: key, child: child);
    

          translate 按坐标点 Offset 平移,水平向右为正向,竖直向下为正向;z 轴方向不平移;

    Center(
        child: Transform.translate(
            offset: Offset(60.0, -40.0),
            child: ClipOval(
                child: SizedBox(
                    width: 120.0,
                    height: 80.0,
                    child: Container(
                        color: Colors.blueAccent))))),
    

    Transform Matrix4 方式

    void translate(dynamic x, [double y = 0.0, double z = 0.0]) {}
    

          Matrix4 平移方式可分别设置 x / y / z 轴方向平移量,必须设置 x 轴方向平移量;

    Center(
        child: Transform(
            transform: Matrix4.identity()
              ..translate(60.0, -40.0, 100.0),
            alignment: Alignment.bottomRight,
            child: ClipOval(
                child: SizedBox(
                    width: 120.0,
                    height: 80.0,
                    child: Container(
                        color: Colors.blueAccent))))),
    

    rotate 旋转

          rotate 旋转可通过构造方法或 Matrix4 矩阵变化来实现;

    Taransform.rotate 构造方法

    Transform.rotate({
        Key key,
        @required double angle,     // 旋转角度
        this.origin,
        this.alignment = Alignment.center,
        this.transformHitTests = true,
        Widget child,
    }) : transform = Matrix4.rotationZ(angle),
           super(key: key, child: child);
    

          由此可看出旋转是沿 z 轴旋转,即垂直手机屏幕方向,视觉上的正常旋转;

    Center(
        child: Transform.rotate(
            angle: pi / 4,
            child: ClipOval(
                child: SizedBox(
                    width: 120.0,
                    height: 80.0,
                    child: Container(
                        color: Colors.blueAccent))))),
    

    Transform Matrix4 方式

    void rotate(Vector3 axis, double angle) {}
    

          Matrix4 可灵活设置旋转方向,包括沿 x / y / z 轴方向立体旋转,且旋转效果可以重叠;而 Matrix4 也提供了两种旋转方式;

    1. Matrix4.rotationZ
    2. Matrix4.identity()..rotateZ

          对于单轴旋转,两种方式实际是完全相同的,且第一种方式只可进行单轴旋转;第二种方式更灵活,可以多个轴叠加;

    Center(
        child: Transform(
            transform: Matrix4.rotationZ(pi / 4),
            alignment: Alignment.center,
            child: ClipOval(
                child: SizedBox(
                    width: 120.0,
                    height: 80.0,
                    child: Container(
                        color: Colors.blueAccent))))),
    Center(
        child: Transform(
            transform: Matrix4.identity()..rotateX(pi / 4),
            alignment: Alignment.center,
            child: ClipOval(
                child: SizedBox(
                    width: 120.0,
                    height: 80.0,
                    child: Container(
                        color: Colors.greenAccent))))),
    Center(
        child: Transform(
            transform: Matrix4.identity()..rotateY(pi / 4),
            alignment: Alignment.center,
            child: ClipOval(
                child: SizedBox(
                    width: 120.0,
                    height: 80.0,
                    child: Container(color: Colors.brown))))),
    Center(
        child: ClipOval(
            child: SizedBox(
                width: 120.0,
                height: 80.0,
                child: Container(color: Colors.black12))))
    

    skew 斜切

          Transform 未提供关于 skew 斜切的构造方法,只能用 Matrix4 方式构建;

    1. skewX 沿水平方向斜切;
    2. skewY 沿竖直方向斜切;
    3. skewx / y 轴共同矩阵转换产生斜切;
    Center(
        child: Transform(
            transform: Matrix4.skewY(pi / 4),
            alignment: Alignment.topLeft,
            child: Container(
                width: 120.0,
                height: 80.0,
                color: Colors.brown))),
    Center(
        child: Transform(
            transform: Matrix4.skewX(pi / 4),
            alignment: Alignment.topLeft,
            child: Container(
                width: 120.0,
                height: 80.0,
                color: Colors.redAccent))),
    Center(
        child: Transform(
            transform: Matrix4.skew(pi / 6, pi / 6),
            alignment: Alignment.topLeft,
            child: Container(
                width: 120.0,
                height: 80.0,
                color: Colors.white70))),
    Center(
        child: Transform(
            transform: Matrix4.skew(0.0, 0.0),
            alignment: Alignment.topLeft,
            child: Container(
                width: 120.0,
                height: 80.0,
                color: Colors.black12))),
    

          所有的矩阵变换均可通过 Matrix4 叠加,在实际应用中更加灵活,下节会重点学习 Matrix4 矩阵方面的小知识点;


          如有错误请多多指导,以下是小菜公众号,欢迎闲来吐槽~


    公众号

    相关文章

      网友评论

        本文标题:Flutter 44: 图解矩阵变换 Transform 类 (

        本文链接:https://www.haomeiwen.com/subject/whmjaqtx.html