Home > Back-end >  Flutter - How to rotate shadow with object?
Flutter - How to rotate shadow with object?

Time:09-28

enter image description here

So I have an object that rotates along the Y axis. I have used a container with box shadow to cast the shadow of the object.

No I have a container that rotates but it kind of loses its width in the center (if you know how transform works)... How can I rotate the container without it losing its width throughout the rotation.

enter image description here

class _TestState extends State<Test> with TickerProviderStateMixin {
 late final AnimationController _controller;
 @override
 void initState() {
  _controller = AnimationController(
    vsync: this,
    duration: Duration(seconds: 25),
  )..repeat();
  super.initState();
}

Widget build(BuildContext context) {
 double screenHeight = MediaQuery.of(context).size.height;
 double screenWidth = MediaQuery.of(context).size.width;

return Scaffold(
  backgroundColor: Colors.black,
  appBar: AppBar(
    title: Text('3D Demo'),
    backgroundColor: Colors.black,
  ),
  body: Center(
    child: Container(
      padding: EdgeInsets.symmetric(horizontal: 0, vertical: 0),
      // width: double.infinity,
      // height: double.infinity,

      decoration: BoxDecoration(
        gradient: LinearGradient(
          begin: Alignment.topCenter,
          end: Alignment.bottomCenter,
          // stops: [0.1, 0.5, 0.7, 0.9],
          colors: [Colors.black, Colors.black],
        ),
      ),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Divider(),
          Divider(),


          SizedBox(
            height: screenHeight * 0.5,
            child: Stack(
              children: [


                Center(
                  child: AnimatedBuilder(
                    animation: _controller,
                    builder: (_, child) {
                      return Transform(
                        alignment: Alignment.center,
                        transform: Matrix4.identity()
                          ..setEntry(3, 2, 0.001)
                          //..rotateX(0.01 * _offset.dy)
                          //   ..rotateY(0.01 * _offset.dx),
                          // alignment: FractionalOffset.center,
                          ..rotateY(
                            _controller.value * (-math.pi),
                          ),
                        // ..rotateZ(
                        //   math.pi *
                        //       2 *
                        //       _controller
                        //           .value, //change 0 to any value to rotate z Axis
                        // ),
                        child: child,
                      );
                    },
                    child: Container(
                      child: AnimatedContainer(
                        //transform: Matrix4.skewX(10),
                        height: 100,
                        width: double.infinity,
                        duration: const Duration(milliseconds: 5000),
                        decoration: BoxDecoration(
                            borderRadius: BorderRadius.circular(100),

                            boxShadow:

                                [
                              BoxShadow(
                                color: Colors.yellow.withOpacity(0.6),
                                spreadRadius: 1,
                                blurRadius: 16,
                                offset: const Offset(-0, 0),
                              ),

                            ]
                            
                            ),
                      ),
                    ),
                  ),
                ),

              ],
            ),
          ),
        ],
      ),
    ),
   ),
  );
 }
}

CodePudding user response:

I think this is what you want. Paste the following code into DartPad and you can see that it's just a matter of adding more rotations. Hopefully someone can show me a more efficient way of doing the transformations, but this works.

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

const Color darkBlue = Color.fromARGB(255, 18, 32, 47);

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark().copyWith(
        scaffoldBackgroundColor: darkBlue,
      ),
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: Test(),
        ),
      ),
    );
  }
}

class Test extends StatefulWidget {
  @override
  _TestState createState() => _TestState();
}

class _TestState extends State<Test> with SingleTickerProviderStateMixin {
  late final AnimationController _controller;

  bool isAnimating = false;

  @override
  void initState() {
    _controller = AnimationController(
      vsync: this,
      duration: Duration(seconds: 10),
    );
    super.initState();
  }

  @override
  dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.black,
      appBar: AppBar(
        title: Text('3D Demo'),
        backgroundColor: Colors.black,
      ),
      body: Center(
        child: AnimatedBuilder(
          animation: _controller,
          builder: (_, child) {
            return Transform(
              alignment: FractionalOffset.center,
              transform: Matrix4.identity()
                ..setEntry(3, 2, 0.002)
                ..rotateY(0.5 * -math.pi)
                ..rotateZ(-0.1 * math.pi)
                ..rotateY((_controller.value - 0.5) * -math.pi)
                ..rotateX(0.5 * math.pi),
              child: child,
            );
          },
          child: Container(
            height: 100,
            width: 200,
            color: Colors.white,
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          isAnimating ? _controller.stop() : _controller.repeat();
          setState(() {
            isAnimating = !isAnimating;
          });
        },
        child: Icon(Icons.play_arrow),
      ),
    );
  }
}
  • Related