搜尋套件、儲存庫與 APP 分類

widget_and_text_animator 封面
套件詳情v1.1.5

widget_and_text_animator

使用內建的多種效果輕鬆實現動畫小部件。透過交錯文字效果讓文字動畫更為美麗。支援轉場、模糊等效果,也能對手勢進行動畫處理。

AndroidiOSWebmacOSWindowsLinux
近 30 天下載
2930
喜歡數
262
Pub 分數
150

安裝套件

flutter pub add widget_and_text_animator

套件介紹

根據套件公開資料產生的選型評估,僅供參考。

Widget and Text Animator 是一個 Flutter 套件,可簡化為元件和文字建立動態動畫的過程。它提供多種內建效果,例如過渡、模糊和交錯文字動畫,讓開發者能透過流暢且視覺上吸引人的移動來增強使用者介面。此套件支援手勢動畫,並可於所有主要平台無縫整合。僅需最少設定,即可為靜態元素注入生氣,非常適合用於啟動畫面、引導流程和互動內容。

適用情境

  • 引導螢幕動畫
  • 啟動畫面效果
  • 互動式按鈕反饋
  • 文字揭示動畫
  • 動態列表項過渡
  • 動畫標題

主要特色

  • 內建動畫效果
  • 交錯文字動畫
  • 基於手勢的動畫支援
  • 跨平台相容性
  • 與現有組件的輕鬆整合
  • 平滑的過渡效果

適合對象

  • 尋求視覺精緻的UI設計師
  • 開發互動式應用的開發者
  • 需要動畫文字的專案
  • 具備引導或教學流程的應用程式
  • 希望快速原型設計的團隊

使用建議

  • 可能會稍微增加應用程式套件大小
  • 大量動畫帶來的效能影響
  • 複雜序列需要仔細掌握時機
  • 最適合與中等動畫複雜度搭配使用
  • 不建議在低端設備上使用大量並發動畫

原始 README

以下為關聯原始碼儲存庫的 README 原文快照,最新內容請造訪原始碼儲存庫。

widget and text animator

A collection of effects to make Widget Animations a breeze and Text animations look beautiful!

See a live preview running in your browser.

Supported Platforms

  • ALL

How to Use

# add this line to your dependencies
widget_and_text_animator: ^1.1.5
import 'package:widget_and_text_animator/widget_and_text_animator.dart';

Basics

The Widget WidgetAnimator can be wrapped around any widget to let you do effects on it without worrying about vsync, stateful classes and all the usual boilerplate code required. It provides you with three main features:

  • Incoming effects - effects that show when a widget first enters the screen
  • At rest effects - effects that are shown while the widget is visible
  • Outgoing effects - effects for if the widget is changed and is leaving the screen to be replaced

So for a really simple example where you might want to animate a Container appearing onto the screen you can just do the following:

  WidgetAnimator(
    incomingEffect: WidgetTransitionEffects.incomingSlideInFromBottom(),
    child: Container(
      width: 100,
      height: 100,
      color: Colors.blue,
    ),
  )

or maybe you would like it to swing backwards and forwards while displayed

  WidgetAnimator(
    atRestEffect: WidgetRestingEffects.swing(),
    child: Container(
      width: 100,
      height: 100,
      color: Colors.blue,
    ),
  )

The library comes with a collection of constructors such as WidgetTransitionEffects.incomingSlideInFromBottom() to allow for a range of really simple effect to be created with minimal code.

WidgetTransitionEffects are used for both incoming and outgoing effects and WidgetAtRestEffects are used when a widget is at rest.

Extending the two examples above, here's a version where both the incoming and at rest animations are combined :

  WidgetAnimator(
    incomingEffect: WidgetTransitionEffects.incomingSlideInFromBottom(),
    atRestEffect: WidgetRestingEffects.swing(),
    child: FloatingActionButton(
      onPressed: (){},
      tooltip: 'Increment',
      child: const Icon(Icons.add),
    ),
  )

Widget overview

The library comprises of four main Widgets which all have their own purpose:

  • WidgetAnimator Animates any widget with effects such as opacity, offset, blur, skew, rotation, scale

  • WidgetAnimatorSequence Animates a list of WidgetAnimator either based on Time or a user pressing on the widget (or both)

  • TextAnimator Can be used as a direct replacement for the standard Text widget, giving it animation superpowers

  • TextAnimatorSequence Similar to WidgetAnimatorSequence but works on TextAnimator widgets

Why does Text have it's own special widgets?

Although you can animate a Text widget easily with the WidgetAnimator, it'll operate on the text as a whole. The reason TextAnimator exists is it allows for processing effects on each character within a string creating some cool staggered effects. TextAnimator is a wrapper around WidgetAnimator handling some of the trickier parts of doing this yourself manually.

Here's some examples below:

Getting into more detail

In the earlier examples WidgetTransitionEffects and WidgetAtRestEffects were used to create some basic effects, but just with some default values. Let's take a look in more detail at what can be set for each:

WidgetTransitionEffects
property description default
offset set up the offset from the position that the widget would normally render, e.g. Offset(50, 20) would render 50 pixels to the right and 20 below the normal location, Offset(-50, -20) would render 50 pixels to the left and 20 above the normal location Offset(0,0)
skew Skew, the amount of skew on the X and Y axis e.g. Offset(0.2, 0.5) would be a skew of 0.2 on the X axis and 0.5 on the Y axis Offset(0,0)
scale The scale proportion compared to the widgets normal size, the default scale is 1.25x the normal size, use smaller numbers such as 0.5 to decrease the size and values larger 1
blur Blur, the amount of blur on the X and Y axis e.g. Offset(2, 5) would be a blur of 2 on the X axis and 5 on the Y axis, note that this effect can be quite performance intensive, so try to limit the amount it's used Offset(0,0)
rotation The rotation in radians, so math.pi/0.5 will rotate a full circle, math.pi/6 will rotate a small amount 0
opacity An opacity range from 0..1 1
curve A curve for the animation tween the play, Curves.Linear if you want it the animation to play at a constant speed, but you can also use things like Curves.bounce to bounce the effect Curve.eastInOut
builder The builder allows you to create your own more complicated version of the animations available by default, find more details about the builders below in the custom animation section null
duration The duration the animation should play for Duration(milliseconds: 300)
delay The length of time before the animation starts to play null
WidgetAtRestEffects

There are a collection of default constructors available to make standard effects simple to create:

WidgetRestingEffects.wave()

Wave the widget up and then down on it's Y axis

WidgetRestingEffects.pulse()

Pulse up and down the opacity of the widget

WidgetRestingEffects.rotate()

Rotate the widget around 360 degrees

WidgetRestingEffects.bounce()

Lift the widget and then bounce it back down

WidgetRestingEffects.slide()

Skew the widget from side-to-side based on a center axis

WidgetRestingEffects.swing()

Swing the widget back and forwards using rotation

WidgetRestingEffects.size()

Change the size of the widget, by default larger - effectStrength parameter can make it smaller too

WidgetRestingEffects.fidget()

Randomly shuffle the widget on both it's X and Y axis

WidgetRestingEffects.dangle()

Skew the widget from side-to-side based on a top center axis

WidgetRestingEffects.vibrate()

Randomly move the widget from its standard position on the X and Y axis

For more control you can specify a collection of properties into the constructors:

property description default
style Style requires an enum from `WidgetRestingEffectStyle' where 10 different effects are available WidgetRestingEffectStyle.none
effectStrength Based on the style above, most effects have a default strength for them, for example when using WidgetRestingEffectStyle.fidget the Widget will randomly move about from it's original position. Changing the effectStrength you can increase or decrease the amount of movement that happens 1
alignment Used only for skew based effects to change the position that the effect takes place from Alignment.center
numberOfPlays The number of times the animation should play before stopping, negative values and null will cause the animation to play forver null (ie repeat forever)
curve A curve for the animation tween the play, Curves.Linear if you want it the animation to play at a constant speed, but you can also use things like Curves.bounce to bounce the effect Curve.eastInOut
builder The builder allows you to create your own more complicated version of the animations available by default, find more details about the builders below in the custom animation section null
duration The duration the animation should play one cycle for Duration(milliseconds: 600)
delay The length of time before the animation starts to play null

WidgetAnimatorSequence

WidgetAnimatorSequence animates a list of WidgetAnimator either based on Time or a user pressing on the widget (or both). .

property description default
children A list of WidgetAnimator for the sequence to play against null, a list is required
tapToProceed If true allows the user to tap on the widget and proceed to displaying the next child in the list of children false
loop Once the list of children has been displayed, does the list loop back to the start false
transitionTime The length of time to wait between changing the widget once in input transition has completed, not specifying a duration will mean it won't change the sequence automatically null
onPressed callback function to perform if the widget is pressed on null

Here's an example displaying 3 containers that change automatically every 4 seconds and each have their own animation effects

    return WidgetAnimatorSequence(
      children: [
        WidgetAnimator(
            key: const ValueKey('one'),
            incomingEffect: WidgetTransitionEffects.incomingScaleDown(),
            outgoingEffect: WidgetTransitionEffects.outgoingScaleUp(),
            child: Container(width: 200,height: 200,color: Colors.red,child: Align(alignment: Alignment.centerLeft,child: Text('Red',style: GoogleFonts.sanchez(textStyle: const TextStyle(fontWeight: FontWeight.w900, letterSpacing: -2, fontSize: 56)),)))),
        WidgetAnimator(
            key: const ValueKey('two'),
            incomingEffect: WidgetTransitionEffects.incomingSlideInFromLeft(),
            outgoingEffect: WidgetTransitionEffects.outgoingSlideOutToBottom(),
            child: Container(width: 200,height: 200,color: Colors.green,child: Align(alignment: Alignment.centerLeft,child: Text('Green',style: GoogleFonts.sanchez(textStyle: const TextStyle(fontWeight: FontWeight.w900, letterSpacing: -2, fontSize: 56)),)))),
        WidgetAnimator(
            key: const ValueKey('two'),
            incomingEffect: WidgetTransitionEffects(blur: const Offset(2,2), duration: const Duration(milliseconds: 600)),
            atRestEffect: WidgetRestingEffects.slide(),
            outgoingEffect: WidgetTransitionEffects(blur: const Offset(2,2), duration: const Duration(milliseconds: 600)),
            child: Container(width: 200,height: 200,color: Colors.blue,child: Align(alignment: Alignment.centerLeft,child: Text('Blue',style: GoogleFonts.sanchez(textStyle: const TextStyle(fontWeight: FontWeight.w900, letterSpacing: -2, fontSize: 56)),))))
      ],
      tapToProceed: true,
      loop: true,
      transitionTime: const Duration(seconds: 4),
    );

TextAnimator

Can be used as a direct replacement for the standard Text widget, giving it animation superpowers. TextAnimator uses WidgetAnimator as its basis for the animation, but splits the text into characters and words to be able to create some nice effects.

property description default
text The [String] of text to display null, but a string of text is required
WidgetTransitionEffects The incoming effects to play when the text is first shown null
WidgetRestingEffects The effects to show when the text isn't incoming or outgoing null
WidgetTransitionEffects the maximum number of lines of text to show within the widget, used in the same way as the standard [Text] widget null
maxLines The outgoing effects to play when the text is replaced null
textAlign The [TextAlign] of the text, in the same was it's used in the [Text] widget null
textStyle The [TextStyle] of the text, in the same was it's used in the [Text] widget null
initialDelay The length of time to wait before starting to show any of the text null
characterDelay A delay to leave between each character of text to display to create a staggered text animation effect, if you want words to appear at once, then set a Duration of zero null
spaceDelay The delay to leave between each word before showing the next. If set the same as the characterDelay the timing will be consistent for all characters. It can be used to drive the timing per word if characterDelay is set to zero null

Here's a basic example of some text within a container using the TextAnimator to make the text wave up and down with a delay between each character

  return Container(width: 200, height: 200, color: Colors.red, 
    child: TextAnimator('Wave text', atRestEffect: WidgetRestingEffects.wave(),)
  );

TextAnimatorSequence

TextAnimatorSequence Animates a list of TextAnimator either based on Time or a user pressing on the text (or both).

property description default
children A list of TextAnimator for the sequence to play against null, a list is required
tapToProceed If true allows the user to tap on the text and proceed to displaying the next child in the list of children false
loop Once the list of children has been displayed, does the list loop back to the start false
transitionTime The length of time to wait between changing the text once in input transition has completed, not specifying a duration will mean it won't change the sequence automatically null
onPressed callback function to perform if the text is pressed on null

Here's an example which changes between 3 strings of text every 4 seconds or when clicked upon, each with their own incoming and outgoing animation styles

return TextAnimatorSequence(
  children: [
      TextAnimator('Red',
        incomingEffect: WidgetTransitionEffects.incomingScaleDown(),
        atRestEffect: WidgetRestingEffects.bounce(),
        outgoingEffect: WidgetTransitionEffects.outgoingScaleUp(),
        style: GoogleFonts.sanchez(textStyle: const TextStyle(fontWeight: FontWeight.w900, color: Colors.red, letterSpacing: -2, fontSize: 64))),
      TextAnimator('Green',
        incomingEffect: WidgetTransitionEffects.incomingSlideInFromLeft(),
        atRestEffect: WidgetRestingEffects.fidget(),
        outgoingEffect: WidgetTransitionEffects.outgoingSlideOutToBottom(),
        style: GoogleFonts.sanchez(textStyle: const TextStyle(fontWeight: FontWeight.w900, color: Colors.green, letterSpacing: -2, fontSize: 64))),
      TextAnimator('Blue',
        incomingEffect: WidgetTransitionEffects(blur: const Offset(2, 2), duration: const Duration(milliseconds: 600)),
        atRestEffect: WidgetRestingEffects.wave(),
        outgoingEffect: WidgetTransitionEffects(blur: const Offset(2, 2), duration: const Duration(milliseconds: 600)),
        style: GoogleFonts.sanchez(textStyle: const TextStyle(fontWeight: FontWeight.w900, color: Colors.blue, letterSpacing: -2, fontSize: 64))),
  ],
tapToProceed: true,
loop: true,
transitionTime: const Duration(seconds: 4),
);

Keys

In a similar way to which widgets such as AnimatedSwitcher work changes are detected on the WidgetAnimator by a change in type of the child widget or by the child widget having a different key, without either of these differences the Widget will not be aware of the changes that have happened and you'll either miss any outgoing transitions or will have no change in widget at all.

So for example if you have two different coloured containers that you want to switch both would need their own key

  WidgetAnimator(
    incomingEffect: WidgetTransitionEffects.incomingSlideInFromLeft(),
    outgoingEffect: WidgetTransitionEffects.outgoingSlideOutToRight(),
    child: isBlue ? Container(key: ValueKey('blue'), width: 100, height: 100, color: Colors.blue) : 
                    Container(key: ValueKey('red'), width: 100, height: 100, color: Colors.red) 
  )

Custom animations

Do you want to create an effect that's not possible with the default effects? Then you may be able to create the effect you want with the builder properties. With these you need to return an AnimationSettings object and you are then free to define your own animation settings for the properties available. Find an example below which draws a container and while it's at rest moves it in a trianglar pattern by adjusting the x and y offset over the duration of the animation:

WidgetAnimator(
atRestEffect: WidgetRestingEffects(
duration: const Duration(seconds: 3),
builder: (WidgetRestingEffects effects, AnimationController animationController) {
  AnimationSettings _animationSettings = AnimationSettings(animationController: animationController);
  _animationSettings.offsetYAnimation = TweenSequence<double>(
  [TweenSequenceItem<double>(tween: Tween<double>(begin: 0, end: 150).chain(CurveTween(curve: Curves.easeInOut)),weight: 33.0,),
  TweenSequenceItem<double>(tween: Tween<double>(begin: 150, end: 150).chain(CurveTween(curve: Curves.easeInOut)),weight: 33.0,),
  TweenSequenceItem<double>(tween: Tween<double>(begin: 150, end: 0).chain(CurveTween(curve: Curves.easeInOut)),weight: 33.0,),],
).animate(CurvedAnimation(parent: animationController, curve: Curves.linear));

_animationSettings.offsetXAnimation = TweenSequence<double>(
  [TweenSequenceItem<double>(tween: Tween<double>(begin: 0, end: 80).chain(CurveTween(curve: Curves.easeInOut)),weight: 33.0,),
  TweenSequenceItem<double>(tween: Tween<double>(begin: 80, end: -80).chain(CurveTween(curve: Curves.easeInOut)),weight: 33.0,),
  TweenSequenceItem<double>(tween: Tween<double>(begin: -80, end: 0).chain(CurveTween(curve: Curves.easeInOut)),weight: 33.0,),],
).animate(CurvedAnimation(parent: animationController, curve: Curves.linear));

return _animationSettings;
},),
child: Container(
  width: 200,
  height: 200,
  color: Colors.amber,
  child: const Center(
  child: Padding(
  padding: EdgeInsets.all(8.0),
  child: Text('Hello'),
  )),
),
)

GestureAnimator

This widget can be used as a direct replacement for the GestureDetector. It only covers basic onTap gestures, but allows you to animate effects on the widget pressed with just a few properties:

property description default
duration The [Duration] of the animation 150 milliseconds
curve The animation curve to use Curves.linear
scaleSize The size to reduce or increase by when the gesture is triggered 0.9
yOffset The amount of pixels to offset up or down the screen 0
xOffset The amount of pixels to offset across the screen 0
blurX The amount of blur on the x axis to apply to the child 0
blurY The amount of blur on the y axis to apply to the child 0
skewX The amount of skew on the x axis to apply to the child 0
skewY The amount of skew on the y axis to apply to the child 0
rotation The amount to rotate the child widget when the gesture is triggered 0
opacity The amount of opacity to trigger when the gesture is triggered 0
hapticFeedback The haptic feedback style to trigger when the gesture is triggered, this is useful if using triggerOnTapAfterAnimationComplete otherwise doing the haptic feedback in the onTap will seem delayed null
triggerOnTapAfterAnimationComplete Delay triggering the onTap callback until after the animation has played, otherwise you may not see much of the animation if navigating to another page false
onTap The code to call when a user taps on the widget null
child The child widget to render null

Here's a basic example of some text within a container using the TextAnimator to make the text wave up and down with a delay between each character

  return GestureAnimator(
    curve: Curves.easeInOut,
    scaleSize: 0.9,
    yOffset: -5,
    duration: const Duration(milliseconds: 150),
    // blurX: 2,
    // blurY: 2,
    // numberOfPlays: 4,
    // rotation: pi / 16,
    // skewX: 0.2,
    opacity: 0.8,
    hapticFeedback: HapticFeedback.selectionClick,   
    triggerOnTapAfterAnimationComplete: true,
    onTap: (){
      Navigator.of(context).push(Samples.route());
    },
    child: Padding(
        padding: const EdgeInsets.all(8.0),
        child: Container(color: Colors.green, child: const Padding(
        padding: EdgeInsets.all(12.0),
        child: Text('Do not push me!'),
      ),),
   ),);

Give me more!

For more examples check out the example project on github.

If you find issues or want new features...

If you come across any issues, please check out the outstanding issues here and raise a new issue if required.

Pull requests welcome, new feature suggestions can be created here

Buy Me a Coffee

If you appreciate this package, you may buy me a coffee...

Buy Me A Coffee

所屬分類

原始碼儲存庫

使用此套件的專案

暫無相關資料。