π nonsense_foil
This is forked from FOIL Much of the doch were just copied, then updated. This also removes the need for sensors for foil. if you prefer sensors use the original package.
pub.dev Listing | API Doc | GitHub
API References: Foil | [
Foils](https://pub.dev/documentation/foil/latest/foil/Foils-class.html) |
Roll |
PointerTracker |
Crinkle |
Foil.sheet |
Steps |
GradientUtils
Wrap a widget with Foil, providing a rainbow shimmer
that twinkles as the pointer (mouse/touch) moves over it.
Consider holographic PokΓ©mon trading cards, some credit cards, or an oil slick on the road.
![]() |
![]() |
|---|
π Table of Contents
- π Foil
- Getting Started
- Advanced Usage
- Extra Goodies
- Reference
- π API Documentation
-
FoilDemo: π·ββοΈ source code, π² built APK - π£οΈ Roadmap
- π Bugs
- πΈ More by Zaba
Getting Started
Wrap a widget by providing it as Foil.child.
Use any gradient
of choice and determine the blendMode to mask the gradient
onto the child in different ways. Default is BlendMode.srcATop which will
reveal the child through the gradient if the gradient has opacity or if
Foil.opacity is provided a non-1.0 value.
- Use
BlendMode.srcInto paint only the gradient and use the child as a mask.
Flag isUnwrapped toggles this Foil's invisibility. Default is false.
When this value is changed, the gradient will smoothly animate to a disabled
state, leaving only the child behind.
class Example extends StatelessWidget {
const Example({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) =>
FittedBox(
child: Foil(
child: const Text(
'FOIL',
style: TextStyle(fontWeight: FontWeight.w900)
),
),
);
}
Quickstart
Plop an instance of this
const Example()in a runningListViewyou've got open in a code editor. Run terminal commandflutter pub add foil.import 'package:foil/foil.dart'
Pointer Tracking
This trading card is wrapped in two
Foilwidgets offering different gradients! Further widget transformation provided by package:xl.
π TABLE OF CONTENTS
By default, the Foil widget reacts to pointer movement (touch or mouse), creating a shimmering effect
as the pointer moves over it. This provides an interactive holographic-like experience
across all platforms.
Disable this Foil's reaction to pointer tracking by
useSensor: false. Default is true.
- In this case, you may want to employ a
RollwithCrinkles for animation.
Influence the intensity of this Foil's reaction to pointer movement
by providing a speed and custom
Scalar property
Foil.scalar.
- Default is
Scalar.identitywhich has both ahorizontalandverticalmultiplier of+1.0.
Transitioning
Control how rapidly this Foil transforms its gradient with Foil.speed
and define the animation curve. Defaults are 150ms and Curves.ease.
![]() |
Furthermore, provide Foil.duration to dictate how long intrinsic animations of gradient will take. Foil.duration is also used if isUnwrapped is made true as the duration over which Foil.gradient will lerp to an appropriately-Typed transparent gradient for tweening. There is hard-coded recognition for linear, radial, and sweep gradients, as well as the additional Steps variants this package provides. Falls back to a transparent LinearGradient if Type cannot be matched. Override with Foil.unwrappedGradient. Click images to view full size. |
![]() |
|---|
Upon completion of any tween to a new
gradient, thisFoilwill callonEnd, an optional void callback.
π TABLE OF CONTENTS
Advanced Usage
Rolls
Wrap any Foil (or many of them!) in a
Roll higher in the
widget tree
to provide some inherited properties.
A gradient provided by an ancestral Roll may be used by as a Foil.gradient
if one is not explicitly perscribed in the Foil.
- If neither an ancestral
Rollnor aFoildictates its owngradient, then the default isFoils.linearLooping. - A descendent that provides its own
Foil.gradientwill override theRoll.gradient.
One day a
Rollwill also provide the option to "cut" any descendentFoilfrom a single shared gradient sheet that covers a space the size of theRoll.
Rolls can also serve to provide animation properties to a descendent Foil,
regardless of whether its serving its gradient.
Crinkles
These animations are in addition to any accelerometer sensors data
already animating the Foil unless Foil.useSensors: false.
Crinkle.smoothis a non-animated presetCrinkle.crawlingis a very slow moving presetCrinkle.twinklingis a little bit fasterCrinkle.vivaciousis highly-animated- Build your own or opt to
Crinkle.copyWitha preset
isAnimated,shouldReverseflags
- Use
periodto determine the animation loopDuration
- The
scalarproperty can be used to invert, scale, or negate axes(this is a
Scalarobject like aFoiluses to scale its sensors data)
π TABLE OF CONTENTS
TransformGradient
This is
the definition of a function
that takes in a scaled double x and double y
and returns a GradientTransform object. That object is used when a Foil's
gradient shader is drawn by calling its transform() method.
To provide a custom transformation as Crinkle.transform, extend that class
and override transform(), returning some Matrix4, such as the default
for this package:
class TranslateGradient extends GradientTransform {
/// The default [TransformGradient] for `Foil`.
/// This class's [transform] method considers [TextDirection] and
/// will consider positive values as translation to the right if `ltr`
/// and translate left for positive values if `rtl`.
const TranslateGradient({required this.percentX, required this.percentY});
final double percentX, percentY;
/// Returning `null` here is equivalent to returning `Matrix4.identity`.
@override
Matrix4? transform(Rect bounds, {TextDirection? textDirection}) =>
Matrix4.translationValues(
(textDirection == TextDirection.rtl ? -1.0 : 1.0) * bounds.width * percentX,
bounds.height * percentY,
0.0,
);
}
π TABLE OF CONTENTS
Extra Goodies
This package also comes with some other offerings.
Some expand on Gradient functionality, and others make them simpler to use.
Up first is named Foil.sheet which functions
like a self-contained
Foil + AnimatedContainer. Stylized by a Sheet
which simply wraps
parameters for the AnimatedContainer.
Steps
The basic premise of a gradient is to gradate between colors.
Consider new Steps to be extensions of Gradients,
one each for linear, radial, and sweep,
where the colors do not gradate but instead hard-transition. Like steps!
RadialSteps are great for making rainbows.
|
SweepSteps|RadialSteps|LinearSteps|
GradientUtils Extensions
Along with the three new variety of Gradient, this package
provides π copyWith() methods for each existing Flutter type.
final copy = RadialGradient( colors: [. . .], stops: [. . .], center: const Alignment(0, 0), ).copyWith(center: const Alignment(-2, -2));Even the superclass
Gradientmay be copied, providedthisis a standard linear, radial, or sweep gradient, or one of the three new steps gradients (falls back to a standard linear gradient). Provides every potential copyable parameter from the varieties. Most useful in a scenario where a common parameter likecolorsortransformis to be applied to some arbitraryGradient.
π TABLE OF CONTENTS
This makes it a cinch to pick out pre-rolled Foils
yet tweak them for specific scenarios--such as changing
start and end points while maintaining the list of colors.
What are Foils?
Foils
Finally, this package is bundled with a selection of pre-defined gradients.
One such pre-rolled Foils.oilslick has opacity within each Color.
- But consider that the
Foilconstructor accepts an overridingopacityparameter for semi-transparent appearance even withoutGradient.colorsthat have opacity.
Find other options like Foils.gymClassParachute and Foils.sitAndSpin,
then tweak them to your liking with the π Gradient.copyWith() methods.
![]() |
![]() |
|---|
There is even a literal rainbow decal gradient made with the new RadialSteps type. Click image to view full size. |
![]() |
|---|
π TABLE OF CONTENTS
Reference
π API Documentation
Foil Demo: π·ββοΈ source code,
π² built APK
π£οΈ Roadmap
- Make available a
RollofFoilfeature such that a developer could deploy a single gradient sheet in a region and mask that single gradient to any childFoilwidgets.Rolls are implemented now, but only offer to pass aGradientto descendentFoils--not to mask them from the same gradient.
- If this package's
Gradientsupport expands further, much of that functionality could be forked to an independent package. - Custom
GradientTransforms will be investigated, for example: to deformFoils.oilslick. - Additional pointer tracking features:
- Option to adjust tracking sensitivity based on movement speed
- Support for multi-touch interactions
- Add spring physics for more natural gradient movement
π Bugs
- Potential optimizations for
GradientTweening withinlerp(), especially with the newStepsstyle gradients. - Because this package's
copyWith()method for the superclassGradientis used when applyingCrinkletransformation, the returned gradient is limited by the hard-coded return types of thecopyWithmethod; that is to say: the three FlutterGradients and the threeStepsgradients added by this package.- If a bespoke
Gradienttype is used for someFoilthat is wrapped in aRollwhoseCrinkleprovides animation, that gradient will become aLinearGradientwith the appropriate colors at least. - In this scenario, until this bug is patched, consider transforming the
gradient prior to providing it to your
Crinkle-animatedFoilin order to maintain the bespokeGradient.
- If a bespoke
- Pointer tracking might behave inconsistently on some devices when the widget
is deeply nested in scrollable containers. In these cases, consider using a
RollwithCrinkleanimations instead of relying solely on pointer tracking.









| 


