Rotate text or image using button gesture in flutter

时光怂恿深爱的人放手 提交于 2020-05-26 09:17:51

问题


Now, the image is smoothly rotating only from left to right when I make a gesture of 360 degree.

Required result:

  • Should rotate from right to left when we make a gesture of 360 degree.
  • Done: Should rotate from right to left when we make a gesture of 360 degree.
  • Once we start rotating from left to right at some point and again back to right to left it should rotate from either direction from which the gesture is made.

  import 'dart:math';

  import 'package:flutter/material.dart';

  class RotateImage extends StatefulWidget {
    RotateImage({Key key}) : super(key: key); // changed

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

  class _RotateImageState extends State<RotateImage> {
    double finalAngle = 0.0;

    @override
    Widget build(BuildContext context) {
      return _defaultApp(context);
    }

    _defaultApp(BuildContext context) {
      return Scaffold(
        appBar: AppBar(
          title: Text('Single finger Rotate text'), // 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,
                  origin: Offset(0, 0),
                  child: Container(
                    height: 100.0,
                    width: 100.0,
                    child: Image.network(
                      'https://picsum.photos/250?image=9',
                    ),
                  ),
                ),
              ),
              GestureDetector(
                onPanStart: (detials) {},
                onPanEnd: (detials) {},
                onPanUpdate: (details) {
                  setState(
                    () {
                      finalAngle += details.delta.distance * -pi / 180;
                    },
                  );
                },
                child: Container(
                  margin: EdgeInsets.only(top: 30),
                  color: Colors.black54,
                  width: 50,
                  height: 50,
                  child: Icon(
                    Icons.rotate_left,
                    color: Colors.white,
                  ),
                ),
              )
            ],
          ),
        ),
      );
    }
  }

回答1:


Here if you do gesture (with one finger) in circle around the icon, it will rotate.

Source Code 1: (Here the angle is based on finger position from the center of GestureDetector)

Demo: DartPad,

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 Rotate text'), // 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,
                      ),
                    ),
                  );
                },
              ),
            )
          ],
        ),
      ),
    );
  }
}

Source Code 2: (Here the angle is persisted and will continue update on every onPanStart)

Demo: DartPad,

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;
  double offsetAngle = 0.0;

  @override
  Widget build(BuildContext context) {
    return _defaultApp(context);
  }

  _defaultApp(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Single finger Rotate text'), // 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,
                    onPanStart: (details) {
                      Offset centerOfGestureDetector = Offset(
                          constraints.maxWidth / 2, constraints.maxHeight / 2);
                      final touchPositionFromCenter =
                          details.localPosition - centerOfGestureDetector;
                      offsetAngle =
                          touchPositionFromCenter.direction - finalAngle;
                    },
                    onPanUpdate: (details) {
                      Offset centerOfGestureDetector = Offset(
                          constraints.maxWidth / 2, constraints.maxHeight / 2);
                      final touchPositionFromCenter =
                          details.localPosition - centerOfGestureDetector;
                      setState(() {
                        finalAngle =
                            touchPositionFromCenter.direction - offsetAngle;
                      });
                    },
                    child: Transform.rotate(
                      angle: finalAngle,
                      child: Icon(
                        Icons.settings,
                        color: Colors.white,
                        size: 200.0,
                      ),
                    ),
                  );
                },
              ),
            )
          ],
        ),
      ),
    );
  }
}



回答2:


My answer became irrelevant after you asked for circle so I remove my code here. Go with the @Crazy Lazy Cat's answer.

I can still say that you should avoid using widget functions, declare them as classes instead.



来源:https://stackoverflow.com/questions/59906976/rotate-text-or-image-using-button-gesture-in-flutter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!