Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter CustomPaint shadow

I have the following widget:

class OutsiderButton extends StatelessWidget {

  final Function onPressed;
  final Icon icon;
  final OutsiderButtonPosition position;

  OutsiderButton({this.onPressed, @required this.icon, this.position});

  @override
  Widget build(BuildContext context) {
    return new Stack(fit: StackFit.loose, alignment: Alignment.center, children: [
      new CustomPaint(
        painter: new _OutsiderShape(position: position),
        size: Size(60.0, 60.0),
        isComplex: false,
      ),
      OutlineButton(
        borderSide: BorderSide(width: 1.0, color: Colors.white),
        color: AppThemeColors.accentColor,
        shape: new CircleBorder(),
        child: new Padding(
          padding: const EdgeInsets.all(6.0),
          child: icon,
        ),
        onPressed: onPressed,
      )
    ]);
  }
}

It uses CustomPainter to draw the background. I need this CustomPainter to draw a shadow, but every time the widget is clicked, the shadow is redrawn and gets stronger and stronger. Here is the CustomPainter:

class _OutsiderShape extends CustomPainter {

  final Paint bookMarkPaint;
  final double hexagonOffset = 15.0;
  final OutsiderButtonPosition position;
  Path path = Path();

  _OutsiderShape({this.position = OutsiderButtonPosition.TOP}) : bookMarkPaint = new Paint() {
    bookMarkPaint.color = AppThemeColors.primaryColorLight;
    bookMarkPaint.style = PaintingStyle.fill;
  }

  @override
  void paint(Canvas canvas, Size size) {

    canvas.save();

    if (position == OutsiderButtonPosition.BOTTOM) {
      canvas.rotate(pi);
      canvas.translate(-size.width, -size.height);
    }

    path.moveTo(0.0, hexagonOffset);
    path.relativeLineTo(size.width / 3, -hexagonOffset);
    path.relativeLineTo(size.width / 3, 0.0);
    path.relativeLineTo(size.width / 3, hexagonOffset);
    path.relativeLineTo(0.0, size.height - hexagonOffset);
    path.relativeLineTo(-size.width, 0.0);
    path.close();

    canvas.drawShadow(path, Colors.grey[900], 2.0, false);
    canvas.drawPath(path, bookMarkPaint);

    canvas.restore();
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return false;
  }
}

Here is how the shadow looks like after four clicks.

Wrong Shadow

How can I avoid this behavior?

like image 702
Andre Haueisen Avatar asked Mar 05 '23 23:03

Andre Haueisen


2 Answers

The problem in this line

//problem here 
canvas.drawShadow(path, Colors.grey[900], 2.0, false)

//change the alpha color of your grey color like this 
canvas.drawShadow(path, Colors.grey.withAlpha(50), 4.0, false);
like image 139
sourav pandit Avatar answered Mar 11 '23 12:03

sourav pandit


My guess is that Flutter does not clear the canvas before the redraw, so you are drawing over the existing shadow.

You can try to clear the canvas manually at the beginning of your paint method:

canvas.drawColor(Color(0), BlendMode.clear);
like image 36
boformer Avatar answered Mar 11 '23 11:03

boformer