Rebrand as TPSchedule and refine clear liquid glass dock
This commit is contained in:
@@ -8,9 +8,13 @@ class GlassRefraction extends StatefulWidget {
|
||||
const GlassRefraction({
|
||||
super.key,
|
||||
required this.strength,
|
||||
this.blurSigma = 2,
|
||||
required this.child,
|
||||
});
|
||||
final double strength;
|
||||
|
||||
/// Optical softness in logical pixels, independent of display density.
|
||||
final double blurSigma;
|
||||
final Widget child;
|
||||
@override
|
||||
State<GlassRefraction> createState() => _GlassRefractionState();
|
||||
@@ -18,6 +22,7 @@ class GlassRefraction extends StatefulWidget {
|
||||
|
||||
class _GlassRefractionState extends State<GlassRefraction> {
|
||||
static Future<ui.FragmentProgram>? _program;
|
||||
static ui.FragmentProgram? _loadedProgram;
|
||||
ui.FragmentShader? _shader;
|
||||
@override
|
||||
void initState() {
|
||||
@@ -27,12 +32,12 @@ class _GlassRefractionState extends State<GlassRefraction> {
|
||||
|
||||
Future<void> _load() async {
|
||||
try {
|
||||
final program = await (_program ??= ui.FragmentProgram.fromAsset(
|
||||
'shaders/liquid_glass.frag',
|
||||
));
|
||||
final program = _loadedProgram ??= await (_program ??=
|
||||
ui.FragmentProgram.fromAsset('shaders/liquid_glass.frag'));
|
||||
if (mounted) setState(() => _shader = program.fragmentShader());
|
||||
} catch (error) {
|
||||
_program = null;
|
||||
_loadedProgram = null;
|
||||
debugPrint('Glass refraction unavailable: $error');
|
||||
}
|
||||
}
|
||||
@@ -46,12 +51,17 @@ class _GlassRefractionState extends State<GlassRefraction> {
|
||||
@override
|
||||
Widget build(BuildContext context) => _shader == null
|
||||
? BackdropFilter(
|
||||
filter: ui.ImageFilter.blur(sigmaX: 0.6, sigmaY: 0.6),
|
||||
filter: ui.ImageFilter.blur(
|
||||
sigmaX: widget.blurSigma,
|
||||
sigmaY: widget.blurSigma,
|
||||
tileMode: TileMode.clamp,
|
||||
),
|
||||
child: widget.child,
|
||||
)
|
||||
: _LiveGlassFilter(
|
||||
shader: _shader!,
|
||||
strength: widget.strength,
|
||||
blurSigma: widget.blurSigma,
|
||||
pixelRatio: MediaQuery.devicePixelRatioOf(context),
|
||||
child: widget.child,
|
||||
);
|
||||
@@ -61,29 +71,41 @@ class _LiveGlassFilter extends SingleChildRenderObjectWidget {
|
||||
const _LiveGlassFilter({
|
||||
required this.shader,
|
||||
required this.strength,
|
||||
required this.blurSigma,
|
||||
required this.pixelRatio,
|
||||
required super.child,
|
||||
});
|
||||
final ui.FragmentShader shader;
|
||||
final double strength, pixelRatio;
|
||||
final double strength, blurSigma, pixelRatio;
|
||||
@override
|
||||
_RenderLiveGlass createRenderObject(BuildContext context) =>
|
||||
_RenderLiveGlass(shader, strength, pixelRatio);
|
||||
_RenderLiveGlass(shader, strength, blurSigma, pixelRatio);
|
||||
@override
|
||||
void updateRenderObject(
|
||||
BuildContext context,
|
||||
_RenderLiveGlass renderObject,
|
||||
) => renderObject.update(shader, strength, pixelRatio);
|
||||
) => renderObject.update(shader, strength, blurSigma, pixelRatio);
|
||||
}
|
||||
|
||||
class _RenderLiveGlass extends RenderProxyBox {
|
||||
_RenderLiveGlass(this._shader, this._strength, this._pixelRatio);
|
||||
_RenderLiveGlass(
|
||||
this._shader,
|
||||
this._strength,
|
||||
this._blurSigma,
|
||||
this._pixelRatio,
|
||||
);
|
||||
ui.FragmentShader _shader;
|
||||
double _strength, _pixelRatio;
|
||||
double _strength, _blurSigma, _pixelRatio;
|
||||
final _layer = LayerHandle<BackdropFilterLayer>();
|
||||
void update(ui.FragmentShader shader, double strength, double pixelRatio) {
|
||||
void update(
|
||||
ui.FragmentShader shader,
|
||||
double strength,
|
||||
double blurSigma,
|
||||
double pixelRatio,
|
||||
) {
|
||||
_shader = shader;
|
||||
_strength = strength;
|
||||
_blurSigma = blurSigma;
|
||||
_pixelRatio = pixelRatio;
|
||||
markNeedsPaint();
|
||||
}
|
||||
@@ -103,7 +125,17 @@ class _RenderLiveGlass extends RenderProxyBox {
|
||||
..setFloat(5, size.height * _pixelRatio)
|
||||
..setFloat(6, _strength);
|
||||
_layer.layer ??= BackdropFilterLayer();
|
||||
_layer.layer!.filter = ui.ImageFilter.shader(_shader);
|
||||
// Refract the original backdrop first, then diffuse it with the engine's
|
||||
// separable Gaussian blur. Keeping the shader inside the composition also
|
||||
// keeps its source texture coordinates independent of blur padding.
|
||||
_layer.layer!.filter = ui.ImageFilter.compose(
|
||||
outer: ui.ImageFilter.blur(
|
||||
sigmaX: _blurSigma,
|
||||
sigmaY: _blurSigma,
|
||||
tileMode: TileMode.clamp,
|
||||
),
|
||||
inner: ui.ImageFilter.shader(_shader),
|
||||
);
|
||||
context.pushLayer(_layer.layer!, super.paint, offset);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user