Home > Blockchain >  How to make text color transparent on top of container
How to make text color transparent on top of container

Time:08-13

I need to make widget this widget. For this, I need to make text transparent on top of coloured container.

enter image description here

CodePudding user response:

You can use ShaderMask with blendMode: BlendMode.srcOut, And use it as a Child on Stack widget.

ClipRRect(
  borderRadius: BorderRadius.circular(12),
  child: ShaderMask(
    blendMode: BlendMode.srcOut,
    shaderCallback: (bounds) {
      return LinearGradient(colors: [
        Colors.white,
        Colors.white,
      ]).createShader(bounds);
    },
    child: Padding(
      padding: const EdgeInsets.all(8.0),
      child: Text(
        "M",
        style: TextStyle(
          fontSize: 44,
        ),
      ),
    ),
  ),
)

enter image description here

CodePudding user response:

You can use ShaderMask and Stack to do this

Stack(
  alignment: Alignment.center,
  children: [
    Container(
      width: double.infinity,
      height: 200,
      decoration: BoxDecoration(
          image: DecorationImage(
              image: NetworkImage('https://res.cloudinary.com/demo/image/upload/v1312461204/sample.jpg'),
              fit: BoxFit.cover
          )
      ),
    ),
    ShaderMask(
      blendMode: BlendMode.srcOut,
      child: Padding(
        padding: const EdgeInsets.fromLTRB(10, 20, 10, 20),
        child: Text('M', style: TextStyle(fontSize: 30),),
      ),
      shaderCallback: (bounds) =>
          LinearGradient(colors: [Colors.white], stops: [0.0])
              .createShader(bounds),
    ),
  ],
),

enter image description here

CodePudding user response:

Here is the method that perfectly worked for me:

class SoterRiskWidget extends StatelessWidget {
  final String letter;
  final double fontSize;
  final Color color;
  final double radius;

  const SoterRiskWidget({
    required this.letter,
    required this.fontSize,
    this.radius = 2,
    this.color = Colors.white,
    Key? key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return SizedBox.square(
      dimension: fontSize,
      child: CustomPaint(
        painter: _CutOutTextPainter(
          text: letter,
          fontSize: fontSize,
          fontWeight: FontWeight.w500,
          color: color,
          radius: radius,
        ),
      ),
    );
  }
}

class _CutOutTextPainter extends CustomPainter {
  final String text;
  final double fontSize;
  final FontWeight fontWeight;
  final Color color;
  final double radius;

  late final TextPainter _textPainter;

  _CutOutTextPainter({
    required this.text,
    required this.fontSize,
    required this.fontWeight,
    required this.color,
    required this.radius,
  }) {
    _textPainter = TextPainter(
      text: TextSpan(
        text: text,
        style: TextStyle(
          fontSize: fontSize,
          fontWeight: fontWeight,
        ),
      ),
      textDirection: TextDirection.ltr,
    );
    _textPainter.layout();
  }

  @override
  void paint(Canvas canvas, Size size) {
    Offset textOffset = size.center(Offset.zero) - _textPainter.size.center(Offset.zero);

    final textRect = textOffset & _textPainter.size;
    Rect newRect;

    double dif = ((textRect.width - textRect.height).abs()) / 2.0;
    if (textRect.width > textRect.height) {
      newRect = Rect.fromLTRB(
        textRect.left,
        textRect.top - dif,
        textRect.right,
        textRect.bottom   dif,
      );
    } else {
      newRect = Rect.fromLTRB(
        textRect.left - dif,
        textRect.top,
        textRect.right   dif,
        textRect.bottom,
      );
    }
    final boxRect = RRect.fromRectAndRadius(newRect.inflate(0), Radius.circular(radius));

    final boxPaint = Paint()
      ..color = color
      ..blendMode = BlendMode.srcOut;

    canvas.saveLayer(boxRect.outerRect, Paint());

    _textPainter.paint(canvas, textOffset);
    canvas.drawRRect(boxRect, boxPaint);

    canvas.restore();
  }

  @override
  bool shouldRepaint(_CutOutTextPainter oldDelegate) {
    return text != oldDelegate.text;
  }
}
  • Related