spoiler_widget 1.0.10
spoiler_widget: ^1.0.10 copied to clipboard
A Flutter package to create spoiler animations similar to the one used in Telegram, allowing you to hide sensitive or spoiler-filled content until it's tapped or clicked.
Spoiler Animation for Flutter #
A Flutter package to create spoiler animations similar to the one used in Telegram, allowing you to hide sensitive or spoiler-filled content until it's tapped or clicked.
Demo #
Features #
-
Spoiler Animation: Blur effect to hide content until tapped or hidden
-
Wave Effects: Optional wave/ripple expansions with
SpoilerSpotsController -
Particle System: Configure particle density, size, speed, color, etc.
-
Fade Animation: Smooth circular reveal/cover transitions
-
Gesture Control: Enable or disable gestures to users can tap toggle the spoiler.
-
Platform Agnostic: Works on iOS, Android, Web and more
Installation #
In your pubspec.yaml:
dependencies:
spoiler_widget: latest
Then run:
flutter pub get
Usage #
1. Basic Spoiler Usage #
Import the package:
import 'package:spoiler_widget/spoiler_widget.dart';
Wrap text or widgets you want to hide in a spoiler:
SpoilerOverlay(
configuration: WidgetSpoilerConfiguration(
isEnabled: true,
fadeRadius: 3,
fadeAnimation: true,
enableGesture: true,
imageFilter: ImageFilter.blur(sigmaX:30, sigmaY:30),
),
child: Text('Hidden Content'),
);
Or use the text-specific widget:
SpoilerText(
text: 'Tap me to reveal secret text!',
configuration: TextSpoilerConfiguration(
isEnabled: true,
fadeAnimation: true,
enableGesture: true,
style: TextStyle(fontSize: 16, color: Colors.black),
),
);
2. Wave Animations (SpoilerSpotsController) #
For dynamic "wave" effects:
class WaveDemo extends StatefulWidget {
const WaveDemo({super.key});
@override
State<WaveDemo> createState() => _WaveDemoState();
}
class _WaveDemoState extends State<WaveDemo> {
late SpoilerSpotsController _controller;
@override
void initState() {
super.initState();
_controller = SpoilerSpotsController(vsyn: this);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return SpoilerOverlay(
controller: _controller,
configuration: WidgetSpoilerConfiguration(
isEnabled: true,
maxActiveWaves: 3,
fadeAnimation: true,
enableGesture: true,
imageFilter: ImageFilter.blur(sigmaX:30, sigmaY:20),
),
child: Image.network('https://your-image-url'),
);
}
}
You’d call _controller.initParticles(...) once you know the widget size. Any time the spoiler is enabled, random wave effects will move particles outward until they fade.
3. Example
Below is a minimalist code sample:
import 'package:flutter/material.dart';
import 'package:spoiler_widget/spoiler_widget.dart';
import 'package:cached_network_image/cached_network_image.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
final String text = 'Tap to reveal a surprise spoiler!';
final String imageUrl =
'https://img.freepik.com/premium-photo/drawing-female-superhero-female-character_1308175-151081.jpg?w=1800';
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold
appBar: AppBar(
title: Text('Spoiler Widget Demo',
),
body: SingleChildScrollView(
child: Column(
children: [
// Text-based spoiler
SpoilerText(
config: TextSpoilerConfiguration(
isEnabled: true,
maxParticleSize: 1,
particleDensity: .2,
speedOfParticles: 0.2,
fadeRadius: 3,
fadeAnimation: true,
enableGesture: true,
selection: const TextSelection(baseOffset: 0, extentOffset: 30),
style: const TextStyle(fontSize: 28, color: Colors.black),
),
text: text,
),
// Widget-based spoiler
ClipRect(
child: SpoilerOverlay(
config: WidgetSpoilerConfiguration(
isEnabled: true,
maxParticleSize: 1,
particleDensity: 0.2,
speedOfParticles: 0.2,
fadeRadius: 3,
fadeAnimation: true,
enableGesture: true,
imageFilter: ImageFilter.blur(sigmaX:30, sigmaY:30),
),
child: CachedNetworkImage(imageUrl: imageUrl),
),
),
],
),
),
),
);
}
}
Configuration
Common Fields
Table showing common config parameters for both TextSpoilerConfiguration and WidgetSpoilerConfiguration.
| Field | Type | Description |
|---|---|---|
isEnabled |
bool | Whether the spoiler starts covered true. |
fadeAnimation |
bool | Whether to animate the spoiler fade in/out. |
fadeRadius |
double | The circle radius for radial fade. |
particleDensity |
double | The density of particles in the spoiler. |
maxParticleSize |
double | The maximum size of particles. |
speedOfParticles |
double | Speed factor for particle movement. |
enableGesture |
bool | Whether tapped toggle should be out of the box. |
TextSpoilerConfiguration
| Field | Type | Description |
|---|---|---|
style |
TextStyle? | The text style applied to the spoiler text. |
selection |
TextSelection? | Range of text to apply the spoiler. |
WidgetSpoilerConfiguration
| Field | Type | Description |
|---|---|---|
imageFilter |
ImageFilter? | Blur filter used to hide the child. |
maxActiveWaves |
int | Max concurrent waves for wave-based effects. |
FAQ
-
How can I animate the blur or wave concurrency? Adjust the properties in your configuration object at runtime. For instance, set a new imageFilter or call methods on the wave controller to dynamically tune the effect.
-
Can I skip the wave logic? Yes—by default, you get a basic spoiler with fade. Use SpoilerSpotsController only if you want wave animations.
-
Does this work on the web? Yes! It’s entirely in Flutter/Dart. Just ensure you handle any platform quirks with gesture input.
Contributing #
Contributions are welcome! Whether it’s bug fixes, new features, or documentation improvements, open a Pull Request or Issue.
License #
Licensed under the MIT License. Enjoy building your spoiler effects!