How To Create Page Curl Effect, Thanos Snap Effects In Flutter

1. Thanos effect in Flutter

Thanos snap effect coming from the Avengers: Infinity War movie.

To put it simply, the goal is to:



1. Convert a Widget to Image
2. Split the image into multiple buckets
3. Display each layer separately
4. Animate every layer of the image

We will use the snappable package.

Getting Started 
Import it

import 'package:snappable/snappable.dart';

Wrap any widget in Snappable 

@override
Widget build(BuildContext context) {
  return Snappable(
    child: Text('This whill be snapped'),
  );
}

Snap with a Key


class MyWidget extends StatelessWidget {
  final key = GlobalKey<SnappableState>();
  @override
  Widget build(BuildContext context) {
    return Snappable(
      key: key,
      child: Text('This whill be snapped'),
    );
  }
  
  void snap() {
    key.currentState.snap();
  }
}

Undo by currentState.reset().

or snap by tap


class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Snappable(
      snapOntap: true,
      child: Text('This whill be snapped'),
    );
  }
}

Undo by tapping again.


NEW Avengers Endgame Easter Egg! *Google Thanos*


2. Page Curl Effect

In this flutter tutorial post, I will show you how to create awesome pages curl effects in a flutter.

Page curl effects can be used in any reading and studying app.



This is an amazing effort from the developer.


Source Code

Click To getting


3. Colorful Boxes Tree Effects Flutter


import 'dart:math';

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(
          textTheme: TextTheme(
        body1: TextStyle(color: Colors.white),
      )),
      home: Tree(),
    );
  }
}

class Tree extends StatelessWidget {
  static final List<double> _offsets =
      _generateOffsets(100, 0.05).toList(growable: false);

  @override
  Widget build(BuildContext context) {
    return Material(
      color: Colors.black,
      child: Align(
        child: Container(
          constraints: BoxConstraints(maxWidth: 500),
          child: ListView(
            children: <Widget>[
              Center(child: Icon(Icons.star, color: Colors.yellow)),
              SizedBox(height: 10),
              for (final x in _offsets) Light(x),
              SizedBox(height: 50),
              Center(child: Text('(Happy Holidays from Naseer)'))
            ],
            padding: const EdgeInsets.symmetric(vertical: 50, horizontal: 10),
          ),
        ),
      ),
    );
  }

  static Iterable<double> _generateOffsets(
      int count, double acceleration) sync* {
    double x = 0;
    yield x;

    double ax = acceleration;
    for (var i = 0; i < count; i++) {
      x += ax;
      ax *= 1.5;

      final maxLateral = min(1, i / count);
      if (x.abs() > maxLateral) {
        x = maxLateral * x.sign;
        ax = x >= 0 ? -acceleration : acceleration;
      }
      yield x;
    }
  }
}

class Light extends StatefulWidget {
  static List<Color> festiveColors = [
    Colors.green,
    Colors.red,
    Colors.orange,
  ];

  /// The light's offset from center.
  final double x;

  /// Pseudo-random period for the light's color change.
  final int period;

  /// One of the [festiveColors].
  final Color color;

  Light(this.x, {Key key})
      : period = 500 + (x.abs() * 2000).floor(),
        color = festiveColors[(x.abs() * 42).floor() % festiveColors.length],
        super(key: key);

  @override
  _LightState createState() => _LightState();
}

class _LightState extends State<Light> {
  Color _newColor = Colors.white;

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      height: 10,
      child: Align(
        alignment: Alignment(widget.x, 0),
        child: AspectRatio(
          aspectRatio: 1,
          child: TweenAnimationBuilder(
            tween: ColorTween(begin: widget.color, end: _newColor),
            duration: Duration(milliseconds: widget.period),
            onEnd: () {
              setState(() {
                _newColor =
                    _newColor == Colors.white ? widget.color : Colors.white;
              });
            },
            builder: (_, color, __) => Container(color: color),
          ),
        ),
      ),
    );
  }
}

Post a Comment

0 Comments