Search code examples
fluttergesturedetector

Flutter: How Do I Make This Shape Rotate Smoothly Using a GestureDetector?


Introduction:

I have begun studying rotations in Flutter using the following code which is supposed to rotate a square by using a GestureDetector:

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

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  double angle = 0.0;
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  void _panHandler(DragUpdateDetails d) {
    setState(() {
      widget.angle = atan(d.delta.dy / d.delta.dx);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: GestureDetector(
        onPanUpdate: _panHandler,
        child: Center(
          child: Transform.rotate(
            angle: this.widget.angle,
            child: Container(
              color: Colors.red,
              child: SizedBox(
                child: null,
                height: 100,
                width: 100,
              ),
            ),
          ),
        ),
      ),
    );
  }
}

Problem: Indeed, the square does rotate; however, it is anything but smooth. It flickers badly while spinning. I am puzzled by this and do not know how to make it turn smoothly.

Question:

1) Does this problem arise from some sort of decimal precision issue or my maths?


Solution

  • Please try this

    import 'package:flutter/material.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: MyHomePage(),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      double angle = 0.0;
    
      void _onPanUpdateHandler(DragUpdateDetails details) {
        final touchPositionFromCenter = details.localPosition;
        setState(
          () {
            angle = touchPositionFromCenter.direction;
          },
        );
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
              child: GestureDetector(
            onPanUpdate: _onPanUpdateHandler,
            child: Transform.rotate(
              angle: angle,
              child: Container(
                color: Colors.red,
                child: SizedBox(
                  child: null,
                  height: 100,
                  width: 100,
                ),
              ),
            ),
          )),
        );
      }
    }