可容纳一个子组件,可以通过一个4*4的变换矩阵对子组件进行变换。

相关组件
Container

斜切变换skew

  1. <br />斜切x由R0C1数控制,入参为弧度值,表示斜切角度<br />斜切y由R1C0数控制,入参为弧度值,表示斜切角度<br />![174.gif](https://cdn.nlark.com/yuque/0/2020/gif/326147/1589462243860-8d483713-b703-4601-8f12-a0d6e9e758ec.gif#align=left&display=inline&height=410&margin=%5Bobject%20Object%5D&name=174.gif&originHeight=410&originWidth=786&size=3547439&status=done&style=none&width=786)
import 'dart:math';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'matrix4_shower.dart';
class SkewTransform extends StatefulWidget {
  @override
  _SkewTransformState createState() => _SkewTransformState();
}

class _SkewTransformState extends State<SkewTransform> {
  Matrix4 _m4;
  double _alpha = 0;
  double _beta = 0;

  @override
  void initState() {
    _m4 = Matrix4.identity();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        Row(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: <Widget>[_buildTransform(), Matrix4Shower(_m4)],
        ),
        _buildSliders()
      ],
    );
  }

  Widget _buildTransform() {
    _m4 = Matrix4.skew(_alpha, _beta);
    return Transform(
      transform: _m4,
      child: Container(
          color: Colors.cyanAccent,
          width: 100,
          height: 100,
          child: Image.asset(
            'assets/images/wy_300x200.jpg',
            fit: BoxFit.cover,
          )),
    );
  }

  Widget _buildSliders() => Column(
        children: <Widget>[
          Slider(
              min: -pi,
              max: pi,
              value: _alpha,
              divisions: 360,
              label: 'alpha:' + (_alpha * 180 / pi).toStringAsFixed(1) + "°",
              onChanged: (v) {
                setState(() {
                  _alpha = v;
                });
              }),
          Slider(
              min: -pi,
              max: pi,
              value: _beta,
              divisions: 360,
              label: 'beta:' + (_beta * 180 / pi).toStringAsFixed(1) + "°",
              onChanged: (v) {
                setState(() {
                  _beta = v;
                });
              })
        ],
      );
}

平移变换translationValues

   <br />平移x由R0C3数控制,入参为数值,表示平移长度<br />平移y由R1C3数控制,入参为数值,表示平移长度<br />平移z由R2C3数控制,入参为数值,表示平移长度<br />![175.gif](https://cdn.nlark.com/yuque/0/2020/gif/326147/1589462318124-8b52d273-6ea5-48e1-9659-6d8325f92ec6.gif#align=left&display=inline&height=616&margin=%5Bobject%20Object%5D&name=175.gif&originHeight=616&originWidth=786&size=3593192&status=done&style=none&width=786)
import 'package:flutter/material.dart';
import 'matrix4_shower.dart';
class TranslationTransform extends StatefulWidget {
  @override
  _TranslationTransformState createState() => _TranslationTransformState();
}

class _TranslationTransformState extends State<TranslationTransform> {
  Matrix4 _m4;
  double _x = 0;
  double _y = 0;
  double _z = 0;

  @override
  void initState() {
    _m4 = Matrix4.identity();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        Row(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: <Widget>[_buildTransform(), Matrix4Shower(_m4)],
        ),
        _buildSliders()
      ],
    );
  }

  Widget _buildTransform() {
    _m4 = Matrix4.translationValues(_x, _y, _z);
    return Transform(
      transform: _m4,
      child: Container(
          color: Colors.cyanAccent,
          width: 100,
          height: 100,
          child: Image.asset(
            'assets/images/wy_300x200.jpg',
            fit: BoxFit.cover,
          )),
    );
  }

  Widget _buildSliders() => Column(
    children: <Widget>[
      Slider(
          min: -100,
          max: 100,
          value: _x,
          divisions: 360,
          label: 'x:${_x.toStringAsFixed(1)}',
          onChanged: (v) {
            setState(() {
              _x = v;
            });
          }),
      Slider(
          min: -100,
          max: 100,
          value: _y,
          divisions: 360,
          label: 'y:${_y.toStringAsFixed(1)}',
          onChanged: (v) {
            setState(() {
              _y = v;
            });
          }),
      Slider(
          min: -100,
          max: 100,
          value: _z,
          divisions: 360,
          label: 'z:${_z.toStringAsFixed(1)}',
          onChanged: (v) {
            setState(() {
              _z = v;
            });
          })
    ],
  );
}

缩放变换diagonal3Values

   <br />缩放x由R0C0数控制,入参为数值,表示缩放分率<br />缩放y由R1C2数控制,入参为数值,表示缩放分率<br />缩放z由R2C2数控制,入参为数值,表示缩放分率<br />![176.gif](https://cdn.nlark.com/yuque/0/2020/gif/326147/1589462374327-af67aff9-33d1-488a-a1f7-579ea178947f.gif#align=left&display=inline&height=522&margin=%5Bobject%20Object%5D&name=176.gif&originHeight=522&originWidth=786&size=2188726&status=done&style=none&width=786)
import 'package:flutter/material.dart';
import 'matrix4_shower.dart';
class ScaleTransform extends StatefulWidget {
  @override
  _ScaleTransformState createState() => _ScaleTransformState();
}

class _ScaleTransformState extends State<ScaleTransform> {
  Matrix4 _m4;
  double _x = 1.0;
  double _y = 1.0;
  double _z = 1.0;

  @override
  void initState() {
    _m4 = Matrix4.identity();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        Row(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: <Widget>[_buildTransform(), Matrix4Shower(_m4)],
        ),
        _buildSliders()
      ],
    );
  }

  Widget _buildTransform() {
    _m4 = Matrix4.diagonal3Values(_x, _y, _z);
    return Transform(
      transform: _m4,
      child: Container(
          color: Colors.cyanAccent,
          width: 100,
          height: 100,
          child: Image.asset(
            'assets/images/wy_300x200.jpg',
            fit: BoxFit.cover,
          )),
    );
  }

  Widget _buildSliders() => Column(
    children: <Widget>[
      Slider(
          min: -2,
          max: 2,
          value: _x,
          divisions: 360,
          label: 'x:${_x.toStringAsFixed(1)}',
          onChanged: (v) {
            setState(() {
              _x = v;
            });
          }),
      Slider(
          min: -2,
          max: 2,
          value: _y,
          divisions: 360,
          label: 'y:${_y.toStringAsFixed(1)}',
          onChanged: (v) {
            setState(() {
              _y = v;
            });
          }),
      Slider(
          min: -2,
          max: 2,
          value: _z,
          divisions: 360,
          label: 'z:${_z.toStringAsFixed(1)}',
          onChanged: (v) {
            setState(() {
              _z = v;
            });
          })
    ],
  );
}

旋转变换rotation

   <br />x旋转由R1C1、R1C2、R2C1、R2C2控制,入参表示弧度<br />y旋转由R0C0、R0C2、R2C0、R2C2控制,入参表示弧度<br />z旋转由R0C0、R0C1、R1C0、R1C1控制,<br />![177.gif](https://cdn.nlark.com/yuque/0/2020/gif/326147/1589462430534-e7ad9d64-f1b3-4e22-be1d-77b02c2ecda2.gif#align=left&display=inline&height=436&margin=%5Bobject%20Object%5D&name=177.gif&originHeight=436&originWidth=786&size=3119049&status=done&style=none&width=786)
import 'dart:math';
import 'package:flutter/material.dart';
import 'matrix4_shower.dart';
class RotateTransform extends StatefulWidget {
  @override
  _RotateTransformState createState() => _RotateTransformState();
}

class _RotateTransformState extends State<RotateTransform> {
  Matrix4 _m4;
  double _x = 0;
  int _rotateFlag = 1;

  @override
  void initState() {
    _m4 = Matrix4.identity();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        Row(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: <Widget>[_buildTransform(), Matrix4Shower(_m4)],
        ),
        _buildSliders()
      ],
    );
  }

  Widget _buildTransform() {
    if (_rotateFlag == 1) {
      _m4 = Matrix4.rotationX(_x);
    } else if (_rotateFlag == 2) {
      _m4 = Matrix4.rotationY(_x);
    } else {
      _m4 = Matrix4.rotationZ(_x);
    }

    return Transform(
      transform: _m4,
      child: Container(
          color: Colors.cyanAccent,
          width: 100,
          height: 100,
          child: Image.asset(
            'assets/images/wy_300x200.jpg',
            fit: BoxFit.cover,
          )),
    );
  }

  final Map<int, String> map = {
    1: 'rotationX',
    2: 'rotationY',
    3: 'rotationZ',
  };

  Widget _buildSliders() => Column(
    children: <Widget>[
      Wrap(
        children: map.keys.map((key) => _buildChild(key)).toList(),
      ),
      Slider(
          min: -pi,
          max: pi,
          value: _x,
          divisions: 360,
          label: 'x:${_x.toStringAsFixed(1)}',
          onChanged: (v) {
            setState(() {
              _x = v;
            });
          }),
    ],
  );

  Padding _buildChild(int key) {
    return Padding(
      padding: const EdgeInsets.all(4.0),
      child: FilterChip(
        selectedColor: Colors.orange.withAlpha(55),
        selectedShadowColor: Colors.blue,
        shadowColor: Colors.orangeAccent,
        pressElevation: 5,
        elevation: 3,
        avatar: CircleAvatar(child: Text(key.toString())),
        label: Text(map[key]),
        selected: _rotateFlag == key,
        onSelected: (bool value) {
          print(map[key]);
          setState(() {
            _x = 0;
            if (value) {
              _rotateFlag = key;
            }
          });
        },
      ),
    );
  }
}

透视变换rotation

   <br />由R3C1、R3C2、R3C3控制透视<br />![178.gif](https://cdn.nlark.com/yuque/0/2020/gif/326147/1589462487281-c244e73c-cb07-456c-897d-2ef8405c4f53.gif#align=left&display=inline&height=436&margin=%5Bobject%20Object%5D&name=178.gif&originHeight=436&originWidth=786&size=2849759&status=done&style=none&width=786)
import 'dart:math';
import 'package:flutter/material.dart';
class R3C2 extends StatefulWidget {
  @override
  _R3C2State createState() => _R3C2State();
}

class _R3C2State extends State<R3C2> {
  Matrix4 _m4;
  double _value = 0;
  double _rad = 0;

  @override
  Widget build(BuildContext context) {
    _m4 = Matrix4.identity()
//      ..setEntry(3, 0, _value) // x
//      ..setEntry(3, 1, _value)//   y
      ..setEntry(3, 2, _value) // z
      ..rotateY(_rad)
//      ..rotateX(_rad)
        ;
    return Column(
      children: <Widget>[
        Transform(
          transform: _m4,
          child: Container(
              color: Colors.cyanAccent,
              width: 100,
              height: 100,
              child: Image.asset(
                'assets/images/wy_300x200.jpg',
                fit: BoxFit.cover,
              )),
        ),
        _buildSliders()
      ],
    );
  }

  Widget _buildSliders() => Column(
    children: <Widget>[
      Slider(
          min: -0.01,
          max: 0.01,
          value: _value,
          divisions: 360,
          label: 'x:${_value.toStringAsFixed(5)}',
          onChanged: (v) {
            setState(() {
              _value = v;
            });
          }),
      Slider(
          min: -pi,
          max: pi,
          value: _rad,
          divisions: 360,
          label: '角度:' + (_rad * 180 / pi).toStringAsFixed(1) + "°",
          onChanged: (v) {
            setState(() {
              _rad = v;
            });
          }),
    ],
  );
}