Перемещение повернутого изображения с помощью GestureDetector в flutter

#flutter #dart

#flutter #dart

Вопрос:

У меня есть следующий код:

 import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'dart:math' as math;

void main() {
  debugPaintSizeEnabled = true;
  return runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        backgroundColor: Colors.grey,
        body: SafeArea(
          child: TestComp(),
        ),
      ),
    );
  }
}

class TestComp extends StatefulWidget {
  @override
  _TestCompState createState() => _TestCompState();
}

class _TestCompState extends State<TestComp> {
  double _y = 0;
  double _x = 0;

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        Positioned(
          top: _y,
          left: _x,
          child: Transform.rotate(
            angle: math.pi / 180 * 90,
            child: Container(
              height: 200,
              width: 300,
              color: Colors.black,
              child: Stack(
                children: <Widget>[
                  Positioned(
                    top: 0,
                    left: 0,
                    child: GestureDetector(
                      onPanUpdate: (details) {
                        var dx = details.delta.dx;
                        var dy = details.delta.dy;
                        setState(() {
                          _y  = dy;
                          _x  = dx;
                        });
                      },
                      child: Image.network("https://via.placeholder.com/300x200"),
                    ),
                  ),
                ],
              ),
            ),
          ),
        ),
      ],
    );
  }
}
  

По сути, функциональность заключается в том, чтобы сделать изображение перетаскиваемым. Но когда я поворачиваю его и пытаюсь переместить изображение, координаты путаются. Он не движется в правильном направлении. Он отлично работает, когда угол равен 0. Любая помощь будет оценена.

Комментарии:

1. Вы изучали виджеты с возможностью перетаскивания и перетаскивания? Если это поможет в вашем случае использования

Ответ №1:

Структура координат Flutter работает немного по-другому. Я не смог найти четкий URL-адрес для этого, но в вашем случае значения меняются следующим образом. Вы можете попробовать пример кода. Чтобы изменить угол, вы можете назначить другой угол в «map» в «selectedAngle».

введите описание изображения здесь

 import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'dart:math' as math;

void main() {
  debugPaintSizeEnabled = true;
  return runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        backgroundColor: Colors.grey,
        body: SafeArea(
          child: TestComp(),
        ),
      ),
    );
  }
}

class TestComp extends StatefulWidget {
  @override
  _TestCompState createState() => _TestCompState();
}

class _TestCompState extends State<TestComp> {
  double _y = 0;
  double _x = 0;

  Map<int, double> map = {
    0: 0.0, // Same 360 angle
    90: math.pi / 180 * 90,
    180: math.pi / 180 * 180,
    270: math.pi / 180 * 270,
  };

  int selectedAngle = 270;

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        Positioned(
          top: _y,
          left: _x,
          child: Transform.rotate(
            angle: map[selectedAngle],
            child: Container(
              height: 200,
              width: 300,
              color: Colors.black,
              child: Stack(
                children: <Widget>[
                  Positioned(
                    top: 0,
                    left: 0,
                    child: GestureDetector(
                      onPanUpdate: (details) {
                        var dx = details.delta.dx;
                        var dy = details.delta.dy;
                        var result = calculate(dx, dy);


                        setState(() {
                          _y  = result['y'];
                          _x  = result['x'];
                        });
                      },
                      child: Image.network("https://via.placeholder.com/300x200"),
                    ),
                  ),
                ],
              ),
            ),
          ),
        ),
      ],
    );
  }

  Map<String, double> calculate(double x, double y) {

    switch(selectedAngle) {

      case(0):
        return {'x': x, 'y': y};
        break;

      case(90):
        return {'x': -y, 'y': x};
        break;

      case(180):
        return {'x': -x, 'y': -y};
        break;

      case(270):
        return {'x': y, 'y': -x};
        break;

      default:
        return {'x': x, 'y': y};
        break;
    }

  }
}
  

Комментарии:

1. Большое спасибо за ответ. Угол должен быть двойным, а не int. Так что, если я поставлю как 136, это не сработает

Ответ №2:

Вы можете скопировать вставить запустить полный код ниже
Вы можете перейти Transform.rotate к переносу Image.network
смотрите рабочую демонстрацию ниже
фрагмента кода

  Transform.rotate(
                angle: math.pi / 180 * 90,
                child: Image.network(
                    "https://via.placeholder.com/300x200")),
          ),
  

рабочая демонстрация

введите описание изображения здесь

полный код

 import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'dart:math' as math;

void main() {
  debugPaintSizeEnabled = true;
  return runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        backgroundColor: Colors.grey,
        body: SafeArea(
          child: TestComp(),
        ),
      ),
    );
  }
}

class TestComp extends StatefulWidget {
  @override
  _TestCompState createState() => _TestCompState();
}

class _TestCompState extends State<TestComp> {
  double _y = 0;
  double _x = 0;

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        Positioned(
          top: _y,
          left: _x,
          child: Container(
            height: 200,
            width: 300,
            color: Colors.black,
            child: Stack(
              children: <Widget>[
                Positioned(
                  top: 0,
                  left: 0,
                  child: GestureDetector(
                    onPanUpdate: (details) {
                      var dx = details.delta.dx;
                      var dy = details.delta.dy;
                      setState(() {
                        _y  = dy;
                        _x  = dx;
                      });
                    },
                    child: Transform.rotate(
                        angle: math.pi / 180 * 90,
                        child: Image.network(
                            "https://via.placeholder.com/300x200")),
                  ),
                ),
              ],
            ),
          ),
        ),
      ],
    );
  }
}