I would like to achive an effect similar to the next one:
The idea is to have a fully displayed Icon in grey, and then in top of it the same Icon but in another color and only showing on the screen a percentage of the widget on top. I’ve tried to do it with Stack
and Align
(heightFactor
) but nothing worked well.
Any ideas?
EDIT: Here it’s the code I tried:
class TestWidget extends StatefulWidget {
const TestWidget({super.key});
@override
State<TestWidget> createState() => _TestWidgetState();
}
class _TestWidgetState extends State<TestWidget> {
GlobalKey aKey = GlobalKey();
@override
Widget build(BuildContext context) {
return Container(
color: Colors.grey[200],
child: Align(
alignment: const Alignment(-0.85, -0.85),
child: Wrap(children: [
Stack(
children: [
Center(
child: Icon(
key: aKey,
Symbols.thunderstorm,
color: Colors.blueGrey,
size: 100)),
Column(
children: [
LayoutBuilder(builder: (context, _) {
RenderBox renderbox =
aKey.currentContext!.findRenderObject() as RenderBox;
return SizedBox(height: renderbox.size.height * 0.25);
}),
const ClipRect(
child: Align(
heightFactor:
0.5, // Set this to 0.8 to see the displaced, unmatching image.
child: Icon(Symbols.thunderstorm,
color: Colors.red, size: 100),
))
],
)
],
)
]),
));
}
}
These are the outputs for 0.5 and 0.8 heightFactor
, respectively:
3
Answers
Inspired by @pskink's answer, I came up with this working example:
Which works as desired. The reason for it is because if you align the coloured widget to the top, the
heightFactor
cuts starting from there. You only need to insert the new cut widget in a Column with a SizedBox with the height you loose from the coloured one.I couldn't figure out how to configure the
Rect
object @pskink suggested, and it would be appreciated if he could give a detailed code with his full solution to complement this one.One way to achieve that is using an Stack and two icons, placing one icon above another, and using a ClipRect to cut superior’s icons in half, showing the bottom half of the icon behind. Here’s an example:
You can use
ShaderMask
widget to make a gradient color.I created this demo so you can see an example here. Run it and click on the icon to see the changes: