Skip to content

Instantly share code, notes, and snippets.

@urusaich
Last active November 20, 2025 08:51
Show Gist options
  • Select an option

  • Save urusaich/25519f2c41162c70cf7caf271c9cce30 to your computer and use it in GitHub Desktop.

Select an option

Save urusaich/25519f2c41162c70cf7caf271c9cce30 to your computer and use it in GitHub Desktop.
import 'package:flutter/rendering.dart';
enum InnerShadowAlgo { sides, corners, overlap }
class InnerShadowPainter extends CustomPainter {
const InnerShadowPainter({
super.repaint,
required this.boxShadow,
this.borderRadius = BorderRadius.zero,
this.algo = InnerShadowAlgo.sides,
});
final List<BoxShadow> boxShadow;
final BorderRadius borderRadius;
final InnerShadowAlgo algo;
@override
void paint(Canvas canvas, Size size) {
for (final boxShadow in boxShadow) {
final paint = boxShadow.toPaint();
final rect = Offset.zero & size;
final Size(width: w, height: h) = size;
final rrect = RRect.fromRectAndCorners(
rect,
topLeft: borderRadius.topLeft,
topRight: borderRadius.topRight,
bottomRight: borderRadius.bottomRight,
bottomLeft: borderRadius.bottomLeft,
);
final top = Rect.fromLTWH(-w, -h, w * 3, h);
final right = Rect.fromLTWH(w, -h, w, h * 3);
final bottom = Rect.fromLTWH(-w, h, w * 3, h);
final left = Rect.fromLTWH(-w, -h, w, h * 3);
final topLeft = Rect.fromLTWH(-w, -h, w, h);
final topRight = Rect.fromLTWH(w, -h, w, h);
final bottomRight = Rect.fromLTWH(w, h, w, h);
final bottomLeft = Rect.fromLTWH(-w, h, w, h);
final topLeftV = Rect.fromLTWH(-w, -h, w, h * 1.5);
final topLeftH = Rect.fromLTWH(-w, -h, w * 1.5, h);
final topRightV = Rect.fromLTWH(w * 0.5, -h, w * 1.5, h);
final topRightH = Rect.fromLTWH(w, -h, w, h * 1.5);
final bottomRightV = Rect.fromLTWH(w, h * 0.5, w, h * 1.5);
final bottomRightH = Rect.fromLTWH(w * 0.5, h, w * 1.5, h);
final bottomLeftV = Rect.fromLTWH(-w, h * 0.5, w, h * 1.5);
final bottomLeftH = Rect.fromLTWH(-w, h, w * 1.5, h);
final rectangles = switch (algo) {
InnerShadowAlgo.sides => [left, top, right, bottom],
InnerShadowAlgo.corners => [topLeft, topRight, bottomRight, bottomLeft],
InnerShadowAlgo.overlap => [
topLeftV,
topLeftH,
topRightV,
topRightH,
bottomRightV,
bottomRightH,
bottomLeftV,
bottomLeftH,
],
};
canvas.save();
canvas.clipRRect(rrect);
for (final rect in rectangles) {
canvas.drawRect(
rect.shift(boxShadow.offset).inflate(boxShadow.spreadRadius),
paint,
);
}
canvas.restore();
}
}
@override
bool shouldRepaint(covariant InnerShadowPainter oldDelegate) =>
oldDelegate.boxShadow != boxShadow ||
oldDelegate.borderRadius != borderRadius ||
oldDelegate.algo != algo;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment