I need help understanding how creating a custom shape in Flutter using the OutlinedBorder
class works.
I don't want to use clipping because I want to test if a custom shape would preferably not clip the button child as well.
I would prefer if someone would explain using an easier shape but here's what I created:
It sort works well enough that only the blue part would react to a click and the ripples don't leak out, but there's two stars and I want it to be just a single star.
Here's my code:
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'dart:math' as Math;
class StarShape extends OutlinedBorder {
final BorderSide side;
StarShape({
this.side = const BorderSide(),
});
@override
OutlinedBorder copyWith({BorderSide? side}) {
return StarShape(side: side ?? const BorderSide());
}
@override
EdgeInsetsGeometry get dimensions => EdgeInsets.all(10);
@override
Path getInnerPath(Rect rect, {TextDirection? textDirection}) {
var _path = Path()
..addRect(rect.deflate(25))
..close();
return _path;
}
@override
Path getOuterPath(Rect rect, {TextDirection? textDirection}) {
rect = rect.inflate(15);
var mid = rect.width / 2;
var min = Math.min(rect.width, rect.height);
var half = min / 2;
mid = mid - half;
var path = Path();
// top left
path.moveTo(mid + half * 0.5, half * 0.84);
// top right
path.lineTo(mid + half * 1.5, half * 0.84);
// bottom left
path.lineTo(mid + half * 0.68, half * 1.45);
// top tip
path.lineTo(mid + half * 1.0, half * 0.5);
// bottom right
path.lineTo(mid + half * 1.32, half * 1.45);
// top left
path.lineTo(mid + half * 0.5, half * 0.84);
return path;
}
@override
void paint(Canvas canvas, Rect rect, {TextDirection? textDirection}) {
var mid = rect.width / 2;
var min = Math.min(rect.width, rect.height);
var half = min / 2;
mid = mid - half;
var path = Path();
// top left
path.moveTo(mid + half * 0.5, half * 0.84);
// top right
path.lineTo(mid + half * 1.5, half * 0.84);
// bottom left
path.lineTo(mid + half * 0.68, half * 1.45);
// top tip
path.lineTo(mid + half * 1.0, half * 0.5);
// bottom right
path.lineTo(mid + half * 1.32, half * 1.45);
// top left
path.lineTo(mid + half * 0.5, half * 0.84);
canvas.drawPath(
path,
Paint()..color = Colors.amber,
);
}
@override
ShapeBorder scale(double t) {
return this.scale(t);
}
}