rotate 3D on X in Flutter

7,177

Solution 1

thanks to this discussion, and this repo, and after more than a day seeking the answer,

static Matrix4 _pmat(num pv) {
    return new Matrix4(
      1.0, 0.0, 0.0, 0.0, //
      0.0, 1.0, 0.0, 0.0, //
      0.0, 0.0, 1.0, pv * 0.001, //
      0.0, 0.0, 0.0, 1.0,
    );
}

Matrix4 perspective = _pmat(1.0);


// then use it

new Center(
      child: new Transform(
        child: new FittedBox(
          fit: BoxFit.fill,
          child: LogoWidget(),
        ),
        alignment: FractionalOffset.center,
        transform: perspective.scaled(1.0, 1.0, 1.0)
          ..rotateX(math.pi - degrees * math.pi / 180)
          ..rotateY(0.0)
          ..rotateZ(0.0)
      ),
    );

here is the result image

mobile flutter rotation 3d perspective

please read a little theory about this subject.

Solution 2

You can use Transform widget to apply a matrix onto it's child.

Here's an example combining Transform with the animation framework to rotate on X, Y, and Z directions.

enter image description here

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

void main() {
  runApp(
    new MaterialApp(
      home: new Home(),
    ),
  );
}

class Home extends StatefulWidget {
  @override
  _HomeState createState() => new _HomeState();
}

class _HomeState extends State<Home> with SingleTickerProviderStateMixin {
  AnimationController animationController;
  Animation<double> rotateX;
  Animation<double> rotateY;
  Animation<double> rotateZ;

  @override
  initState() {
    super.initState();
    animationController = new AnimationController(
      duration: const Duration(seconds: 2),
      vsync: this,
    )..repeat();
    print('bar');
    rotateX = new Tween<double>(
      begin: .0,
      end: 1.0,
    ).animate(new CurvedAnimation(
      parent: animationController,
      curve: new Interval(.0, 1 / 3),
    ));
    rotateY = new Tween<double>(
      begin: .0,
      end: 1.0,
    ).animate(new CurvedAnimation(
      parent: animationController,
      curve: new Interval(1 / 3, 2 / 3),
    ));
    rotateZ = new Tween<double>(
      begin: .0,
      end: .5,
    ).animate(new CurvedAnimation(
      parent: animationController,
      curve: new Interval(2 / 3, 1.0),
    ));
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: new Center(
        child: new AnimatedBuilder(
          animation: animationController,
          builder: (context, child) {
            final card = new SizedBox(
              width: 42.0,
              height: 42.0,
              child: new Card(
                color:
                    animationController.value >= 1 / 6 && animationController.value <= 3 / 6 ? Colors.blue : Colors.red,
              ),
            );

            return new Transform(
              transform: new Matrix4.rotationX(rotateX.value * math.pi)
                ..multiply(new Matrix4.rotationY(rotateY.value * math.pi))
                ..multiply(new Matrix4.rotationZ(rotateZ.value * math.pi)),
              alignment: Alignment.center,
              child: card,
            );
          },
        ),
      ),
    );
  }
}
Share:
7,177
AbdulMomen عبدالمؤمن
Author by

AbdulMomen عبدالمؤمن

Hello there! ;) I like computers, mathematics, philosophy, logic, music and religion.

Updated on December 05, 2022

Comments

  • AbdulMomen عبدالمؤمن
    AbdulMomen عبدالمؤمن over 1 year

    I've been working with Flutter rotation,

    new Matrix4.identity() ..rotateX(degrees * 3.1415927 / 180),

    but, the problem, I want it to be similar to the diagram below. can I achieve a 3D-like rotation on the x-axis with Flutter?

    even if there is a mapping from 3D to 2D or there are alternatives that would get the same result. thanks in advance.

    rotate3d diagram

    Example image in OpenCV: How to calculate perspective transform for OpenCV from rotation angles?