import 'dart:ui'; import 'package:flutter/material.dart'; class FadedScrollView extends StatefulWidget { final Widget child; final double fadeHeight; final double easingDistance; final double maxBlur; final ScrollController? controller; final EdgeInsetsGeometry? padding; const FadedScrollView({ super.key, required this.child, this.fadeHeight = 20.0, this.easingDistance = 10.0, this.maxBlur = 3.0, this.controller, this.padding, }); @override State createState() => _FadedScrollViewState(); } class _FadedScrollViewState extends State { late ScrollController _scrollController; @override void initState() { super.initState(); _scrollController = widget.controller ?? ScrollController(); } @override void dispose() { if (widget.controller == null) { _scrollController.dispose(); } super.dispose(); } @override Widget build(BuildContext context) { return AnimatedBuilder( animation: _scrollController, builder: (context, child) { final double offset = _scrollController.hasClients ? _scrollController.offset : 0.0; final double fadeProgress = (offset / widget.easingDistance).clamp(0.0, 1.0); final double currentBlur = widget.maxBlur * fadeProgress; return Stack( children: [ // Main content ShaderMask( shaderCallback: (Rect bounds) { final double fadeStop = widget.fadeHeight / bounds.height; final Color transparentColor = Colors.white.withOpacity(1.0 - fadeProgress); return LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [ transparentColor, Colors.white, Colors.white, ], stops: [0.0, fadeStop, 1.0], ).createShader(bounds); }, blendMode: BlendMode.dstIn, child: SingleChildScrollView( controller: _scrollController, padding: widget.padding, child: widget.child, ), ), // Single blur with extended fade area for smoother transition if (currentBlur > 0) Positioned( top: 0, left: 0, right: 0, height: widget.fadeHeight * 1.5, // Extend beyond fade area child: ClipRect( child: BackdropFilter( filter: ImageFilter.blur( sigmaX: currentBlur * 0.7, // Reduce intensity slightly sigmaY: currentBlur * 0.7, ), child: Container( decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [ Colors.transparent, Colors.transparent, Colors.transparent, Colors.black.withOpacity(0.0), ], stops: [0.0, 0.6, 0.9, 1.0], ), ), ), ), ), ), ], ); }, ); } }