Eray Erdin
Eray Erdin

Reputation: 3149

How do I reverse mask a widget on top of another widget in Flutter?

I have a RawMaterialButton as below:

RawMaterialButton(
  onPressed: () {},
  fillColor: Colors.white,
  padding: const EdgeInsets.all(15),
  shape: const CircleBorder(),
  child: Icon(
    Icons.chevron_right,
    size: 35,
    color: context.primaryColor,
  ),
)

It looks like this on a page:

button looks like this

However, the background is gradient and it is animated, so it changes color constantly. The color of the right chevron icon also should change color depending on the background. I thought maybe there's a way to use right chevron icon as kind-of a reverse mask. It should be transparent and show what's behind its parent.

I'm also going to implement a same kind of design with a container containing a text where the text is transparent and shows the background of its parent container.

Is there a straightforward way to do this in Flutter.

Thanks in advance.


Environment

Flutter doctor says:

[✓] Flutter (Channel stable, 3.7.0, on Fedora Linux 36 (KDE Plasma) 6.1.8-100.fc36.x86_64, locale en_US.UTF-8)
    • Flutter version 3.7.0 on channel stable at /home/erayerdin/.local/lib/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision b06b8b2710 (11 days ago), 2023-01-23 16:55:55 -0800
    • Engine revision b24591ed32
    • Dart version 2.19.0
    • DevTools version 2.20.1

[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
    • Android SDK at /home/erayerdin/.sdks/android/
    • Platform android-33, build-tools 33.0.0
    • ANDROID_SDK_ROOT = /home/erayerdin/.sdks/android
    • Java binary at: /var/lib/snapd/snap/android-studio/125/android-studio/jre/bin/java
    • Java version OpenJDK Runtime Environment (build 11.0.13+0-b1751.21-8125866)
    • All Android licenses accepted.

[✓] Chrome - develop for the web
    • Chrome at google-chrome

[✓] Linux toolchain - develop for Linux desktop
    • clang version 14.0.5 (Fedora 14.0.5-2.fc36)
    • cmake version 3.25.2
    • ninja version 1.10.2
    • pkg-config version 1.8.0

[✓] Android Studio (version 2021.3)
    • Android Studio at /var/lib/snapd/snap/android-studio/125/android-studio
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 11.0.13+0-b1751.21-8125866)

[✓] VS Code
    • VS Code at /snap/code/current
    • Flutter extension version 3.58.0

[✓] Connected device (3 available)
    • sdk gphone64 x86 64 (mobile) • emulator-5554 • android-x64    • Android 13 (API 33) (emulator)
    • Linux (desktop)              • linux         • linux-x64      • Fedora Linux 36 (KDE Plasma) 6.1.8-100.fc36.x86_64
    • Chrome (web)                 • chrome        • web-javascript • Google Chrome 109.0.5414.119

[✓] HTTP Host Availability
    • All required HTTP hosts are available

• No issues found!

Upvotes: 0

Views: 334

Answers (1)

Mobin Ansar
Mobin Ansar

Reputation: 710

Try This Code:

import 'package:flutter/cupertino.dart';
    import 'package:flutter/cupertino.dart';
    import 'package:flutter/cupertino.dart';
    import 'package:flutter/material.dart';
    
    class GradietnColor extends StatefulWidget {
      const GradietnColor({Key? key}) : super(key: key);
    
      @override
      State<GradietnColor> createState() => _GradietnColorState();
    }
    
    class _GradietnColorState extends State<GradietnColor> {
      List<Color> arrColors = [Colors.green.withOpacity(0.30), Colors.yellow.withOpacity(0.10)] ;
      @override
      Widget build(BuildContext context) {
        return Scaffold(
    
          body: Center(
            child: Stack(
              children: [
    
                Container(
                  height: 200,
                  width: 200,
                  decoration: BoxDecoration(
                    gradient: LinearGradient(
                      begin: Alignment.topRight,
                      end: Alignment.bottomLeft,
                      colors: arrColors,
                    )
                  ),
                ),
    
            Positioned(
              left: 50,bottom: 80,
    
              child: ShaderMask(
                child: RawMaterialButton(
                  onPressed: () {},
                  fillColor: Colors.transparent,
                  padding: const EdgeInsets.all(15),
                  shape: const CircleBorder(),
                  child: Icon(
                    Icons.chevron_right,
                    size: 35,
                  ),
                ),
                  blendMode: BlendMode.srcATop,
                  shaderCallback: (Rect bounds) {
                    return RadialGradient(
                      center: Alignment.topLeft,
                      radius: 1.0,
                      colors: <Color>[Colors.red, Colors.yellow],
                      tileMode: TileMode.mirror,
                    ).createShader(bounds);
                  }
              ),
            )
              ],
            ),
          )
        );
      }
    
    }

Upvotes: 2

Related Questions