Rotate text or image using button gesture in flutter

3,056

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,
                      ),
                    ),
                  );
                },
              ),
            )
          ],
        ),
      ),
    );
  }
}
Share:
3,056
jazzbpn
Author by

jazzbpn

With 6+ years of experience, I have developed many iOS/android applications in different context, professional and oldest passion for computer programming began very early in my life. I've learned the social environment is as important as logic aspects of the developing approach then I appreciate very much to get in touch with positive and eager colleagues that involve me in new and exciting challenges. This is why I still want to get involved in new opportunities to improve my skillness.

Updated on December 17, 2022

Comments

  • jazzbpn
    jazzbpn over 1 year

    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.

    enter image description here

      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,
                      ),
                    ),
                  )
                ],
              ),
            ),
          );
        }
      }
    
    • Hussnain Haidar
      Hussnain Haidar over 4 years
      What are the issues?
    • jazzbpn
      jazzbpn over 4 years
      It's rotating zigzag. It's not rotating smoothly.
    • Tizianoreica
      Tizianoreica over 4 years
      You should try on a device to see the actual outcome of animation
    • jazzbpn
      jazzbpn over 4 years
      Already tried on the real device. Did you try running the code?
    • easeccy
      easeccy over 4 years
      Do you want it to rotate while you're making circles with your finger? Because that's very different approach. My current answer is based on straight line drags.
    • jazzbpn
      jazzbpn over 4 years
      Yes. Exactly!! I want to rotate the widget while we make circles with our finger.
  • jazzbpn
    jazzbpn almost 3 years
    1. Widget moves when tap to rotate button in some unknown angle. Why? 2. It is too sensitive to gesture. So, can we make more smooth? Please help me with this.
  • Crazy Lazy Cat
    Crazy Lazy Cat almost 3 years
    The first example is rotates based on you finger position from center point. you can try the second example