Flutter:如何移动,旋转和缩放容器?

时间:2019-03-18 10:46:35

标签: flutter rotation zoom gesture pan

我想制作一个可以拖动,缩放和旋转的容器。我能够实现变焦。下面是我的代码:

//variable declaration
  double _scale = 1.0;
  double _previousScale;
  var yOffset = 400.0;
  var xOffset = 50.0;
  var rotation = 0.0;
  var lastRotation = 0.0;

//构建方法

@override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Center(
          child: GestureDetector(
            onScaleStart: (scaleDetails) {
              _previousScale = _scale;
              print(' scaleStarts = ${scaleDetails.focalPoint}');
            },
            onScaleUpdate: (scaleUpdates){
              //ScaleUpdateDetails
              rotation += lastRotation - scaleUpdates.rotation;
              lastRotation = scaleUpdates.rotation;
              print("lastRotation = $lastRotation");
              print(' scaleUpdates = ${scaleUpdates.scale} rotation = ${scaleUpdates.rotation}');
              setState(() => _scale = _previousScale * scaleUpdates.scale);
            },
            onScaleEnd: (scaleEndDetails) {
              _previousScale = null;
              print(' scaleEnds = ${scaleEndDetails.velocity}');
            },
            child:
            Transform(
              transform: Matrix4.diagonal3( Vector3(_scale, _scale, _scale))..rotateZ(rotation * math.pi/180.0),
              alignment: FractionalOffset.center,
              child: Container(
                height: 200.0,
                width: 200.0,
                color: Colors.red,
              ),
            )
            ,
          ),
        ),
      ),
    );
  }

当前,没有旋转,我无法移动容器。

4 个答案:

答案 0 :(得分:2)

使用matrix_gesture_detector软件包,这里有基本示例:

MatrixGestureDetector(
  onMatrixUpdate: (m, tm, sm, rm) {
    setState(() {
      matrix = n;
    });
  },
  child: Transform(
    transform: matrix,
    child: ....
  ),
),

有关更多示例代码,请参见包含6个演示的example文件夹

答案 1 :(得分:0)

您也可以使用photo_viewer代替matrix_gesture_detector。有关此答案的更多信息:https://stackoverflow.com/a/62426232/2942294

答案 2 :(得分:0)

您可以使用 RotatedBox 小部件(用于旋转)以及 InteractiveViewer 小部件(用于放大和缩小)。

用于移动容器的InteractiveViewer小部件中的

panEnabled属性

Scaffold(
    backgroundColor: Colors.black,
    body: Center(
      child: RotatedBox(
        quarterTurns: 1,
        child: InteractiveViewer(
          boundaryMargin: EdgeInsets.zero,
          minScale: 1,
          maxScale: 4,
          child: Container(
            height: 200,
            width: 200,
            color: Colors.blue,
          ),
        ),
      ),
    ),
  ),

答案 3 :(得分:0)

我有同样的问题。该问题由 Matrix 手势检测器包解决。但我已经通过另一个案例解决了这个问题:- 整个代码在这里。

// @dart=2.9
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({Key key}) : super(key: key);

  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomePage(),
    );
  }
}

class ContainerList {
  double height;
  double width;
  double scale;
  double rotation;
  double xPosition;
  double yPosition;

  ContainerList({
    this.height,
    this.rotation,
    this.scale,
    this.width,
    this.xPosition,
    this.yPosition,
  });
}

class HomePage extends StatefulWidget {
  const HomePage({Key key}) : super(key: key);

  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  List<ContainerList> list = [];
  Offset _initPos;
  Offset _currentPos = Offset(0, 0);
  double _currentScale;
  double _currentRotation;
  Size screen;

  @override
  void initState() {
    screen = Size(400, 500);
    list.add(ContainerList(
      height: 200.0,
      width: 200.0,
      rotation: 0.0,
      scale: 1.0,
      xPosition: 0.1,
      yPosition: 0.1,
    ));
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Container(
        padding: EdgeInsets.symmetric(horizontal: 10.0, vertical: 10.0),
        height: 500.0,
        color: Colors.blue.withOpacity(0.8),
        width: double.infinity,
        child: Stack(
          children: list.map((value) {
            return GestureDetector(
              onScaleStart: (details) {
                if (value == null) return;
                _initPos = details.focalPoint;
                _currentPos = Offset(value.xPosition, value.yPosition);
                _currentScale = value.scale;
                _currentRotation = value.rotation;
              },
              onScaleUpdate: (details) {
                if (value == null) return;
                final delta = details.focalPoint - _initPos;
                final left = (delta.dx / screen.width) + _currentPos.dx;
                final top = (delta.dy / screen.height) + _currentPos.dy;

                setState(() {
                  value.xPosition = Offset(left, top).dx;
                  value.yPosition = Offset(left, top).dy;
                  value.rotation = details.rotation + _currentRotation;
                  value.scale = details.scale * _currentScale;
                });
              },
              child: Stack(
                children: [
                  Positioned(
                    left: value.xPosition * screen.width,
                    top: value.yPosition * screen.height,
                    child: Transform.scale(
                      scale: value.scale,
                      child: Transform.rotate(
                        angle: value.rotation,
                        child: Container(
                          height: value.height,
                          width: value.width,
                          child: FittedBox(
                            fit: BoxFit.fill,
                            child: Listener(
                              onPointerDown: (details) {
                                // if (_inAction) return;
                                // _inAction = true;
                                // _activeItem = val;
                                _initPos = details.position;
                                _currentPos =
                                    Offset(value.xPosition, value.yPosition);
                                _currentScale = value.scale;
                                _currentRotation = value.rotation;
                              },
                              onPointerUp: (details) {
                                // _inAction = false;
                              },
                              child: Container(
                                height: value.height,
                                width: value.width,
                                color: Colors.red,
                              ),
                              // child: Image.network(value.name),
                            ),
                          ),
                        ),
                      ),
                    ),
                  )
                ],
              ),
            );
          }).toList(),
        ),
      ),
    );
  }
}

所以现在我也可以知道旋转角度值和缩放值。在矩阵手势检测器包中,您无法了解这些值。