代码之家  ›  专栏  ›  技术社区  ›  Axel

如何基于手势检测器手柄在颤动中旋转图像?

  •  0
  • Axel  · 技术社区  · 4 年前

    我有以下代码:

    import 'package:flutter/material.dart';
    
    double ballRadius = 7.5;
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatefulWidget {
      @override
      _MyAppState createState() => _MyAppState();
    }
    
    class _MyAppState extends State<MyApp> {
      double finalAngle = 0.0;
      double oldAngle = 0.0;
      double upsetAngle = 0.0;
    
      double _height = 200;
      double _width = 300;
    
      Offset centerOfGestureDetector = Offset(ballRadius, ballRadius);
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          debugShowCheckedModeBanner: false,
          home: Scaffold(
            body: SafeArea(
              child: // rotate
                  Transform.rotate(
                angle: finalAngle,
                child: Stack(
                  children: [
                    Positioned(
                      top: 50,
                      left: 50 + _width / 2,
                      child: Column(
                        children: [
                          GestureDetector(
                            behavior: HitTestBehavior.translucent,
                            onPanStart: (details) {
                              final touchPositionFromCenter =
                                  details.localPosition - centerOfGestureDetector;
                              upsetAngle =
                                  oldAngle - touchPositionFromCenter.direction;
                            },
                            onPanEnd: (details) {
                              setState(
                                () {
                                  oldAngle = finalAngle;
                                },
                              );
                            },
                            onPanUpdate: (details) {
                              final touchPositionFromCenter =
                                  details.localPosition - centerOfGestureDetector;
    
                              setState(
                                () {
                                  finalAngle = touchPositionFromCenter.direction +
                                      upsetAngle;
                                },
                              );
                            },
                            child: Container(
                              height: 2 * ballRadius,
                              width: 2 * ballRadius,
                              decoration: BoxDecoration(
                                color: Colors.white,
                                borderRadius: BorderRadius.circular(ballRadius),
                                border: Border.all(
                                  width: 2,
                                  color: Colors.blue,
                                ),
                              ),
                            ),
                          ),
                          Container(
                            height: 50,
                            width: 2,
                            color: Colors.blue,
                          ),
                        ],
                      ),
                    ),
                    Positioned(
                      top: 100,
                      left: 50,
                      child: Image.network(
                        "https://via.placeholder.com/300x200",
                        width: _width,
                        height: _height,
                        fit: BoxFit.fill,
                      ),
                    )
                  ],
                ),
              ),
            ),
          ),
        );
      }
    }
    
    

    拖动控制柄时,图像应相应地旋转。但正如你所看到的,它工作不正常。如果我不使用 Stack Positioned ,它工作得很好。但我确实需要 堆栈 已定位 请帮我。

    我预计轮换如下:

    enter image description here

    0 回复  |  直到 4 年前
        1
  •  6
  •   Henok    4 年前

    添加固定 高度 宽度 堆栈修复了这个问题,它正在正确旋转,如下图所示。

    enter image description here

    
    import 'package:flutter/material.dart';
    
    double ballRadius = 7.5;
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatefulWidget {
      @override
      _MyAppState createState() => _MyAppState();
    }
    
    class _MyAppState extends State<MyApp> {
      double finalAngle = 0.0;
      double oldAngle = 0.0;
      double upsetAngle = 0.0;
    
      double _height = 200;
      double _width = 300;
    
      Offset centerOfGestureDetector = Offset(ballRadius, ballRadius);
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          debugShowCheckedModeBanner: false,
          home: Scaffold(
            body: SafeArea(
              child: // rotate
              Stack(
                children: [
                  getImageWithHandle(),
                ],
              ),
            ),
          ),
        );
      }
      
      
      Widget getImageWithHandle(){
        return Transform.rotate(
                      angle: finalAngle,
                      child: SizedBox(
                        height: 400,
                        width: 400,
                        child: Stack(
                          children: [
                            Positioned(
                              top: 50,
                              left: 50 + _width / 2,
                              child: Column(
                                mainAxisSize: MainAxisSize.min,
                                children: [
                                  GestureDetector(
                                    behavior: HitTestBehavior.translucent,
                                    onPanStart: (details) {
                                      final touchPositionFromCenter =
                                          details.localPosition - centerOfGestureDetector;
                                      upsetAngle =
                                          oldAngle - touchPositionFromCenter.direction;
                                    },
                                    onPanEnd: (details) {
                                      setState(
                                            () {
                                          oldAngle = finalAngle;
                                        },
                                      );
                                    },
                                    onPanUpdate: (details) {
                                      final touchPositionFromCenter =
                                          details.localPosition - centerOfGestureDetector;
    
                                      setState(
                                            () {
                                          finalAngle = touchPositionFromCenter.direction +
                                              upsetAngle;
                                        },
                                      );
                                    },
                                    child: Container(
                                      height: 2 * ballRadius,
                                      width: 2 * ballRadius,
                                      decoration: BoxDecoration(
                                        color: Colors.white,
                                        borderRadius: BorderRadius.circular(ballRadius),
                                        border: Border.all(
                                          width: 2,
                                          color: Colors.blue,
                                        ),
                                      ),
                                    ),
                                  ),
                                  Container(
                                    height: 50,
                                    width: 2,
                                    color: Colors.blue,
                                  ),
                                ],
                              ),
                            ),
                            Positioned(
                              top: 100,
                              left: 50,
                              child: Image.network(
                                "https://via.placeholder.com/300x200",
                                width: _width,
                                height: _height,
                                fit: BoxFit.fill,
                              ),
                            )
                          ],
                        ),
                      ),
                    );
      }
    }
    
    
    
        2
  •  0
  •   Ronak Patel    4 年前

    我认为这可能是你的解决方案,这是演示 https://dartpad.dartlang.org/dart .

    import 'dart:math';
    
    import 'package:flutter/material.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          debugShowCheckedModeBanner: false,
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: RotateText(),
        );
      }
    }
    
    class RotateText extends StatefulWidget {
      RotateText({Key key}) : super(key: key); // changed
    
      @override
      _RotateTextState createState() => _RotateTextState();
    }
    
    class _RotateTextState extends State<RotateText> {
      double finalAngle = 0.0;
    
      @override
      Widget build(BuildContext context) {
        return _defaultApp(context);
      }
    
      _defaultApp(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('Single finger Rotation'), // changed
          ),
          body: Center(
            child: Column(
              children: <Widget>[
                Container(
                  color: Colors.red,
                  padding: EdgeInsets.all(10),
                  margin: EdgeInsets.only(top: 50),
                  child: Transform.rotate(
                    angle: finalAngle,
                    child: Container(
                      height: 100.0,
                      width: 100.0,
                      child: Image.network(
                        'https://picsum.photos/250?image=9',
                      ),
                    ),
                  ),
                ),
                Container(
                  width: 250,
                  height: 250,
                  color: Colors.grey,
                  margin: EdgeInsets.all(30.0),
                  child: LayoutBuilder(
                    builder: (context, constraints) {
                      return GestureDetector(
                        behavior: HitTestBehavior.translucent,
                        onPanUpdate: (details) {
                          Offset centerOfGestureDetector = Offset(
                              constraints.maxWidth / 2, constraints.maxHeight / 2);
                          final touchPositionFromCenter =
                              details.localPosition - centerOfGestureDetector;
                          print(touchPositionFromCenter.direction * 180/pi);
                          setState(
                                () {
                              finalAngle = touchPositionFromCenter.direction;
                            },
                          );
                        },
                        child: Transform.rotate(
                          angle: finalAngle,
                          child: Icon(
                            Icons.arrow_forward,
                            color: Colors.white,
                            size: 200,
                          ),
                        ),
                      );
                    },
                  ),
                )
              ],
            ),
          ),
        );
      }
    }