Search code examples
flutterflutter-animation

how to make a mood randomizer screen in flutter


I am having trouble in creating a UI screen in flutter, essentially this screen has 7 circles, one in the middle and six around it. When any of six circles are tapped, I want all six circles to start revolving around middle one. For more understanding plese refer to the image attached.

Deign of Screen

Uptil now I tried using flutter package circular_rotation: ^0.0.1. This package wproviding me with exctly what I want, but the issue is that this package is letting mr to only create 4 circles around middle one, just when I add 5th, it starts acting wierd.

My code

import 'dart:math';
import 'package:circular_rotation/circular_rotation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:islamicapp/app/data/constant/app_color.dart';
import 'package:islamicapp/app/data/constant/image_string.dart';
import 'package:islamicapp/app/views/widgets/button_text2.dart';
import 'package:islamicapp/app/views/widgets/ktext2.dart';

class Randomizer extends StatefulWidget {
  const Randomizer({super.key});

  @override
  State<Randomizer> createState() => _RandomizerState();
}

class _RandomizerState extends State<Randomizer> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: AppColor.green,
      body: Container(
        width: Get.width,
        height: Get.height,
        alignment: Alignment.center,
        child: CircularRotation(
          circularRotationProperty: CircularRotationModel(
            // defaultCircleStrokeWidth: Dimens.strokeSmall,
            defaultCircleStrokeColor: Colors.transparent,
            startAnimation: false,
            repeatAnimation: false,
            firstCircleAnimationDuration: 12000,

            // thirdCircleAnimationDuration: 10000,
        centerWidget: Container(
          width: 150.w,
          height: 150.h,
          padding: EdgeInsets.all(10),
          alignment: Alignment.center,
          decoration: BoxDecoration(
            color: AppColor.feel,
            shape: BoxShape.circle,
          ),
          child: KText2(
            text: "feel".tr,
            fontSize: 24.sp,
            fontWeight: FontWeight.bold,
          ),
        ),

        visibleThirdCircle: false,
        firstCircleWidgets: [
          InkWell(
            // onTap: CircularRotation.eitherStartOrStopAnimation,
            child: Container(
              width: 100.w,
              // height: 100.h,
              padding: EdgeInsets.all(10),
              alignment: Alignment.center,
              decoration: BoxDecoration(
                color: Colors.white,
                shape: BoxShape.circle,
              ),
              child: Column(
                children: [
                  Image(
                    image: ImageString.happy,
                    width: 60.w,
                    height: 60.h,
                  ),
                  KText2(
                    text: "happy".tr,
                    fontSize: 20.sp,
                    fontWeight: FontWeight.bold,
                  ),
                ],
              ),
            ),
          ),
          InkWell(
            // onTap: CircularRotation.eitherStartOrStopAnimation,
            child: Container(
              width: 100.w,
              // height: 100.h,
              padding: EdgeInsets.all(10),
              alignment: Alignment.center,
              decoration: BoxDecoration(
                color: Colors.white,
                shape: BoxShape.circle,
              ),
              child: Column(
                children: [
                  Image(
                    image: ImageString.happy,
                    width: 60.w,
                    height: 60.h,
                  ),
                  KText2(
                    text: "happy".tr,
                    fontSize: 20.sp,
                    fontWeight: FontWeight.bold,
                  ),
                ],
              ),
            ),
          ),
          InkWell(
            // onTap: CircularRotation.eitherStartOrStopAnimation,
            child: Container(
              width: 100.w,
              // height: 100.h,
              padding: EdgeInsets.all(10),
              alignment: Alignment.center,
              decoration: BoxDecoration(
                color: Colors.white,
                shape: BoxShape.circle,
              ),
              child: Column(
                children: [
                  Image(
                    image: ImageString.happy,
                    width: 60.w,
                    height: 60.h,
                  ),
                  KText2(
                    text: "happy".tr,
                    fontSize: 20.sp,
                    fontWeight: FontWeight.bold,
                  ),
                ],
              ),
            ),
          ),
          InkWell(
            // onTap: CircularRotation.eitherStartOrStopAnimation,
            child: Container(
              width: 100.w,
              // height: 100.h,
              padding: EdgeInsets.all(10),
              alignment: Alignment.center,
              decoration: BoxDecoration(
                color: Colors.white,
                shape: BoxShape.circle,
              ),
              child: Column(
                children: [
                  Image(
                    image: ImageString.happy,
                    width: 60.w,
                    height: 60.h,
                  ),
                  KText2(
                    text: "happy".tr,
                    fontSize: 20.sp,
                    fontWeight: FontWeight.bold,
                  ),
                ],
              ),
            ),
          ),
        ],
        firstCircleRadius: 330.w,
        visibleSecondCircle: true,
        // secondCircleRadius: 330.w,
        // secondCircleAnimationDuration: 12000,
        // thirdCircleRadius: 150.w,
        // secondCircleWidgets: [
        //   Container(
        //     width: 120.w,
        //     // height: 100.h,
        //     padding: EdgeInsets.all(10),
        //     alignment: Alignment.center,
        //     decoration: BoxDecoration(
        //       color: Colors.white,
        //       shape: BoxShape.circle,
        //     ),
        //     child: Column(
        //       children: [
        //         Image(
        //           image: ImageString.happy,
        //           width: 60.w,
        //           height: 60.h,
        //         ),
        //         KText2(
        //           text: "happy".tr,
        //           fontSize: 20.sp,
        //           fontWeight: FontWeight.bold,
        //         ),
        //       ],
        //     ),
        //   ),
        // ],
        // thirdCircleWidgets: _thirdCircleImages,
        // thirdCircleRadians: Dimens.thirdCircleRadians,
        // secondCircleRadians: Dimens.secondCircleRadians,
        // firstCircleRadians: Dimens.firstCircleRadians,
      ),
    ),
  ),
);
  }
}

Solution

  • You can create it using the circle_list package as follows

    more examples here

    import 'package:flutter/material.dart';
    import 'dart:math';
    import 'package:circle_list/circle_list.dart';
    
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          debugShowCheckedModeBanner: false,
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: const RotateCircles(),
        );
      }
    }
    
    class RotateCircles extends StatefulWidget {
      const RotateCircles({Key? key}) : super(key: key);
      @override
      State<RotateCircles> createState() => _RotateCirclesState();
    }
    
    class _RotateCirclesState extends State<RotateCircles>
        with SingleTickerProviderStateMixin {
      late AnimationController animationController;
    
      @override
      void initState() {
        animationController = AnimationController(
          upperBound: pi * 2,
          vsync: this,
          duration: const Duration(seconds: 2),
        );
        super.initState();
      }
    
      @override
      void dispose() {
        animationController.dispose();
        super.dispose();
      }
    
      List<int> elements = List.generate(6, (index) => index);
    
      _rotate(int index) {
        //final _random = new Random();
        final angle = (pi * 2) * (index / 10);
        // you can rotate to any angle you want
        animationController.animateTo(angle);
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(),
          drawer: const Drawer(),
          body: Center(
            child: AnimatedBuilder(
              animation: animationController,
              builder: ((context, child) {
                return CircleList(
                  onDragEnd: () {},
                  onDragStart: (cord) {},
                  innerCircleColor: Colors.redAccent,
                  outerCircleColor: Colors.greenAccent,
                  initialAngle: -animationController.value - pi / 2,
                  outerRadius: 130,
                  innerRadius: 50,
                  centerWidget: Container(
                    width: 100,
                    height: 100,
                    decoration: const BoxDecoration(
                      color: Colors.blue,
                      shape: BoxShape.circle,
                    ),
                  ),
                  rotateMode: RotateMode.stopRotate,
                  origin: const Offset(0, 0),
                  children: elements
                      .map(
                        (index) => GestureDetector(
                          onTap: () => _rotate(index),
                          child: Container(
                            width: 75,
                            height: 75,
                            decoration: const BoxDecoration(
                              color: Colors.green,
                              shape: BoxShape.circle,
                            ),
                          ),
                        ),
                      )
                      .toList(),
                );
              }),
            ),
          ),
        );
      }
    }
    

    code is here