Skip to content

Commit

Permalink
Merge pull request #5 from thecodexhub/feat/controller-revamp
Browse files Browse the repository at this point in the history
feat/controller: revamp controller structure
  • Loading branch information
thecodexhub authored Feb 3, 2024
2 parents 7f180ef + 81d0841 commit 6c3e19a
Show file tree
Hide file tree
Showing 9 changed files with 390 additions and 535 deletions.
100 changes: 69 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,72 +5,110 @@
[![License: MIT](https://img.shields.io/badge/License-MIT-purple.svg)](https://opensource.org/licenses/MIT)
[![Package Version](https://img.shields.io/pub/v/typethis.svg)](https://pub.dev/packages/typethis)

A flutter package that aims to simplify versatile typing animation with reset, freeze and unfreeze functionality.
A flutter package that aims to simplify versatile typing animation with rich text effects and other operations (reset, freeze, unfreeze).

## Create a TypeThis widget
## Create and style TypeThis widget

The `TypeThis` widget requires only one essential parameter: `string`. This parameter represents the text that will undergo animation.

Additionally, you can customize the animation speed using the optional `speed` parameter, with a default value of 50 milliseconds. This implies that each character in the provided text will be rendered at intervals of 50 milliseconds, creating a dynamic and engaging typing effect.

Here is an example:

```dart
final typeThisWidget = TypeThis(
// The text which will be animated.
string: 'Hi there! How are you doing?',
// Speed in milliseconds at which the typing animation will be executed.
speed: 100,
// Text style for the string.
style: const TextStyle(fontSize: 20),
TypeThis(
string: 'An example string with typing animation.',
speed: 150,
);
```

## Reset the animation
The `TypeThis` widget gives users the complete control over text rendering, offering all the parameters available in the standard `Text` widget.

```dart
// Call the `reset()` method on controller to reset the typing animation.
typeThisWidget.controller.reset();
TypeThis(
string: 'An example string with typing animation.',
speed: 150,
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
color: Colors.indigo,
),
textAlign: TextAlign.center,
);
```

## Freeze (pause) the animation
## Control the animation

To control the typing animation, create a `TypeThisController` and supply it to the `TypeThis` widget.

> 📘 **Important**
>
> Call `dispose` of the `TypeThisController` when you’ve finished using it. This ensures that you discard any resources used by the object.
```dart
// Call the `freeze()` method on controller to freeze/pause the typing animation.
typeThisWidget.controller.freeze();
// Define a custom widget.
class MyTypingWidget extends StatefulWidget { ... }
class _MyTypingWidgetState extends State<MyTypingWidget> {
// Create a typethis controller.
final myController = TypeThisController();
@override
void dispose() {
// Clean up the controller when the widget is disposed.
myController.dispose();
super.dispose();
}
}
```

## Unfreeze (resume) the animation
Now that you have a `TypeThisController`, wire it up to a text field using the controller property.

```dart
// Call the `unfreeze()` method on controller to unfreeze/resume the typing animation.
typeThisWidget.controller.unfreeze();
TypeThis(
string: 'An example string with typing animation.',
controller: myController,
);
```

## RichText effects
After supplying the `TypeThisController`, begin controlling the typing animatiomn. Use the reset() method provided by the TypeThisController to resets the typing animation and restart it from the beginning.

Similarly, use the freeze() and unfreeze() methods to pause/freeze and resume/unfreeze the animation respectively.

```dart
// Reset
myController.reset();
// Freeze / Pause
myController.freeze();
// Unfreeze / Resume
myController.unfreeze();
```

## Bring in RichText effects

One standout feature of this package is the ability to incorporate rich text styling within the typing animation.

Add rich text effects within typing animation using `TypeThisMatcher` that works with regex pattern.

```dart
final richTypeThisWidget = TypeThis(
TypeThis(
string: 'Welcome to the typethis package.',
speed: 100,
style: const TextStyle(fontSize: 18),
softWrap: true,
richTextMatchers: const [
TypeThisMatcher(
'typethis',
style: TextStyle(
fontWeight: FontWeight.bold,
fontStyle: FontStyle.italic,
decoration: TextDecoration.underline,
decorationColor: Colors.indigo,
color: Colors.indigo,
),
),
],
);
// Reset, freeze and unfreeze animation similarly
richTypeThisWidget.controller.reset();
richTypeThisWidget.controller.freeze();
richTypeThisWidget.controller.unfreeze();
```

Use the TypeThisController to manage and control the animations as well. [Read here](#control-the-animation).

## Demo

[![Demo](demo/typethis.gif)](https://github.com/thecodexhub/typethis)
Expand Down
139 changes: 98 additions & 41 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,41 +1,29 @@
import 'package:example/widgets/widgets.dart';
// import 'package:example/widgets/widgets.dart';
import 'package:flutter/material.dart';
import 'package:typethis/typethis.dart';

void main() {
runApp(const MyApp());
}

class MyApp extends StatelessWidget {
class MyApp extends StatefulWidget {
const MyApp({super.key});

@override
Widget build(BuildContext context) {
final typeThisWidget = TypeThis(
string: 'Hi there! How are you doing?',
speed: 100,
style: const TextStyle(fontSize: 18),
);
State<MyApp> createState() => _MyAppState();
}

final richTypeThisWidget = TypeThis(
string: 'Welcome to the typethis package.',
speed: 100,
style: const TextStyle(fontSize: 18),
softWrap: true,
richTextMatchers: const [
TypeThisMatcher(
'typethis',
style: TextStyle(
fontWeight: FontWeight.bold,
fontStyle: FontStyle.italic,
decoration: TextDecoration.underline,
decorationColor: Colors.indigo,
color: Colors.indigo,
),
),
],
);
class _MyAppState extends State<MyApp> {
final TypeThisController controller = TypeThisController();

@override
void dispose() {
controller.dispose();
super.dispose();
}

@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter TypeThis Demo',
theme: ThemeData(primarySwatch: Colors.deepPurple),
Expand All @@ -44,23 +32,92 @@ class MyApp extends StatelessWidget {
title: const Text('TypeThis Example'),
backgroundColor: Colors.grey[200],
),
body: Column(
children: [
SimpleDecoratedBox(
typeThisWidget: typeThisWidget,
onResetPressed: () => typeThisWidget.controller.reset(),
onFreezePressed: () => typeThisWidget.controller.freeze(),
onUnfreezePressed: () => typeThisWidget.controller.unfreeze(),
body: SimpleDecoratedBox(
onResetPressed: () => controller.reset(),
onFreezePressed: () => controller.freeze(),
onUnfreezePressed: () => controller.unfreeze(),
child: TypeThis(
string: 'An example string with typing animation.',
controller: controller,
speed: 100,
style: const TextStyle(fontSize: 16),
richTextMatchers: const [
TypeThisMatcher(
'typing',
style: TextStyle(
fontWeight: FontWeight.bold,
decoration: TextDecoration.underline,
fontStyle: FontStyle.italic,
),
),
],
),
),
),
);
}
}

class SimpleDecoratedBox extends StatelessWidget {
const SimpleDecoratedBox({
super.key,
required this.child,
required this.onResetPressed,
required this.onFreezePressed,
required this.onUnfreezePressed,
});
final Widget child;
final VoidCallback onResetPressed;
final VoidCallback onFreezePressed;
final VoidCallback onUnfreezePressed;

@override
Widget build(BuildContext context) {
return Container(
constraints: const BoxConstraints(maxWidth: 550),
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 48),
Container(
height: 60,
width: double.infinity,
padding: const EdgeInsets.symmetric(
vertical: 8,
horizontal: 16,
),
const SizedBox(height: 16),
RichDecoratedBox(
typeThisWidget: richTypeThisWidget,
onResetPressed: () => richTypeThisWidget.controller.reset(),
onFreezePressed: () => richTypeThisWidget.controller.freeze(),
onUnfreezePressed: () => richTypeThisWidget.controller.unfreeze(),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16),
color: Colors.grey[200],
),
],
),
child: child,
),
const SizedBox(height: 24),
Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
OutlinedButton.icon(
onPressed: onResetPressed,
icon: const Icon(Icons.refresh),
label: const Text('Reset'),
),
const SizedBox(width: 12),
OutlinedButton.icon(
onPressed: onFreezePressed,
icon: const Icon(Icons.pause),
label: const Text('Freeze'),
),
const SizedBox(width: 12),
OutlinedButton.icon(
onPressed: onUnfreezePressed,
icon: const Icon(Icons.play_arrow),
label: const Text('Unfreeze'),
),
],
),
],
),
);
}
Expand Down
91 changes: 0 additions & 91 deletions example/lib/widgets/rich_decorated_box.dart

This file was deleted.

Loading

0 comments on commit 6c3e19a

Please sign in to comment.