aytunch
aytunch

Reputation: 1434

Flutter 3D Cube rotation Transform Matrix (Like Instagram stories)

I have a PageView.builder and I am trying to add a custom transition effect just like Instagram's stories. Swift Package which has a gif showing the desired effect Using matrix4 is hard to debug and require lots of math I guess so right now I am getting Gaps and Overlaps between the Left and Right child of the PageView.

My current Implementation as you can see is far from perfect

The code is taken partially from the tutorial at: custom pageview transitions

PageView.builder(
  controller: controller,
  itemBuilder: (context, position) {
    if (position == currentPageValue.floor()) {
        //page being swiped from
        return Transform(
            transform: _matrix3dSwipeL(position),   //First Matrix ???
            child: _child,
        );
    } else if (position == currentAnimationValue.floor() + 1){
        //page being swiped to 
        return Transform(
            transform: _matrix3dSwipeR(position),   //Second Matrix ???
            child: _child,
        );         
    } else {
        //off screen page
        return _child;
    }
  },
  itemCount: 10,
)

The Matrix I came up with right now is(does not work!):

Matrix4 _matrix3dSwipeL(int index) {
    double _animationvalue =
        ui.lerpDouble(0.0, math.pi / 2, _currentPageValue - index);
    return Matrix4.identity()
      ..setEntry(3, 2, 0.001)
      ..translate(((_screenSize.width / 2) * math.sin(_animationvalue)), 0.0,
          ((_screenSize.width / 2) * math.sin(_animationvalue)))
      ..rotateY(_animationvalue);
  }

  Matrix4 _matrix3dSwipeR(int index) {
    double _animationvalue =
        ui.lerpDouble(0.0, math.pi / 2, _currentPageValue + 1 - index);
    return Matrix4.identity()
      ..setEntry(3, 2, 0.001)
      ..translate(((-_screenSize.width / 2) * math.cos(_animationvalue)), 0.0,
          ((_screenSize.width / 2) * math.cos(_animationvalue)))
      ..rotateY(-(math.pi / 2) + _animationvalue);
  }

How would we construct the two Transformations for the current and the next page?

Upvotes: 0

Views: 3656

Answers (1)

diegoveloper
diegoveloper

Reputation: 103451

I've just released a package that has the animation you want. It's called cube_transition.

You can check it : https://pub.dev/packages/cube_transition

Using my package the code is very simple.


import 'package:cube_transition/cube_transition.dart';

const places = [ ...];

class Sample2 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final height = MediaQuery.of(context).size.height / 2;
    return Scaffold(
      appBar: AppBar(
        title: Text('PageView Cube Transition'),
      ),
      body: Center(
        child: SizedBox(
          height: height,
          child: CubePageView(
            children: places
                .map(
                  (item) =>  Image.network(
                        item.url,
                        height: height,
                        fit: BoxFit.cover,
                      ),
                )
                .toList(),
          ),
        ),
      ),
    );
  }
}

Result

enter image description here

Upvotes: 5

Related Questions