foil 0.9.0+1
foil: ^0.9.0+1 copied to clipboard
Wrap a widget with Foil, providing a rainbow shimmer that twinkles as the accelerometer moves as well as tons of neat gradient features.
Foil #
Wrap a widget with Foil, providing a rainbow shimmer
that twinkles as the accelerometer moves.
Consider holographic PokΓ©mon trading cards, some credit cards,
or an oil slick on the road.
![]() |
![]() |
|---|
π Table of Contents #
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'
Accelerometer #
![]()
This trading card is wrapped in twoFoilwidgets offering different gradients!
Further widget transformation provided by package:xl.
Disable this Foil's reaction to accelerometer sensor motion by
useSensor: false. Default is true.
- In this case, you may want to employ a
RollwithCrinkles.
Influence the intensity of this Foil's reaction to accelerometer motion
by providing a speed and custom Scalar property Foil.scalar.
- Default is
Scalar.identitywhich has both ahorizontalandvertical
multiplier 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.
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 aScalarobject like aFoiluses to scale its sensors data)
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,
);
}
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.
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 overriding
opacityparameter for semi-transparent appearance even without
Gradient.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. |
![]() |
|---|
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.
π 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












