preface

Implementing UI and interaction are essential skills for big front-end developers and are key to mastering The development of Flutter; While learning About Flutter, I implemented several cool UI effects that are common on the client. Although the original wheel was built with Flutter, the cross-platform features of Flutter are uncomparable, not to mention the performance. This article mainly introduces the basic situation and use of Flutter effect library Flutter_Effects.

Project introduction

Flutter_effects: Composed of several Flutter package projects, the goal is to use pure Flutter to achieve cool UI effects on Android and ios. At present, the project is just in its infancy, so suggestions and feedback are welcome. If you have good ideas, you are welcome to put forward requirements or join us.

Implemented functions:

type Support the child widgets note
Bad word zoom The text Only characters are supported, rich text is not supported
The border line all
Rainbow font The text Currently, only text is supported, rich text to be determined
Particle explosions all Support for all widgets, including images
Stung to all
Scratch CARDS all The foreground needs to be drawn on canvas
More functions Under development…

Used to introduce

Bad word zoom

void initState() {
  super.initState();
  sentences = [
    "What is design?"."Design is not just"."what it looks like and feels like."."Design is how it works. \n- Steve Jobs"."Older people"."sit down and ask,"."'What is it? '"."but the boy asks,"."What can I do with it? . \n- Steve Jobs"."Swift"."Objective-C"."iPhone"."iPad"."Mac Mini"."MacBook Pro"."Mac Pro"."Love my wife"."Wife and daughter."
  ];
}
DiffScaleText(
  text: sentences[diffScaleNext % sentences.length],
  textStyle: TextStyle(fontSize: 20, color: Colors.blue),
)
Copy the code

DiffScaleText only supports Chinese and English characters, but not emojis and rich text. The text parameter controls the display text. Update the next one only needs to change the text and rebuild. There is no need to manually save the historical text.

The border line

LineBorderText(
    child: Text(
      "Border Effect",
      style: TextStyle(fontSize: 20),
    ),
    autoAnim: true)
    
Copy the code

LineBorderText supports any widget as a child, and the parameter autoAnim controls whether an animation is automatically performed at creation time.

Rainbow font

RainbowText(colors: [
  Color(0xFFFF2B22),
  Color(0xFFFF7F22),
  Color(0xFFEDFF22),
  Color(0xFF22FF22),
  Color(0xFF22F4FF),
  Color(0xFF5400F7),
], text: "Welcome to BBT", loop: true)

Copy the code

RainbowText temporarily supports the color change of text. The loop parameter controls whether the animation is looping.

Particle explosions

ExplosionWidget(
    tag: "Explosion Text",
    child: Container(
        alignment: Alignment.center,
        color: Colors.blueAccent,
        child: Text(
          "Explosion Text",
          style: TextStyle(
              fontSize: 20,
              color: Colors.red,
              fontWeight: FontWeight.bold),
        )))
Copy the code

ExplosionWidget supports any type of widget as a child. Note that the tag parameter indicates the uniqueness of the child. If you change the child, you must change the tag, otherwise rebuild will not execute the explosion effect.

Stung to

AnvilEffectWidget(child: Text(
  "👉 AnvilEffect 👈",
  style: TextStyle(color: Colors.white, fontSize: 20),Copy the code

AnvilEffectWidget supports any type of widget as a child;

Scratch CARDS

ScratchCardWidget(
    strokeWidth: 20,
    threshold: 0.5,
    foreground: (canvas, size, offset) {
      if(_image ! =null) {
        double scale;
        double dx = 0;
        double dy = 0;
        if (_image.width * size.height >
            size.width * _image.height) {
          scale = size.height / _image.height;
          dx = (size.width - _image.width * scale) / 2;
        } else {
          scale = size.width / _image.width;
          dy = (size.height - _image.height * scale) / 2;
        }
        canvas.save();
        canvas.translate(dx, dy);
        canvas.scale(scale, scale);
        canvas.drawImage(_image, Offset(0.0), new Paint());
        canvas.restore();
      } else {
        canvas.drawRect(
            Rect.fromLTWH(0.0, size.width, size.height), Paint() .. color = Colors.grey); } }, child: Container( color: Colors.blueAccent, alignment: Alignment.center, child: Image.asset("assets/images/icon_sm_sigin_status_three.png",
        fit: BoxFit.scaleDown, height: 20,)))Copy the code

ScratchCardWidget has more parameters, one by one:

  • strokeWidthWidth of hand touch;
  • threshold: the threshold that triggers the clearance of foreground coverings. The code logic is to calculate the proportion of fully transparent pixels;
  • foreground: This is the Function type. The purpose of this is to paint the foreground covering, which is the coating of the scratch card;
  • childThis is the content of the scratch card and supports any widget as a child;
  • (canvas, size, offset){}:foregroundThe correspondingFunctionType, support withcanvasRendering foreground coating;

More effects will continue to be updated, please stay tunedflutter_effects;

Next step

  • Optimize existing features: I used a week’s spare time to rush out the current function, it is inevitable that there are some improper, the matter is not more than fine, optimize performance and API call may be more important;
  • Submit to dart Pub: Commit to pub is certainly easy to use, before this, the module needs to be divided into a new division, perhaps into multiple package commit;
  • Introduction of events: Currently firing an animation in rebuild form is not a smart way;
  • Introduce more featuresIf it works well, I will try it.

Thank you:

During the implementation of this project, part of the inspiration came from the native code implementation:

Android Particle Explosion: github.com/tyrantgit/E…

TextView: github.com/hanks-zyh/H…

Thanks to Hanks and Tyrantgit for the above project.