Skip to content

Commit

Permalink
radius防越界
Browse files Browse the repository at this point in the history
  • Loading branch information
yixiaco committed Jul 28, 2021
1 parent 80ffb4d commit e4854c7
Showing 1 changed file with 74 additions and 75 deletions.
149 changes: 74 additions & 75 deletions lib/src/shape/bubble_shape_border.dart
Original file line number Diff line number Diff line change
Expand Up @@ -187,12 +187,13 @@ class BubbleShapeBorder extends ShapeBorder {
@override
Path getOuterPath(Rect rect, {TextDirection? textDirection}) {
// 修正塞贝尔曲线高度
var arrowQuadraticBezierLength =
this.arrowQuadraticBezierLength > arrowHeight
? arrowHeight
: this.arrowQuadraticBezierLength;
var arrowQuadraticBezierLength = this.arrowQuadraticBezierLength > arrowHeight ? arrowHeight : this.arrowQuadraticBezierLength;

Size size = Size(rect.width, rect.height);

//修改radius安全范围
BorderRadius radius = _radius(size);

var path = Path();
//高度
double ah = arrowHeight;
Expand All @@ -211,16 +212,12 @@ class BubbleShapeBorder extends ShapeBorder {
/// 左上角半径
path.moveTo(
leftMargin,
topMargin +
math.min(_min(position.start, radius.topLeft.y, BubbleDirection.left),
size.height),
topMargin + math.min(_min(position.start, radius.topLeft.y, BubbleDirection.left), size.height),
);
path.quadraticBezierTo(
leftMargin,
topMargin,
leftMargin +
math.min(_min(position.start, radius.topLeft.x, BubbleDirection.top),
size.width),
leftMargin + math.min(_min(position.start, radius.topLeft.x, BubbleDirection.top), size.width),
topMargin,
);

Expand All @@ -232,33 +229,25 @@ class BubbleShapeBorder extends ShapeBorder {

var x = arrowAngle * arrowQuadraticBezierLength / ah;

path.quadraticBezierTo(p - arrowAngle + smooth, topMargin, p - x,
arrowQuadraticBezierLength);
path.quadraticBezierTo(p - arrowAngle + smooth, topMargin, p - x, arrowQuadraticBezierLength);
// path.lineTo(p - x, arrowQuadraticBezierLength);

path.quadraticBezierTo(p, 0, p + x, arrowQuadraticBezierLength);

path.quadraticBezierTo(p + arrowAngle - smooth, topMargin,
p + arrowAngle + smooth, topMargin);
path.quadraticBezierTo(p + arrowAngle - smooth, topMargin, p + arrowAngle + smooth, topMargin);
// path.lineTo(p + arrowAngle, topMargin);
}

/// 右上角半径
path.lineTo(
size.width -
rightMargin -
math.min(_min(position.end, radius.topRight.x, BubbleDirection.top),
size.width),
size.width - rightMargin - math.min(_min(position.end, radius.topRight.x, BubbleDirection.top), size.width),
topMargin,
);
path.quadraticBezierTo(
size.width - rightMargin,
topMargin,
size.width - rightMargin,
topMargin +
math.min(
_min(position.start, radius.topRight.y, BubbleDirection.right),
size.height),
topMargin + math.min(_min(position.start, radius.topRight.y, BubbleDirection.right), size.height),
);

/// 右尖角
Expand All @@ -269,82 +258,52 @@ class BubbleShapeBorder extends ShapeBorder {

var x = ah * arrowQuadraticBezierLength / arrowAngle;

path.quadraticBezierTo(size.width - rightMargin, p - arrowAngle + smooth,
size.width - arrowQuadraticBezierLength, p - x);
path.quadraticBezierTo(size.width - rightMargin, p - arrowAngle + smooth, size.width - arrowQuadraticBezierLength, p - x);
// path.lineTo(size.width - arrowQuadraticBezierLength, p - x);

path.quadraticBezierTo(
size.width, p, size.width - arrowQuadraticBezierLength, p + x);
path.quadraticBezierTo(size.width, p, size.width - arrowQuadraticBezierLength, p + x);

path.quadraticBezierTo(size.width - rightMargin, p + arrowAngle - smooth,
size.width - rightMargin, p + arrowAngle + smooth);
path.quadraticBezierTo(size.width - rightMargin, p + arrowAngle - smooth, size.width - rightMargin, p + arrowAngle + smooth);
// path.lineTo(size.width - rightMargin, p + arrowAngle);
}

/// 右下角半径
path.lineTo(
size.width - rightMargin,
size.height -
bottomMargin -
math.min(
_min(position.end, radius.bottomRight.y, BubbleDirection.right),
size.height),
size.height - bottomMargin - math.min(_min(position.end, radius.bottomRight.y, BubbleDirection.right), size.height),
);
path.quadraticBezierTo(
size.width - rightMargin,
size.height - bottomMargin,
size.width -
rightMargin -
math.min(
_min(
position.end, radius.bottomRight.x, BubbleDirection.bottom),
size.width),
size.width - rightMargin - math.min(_min(position.end, radius.bottomRight.x, BubbleDirection.bottom), size.width),
size.height - bottomMargin);

/// 下尖角
if (direction == BubbleDirection.bottom) {
double p = _getTopBottomPosition(size);

path.lineTo(
p + arrowAngle - rightMargin + smooth, size.height - bottomMargin);
path.lineTo(p + arrowAngle - rightMargin + smooth, size.height - bottomMargin);

var x = arrowAngle * arrowQuadraticBezierLength / ah;

// path.lineTo(p + x - rightMargin, size.height - arrowQuadraticBezierLength);
path.quadraticBezierTo(
p + arrowAngle - rightMargin - smooth,
size.height - bottomMargin,
p + x - rightMargin,
size.height - arrowQuadraticBezierLength);
p + arrowAngle - rightMargin - smooth, size.height - bottomMargin, p + x - rightMargin, size.height - arrowQuadraticBezierLength);

path.quadraticBezierTo(p - rightMargin, size.height, p - rightMargin - x,
size.height - arrowQuadraticBezierLength);
path.quadraticBezierTo(p - rightMargin, size.height, p - rightMargin - x, size.height - arrowQuadraticBezierLength);

// path.lineTo(p - arrowAngle - rightMargin, size.height - bottomMargin);
path.quadraticBezierTo(
p - arrowAngle - rightMargin + smooth,
size.height - bottomMargin,
p - arrowAngle - rightMargin - smooth,
size.height - bottomMargin);
p - arrowAngle - rightMargin + smooth, size.height - bottomMargin, p - arrowAngle - rightMargin - smooth, size.height - bottomMargin);
}

/// 左下角半径
path.lineTo(
leftMargin +
math.min(
_min(position.start, radius.bottomLeft.x,
BubbleDirection.bottom),
size.width),
size.height - bottomMargin);
path.lineTo(leftMargin + math.min(_min(position.start, radius.bottomLeft.x, BubbleDirection.bottom), size.width), size.height - bottomMargin);
path.quadraticBezierTo(
leftMargin,
size.height - bottomMargin,
leftMargin,
size.height -
bottomMargin -
math.min(
_min(position.end, radius.bottomLeft.y, BubbleDirection.left),
size.height),
size.height - bottomMargin - math.min(_min(position.end, radius.bottomLeft.y, BubbleDirection.left), size.height),
);

/// 左尖角
Expand All @@ -353,24 +312,17 @@ class BubbleShapeBorder extends ShapeBorder {
path.lineTo(leftMargin, p + arrowAngle + smooth);
var x = ah * arrowQuadraticBezierLength / arrowAngle;

path.quadraticBezierTo(leftMargin, p + arrowAngle - smooth,
arrowQuadraticBezierLength, p + x);
path.quadraticBezierTo(leftMargin, p + arrowAngle - smooth, arrowQuadraticBezierLength, p + x);
// path.lineTo(arrowQuadraticBezierLength, p + x);

path.quadraticBezierTo(0, p, arrowQuadraticBezierLength, p - x);

// path.lineTo(leftMargin, p - arrowAngle);
path.quadraticBezierTo(leftMargin, p - arrowAngle + smooth, leftMargin,
p - arrowAngle - smooth);
path.quadraticBezierTo(leftMargin, p - arrowAngle + smooth, leftMargin, p - arrowAngle - smooth);
}

/// 收尾
path.lineTo(
leftMargin,
topMargin +
math.min(
_min(position.start, radius.topRight.y, BubbleDirection.left),
size.height));
path.lineTo(leftMargin, topMargin + math.min(_min(position.start, radius.topRight.y, BubbleDirection.left), size.height));
path.close();
return path;
}
Expand Down Expand Up @@ -453,6 +405,54 @@ class BubbleShapeBorder extends ShapeBorder {
return math.min(v1, v2);
}

/// 对radius值做处理,防越界
BorderRadius _radius(Size size) {
double topLeftX = 0, topLeftY = 0, topRightX = 0, topRightY = 0, bottomLeftX = 0, bottomLeftY = 0, bottomRightX = 0, bottomRightY = 0;
switch(direction){
case BubbleDirection.left:
topLeftY = size.height - _getLeftRightPosition(size) - arrowAngle / 2 + smooth;
bottomLeftY = _getLeftRightPosition(size) - arrowAngle / 2 + smooth;
break;
case BubbleDirection.right:
topRightY = size.height - _getLeftRightPosition(size) - arrowAngle / 2 + smooth;
bottomRightY = _getLeftRightPosition(size) - arrowAngle / 2 + smooth;
break;
case BubbleDirection.top:
topLeftX = size.width - _getTopBottomPosition(size) - arrowAngle / 2 + smooth;
topRightX = _getTopBottomPosition(size) - arrowAngle / 2 + smooth;
break;
case BubbleDirection.bottom:
bottomLeftX = size.width - _getTopBottomPosition(size) - arrowAngle / 2 + smooth;
bottomRightX = _getTopBottomPosition(size) - arrowAngle / 2 + smooth;
break;
default:
}
BorderRadius _radius = radius.copyWith(
topLeft: Radius.elliptical(
_s(radius.topLeft.x, radius.topRight.x, size.width - topLeftX),
_s(radius.topLeft.y, radius.bottomLeft.y, size.height - topLeftY),
),
topRight: Radius.elliptical(
_s(radius.topRight.x, radius.topLeft.x, size.width - topRightX),
_s(radius.topRight.y, radius.bottomRight.y, size.height - topRightY),
),
bottomLeft: Radius.elliptical(
_s(radius.bottomLeft.x, radius.bottomRight.x, size.width - bottomLeftX),
_s(radius.bottomLeft.y, radius.topLeft.y, size.height - bottomLeftY),
),
bottomRight: Radius.elliptical(
_s(radius.bottomRight.x, radius.bottomLeft.x, size.width - bottomRightX),
_s(radius.bottomRight.y, radius.topRight.y, size.height - bottomRightY),
),
);
return _radius;
}

/// 比例最小值
double _s(double s1, double s2, double length) {
return math.min(math.min(s1, s1 / (s1 + s2) * length), length);
}

/// copyWith the border
BubbleShapeBorder copyWith({
final BubbleDirection? direction,
Expand All @@ -471,8 +471,7 @@ class BubbleShapeBorder extends ShapeBorder {
direction: direction ?? this.direction,
arrowHeight: arrowHeight ?? this.arrowHeight,
arrowAngle: arrowAngle ?? this.arrowAngle,
arrowQuadraticBezierLength:
arrowQuadraticBezierLength ?? this.arrowQuadraticBezierLength,
arrowQuadraticBezierLength: arrowQuadraticBezierLength ?? this.arrowQuadraticBezierLength,
position: position ?? this.position,
border: border ?? this.border,
radius: radius ?? this.radius,
Expand Down

0 comments on commit e4854c7

Please sign in to comment.