• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

hacktons / convex_bottom_bar / #133

06 Feb 2023 10:10AM UTC coverage: 97.455%. Remained the same
#133

push

travis-ci

web-flow
Merge branch 'master' into master

1 of 1 new or added line in 1 file covered. (100.0%)

651 of 668 relevant lines covered (97.46%)

2.41 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.11
/lib/src/convex_shape.dart
1
/*
2
 *  Copyright 2020 Chaobin Wu <chaobinwu89@gmail.com>
3
 *  
4
 *  Licensed under the Apache License, Version 2.0 (the "License");
5
 *  you may not use this file except in compliance with the License.
6
 *  You may obtain a copy of the License at
7
 *  
8
 *      http://www.apache.org/licenses/LICENSE-2.0
9
 *  
10
 *  Unless required by applicable law or agreed to in writing, software
11
 *  distributed under the License is distributed on an "AS IS" BASIS,
12
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 *  See the License for the specific language governing permissions and
14
 *  limitations under the License.
15
 */
16
import 'dart:math' as math;
17

18
// Copyright 2014 The Flutter Authors. All rights reserved.
19
// Use of this source code is governed by a BSD-style license that can be
20
// found in the LICENSE file.
21

22
import 'package:flutter/painting.dart';
23

24
/// A convex shape which implemented [NotchedShape].
25
///
26
/// It's used to draw a convex shape for [ConvexAppBar], If you are interested about
27
/// the math calculation, please refer to [CircularNotchedRectangle], it's based
28
/// on Bezier curve;
29
///
30
/// See also:
31
///
32
///  * [CircularNotchedRectangle], a rectangle with a smooth circular notch.
33
class ConvexNotchedRectangle extends NotchedShape {
34
  /// Create Shape instance
35
  const ConvexNotchedRectangle({this.radius = 0});
2✔
36

37
  /// Draw the background with topLeft and topRight corner
38
  final double radius;
39

40
  @override
2✔
41
  Path getOuterPath(Rect host, Rect? guest) {
42
    if (guest == null || !host.overlaps(guest)) {
2✔
43
      return Path()..addRect(host);
×
44
    }
45

46
    // The guest's shape is a circle bounded by the guest rectangle.
47
    // So the guest's radius is half the guest width.
48
    final notchRadius = guest.width / 2.0;
4✔
49

50
    const s1 = 15.0;
51
    const s2 = 1.0;
52

53
    final r = notchRadius;
54
    final a = -1.0 * r - s2;
6✔
55
    final b = host.top - guest.center.dy;
8✔
56

57
    final n2 = math.sqrt(b * b * r * r * (a * a + b * b - r * r));
20✔
58
    final p2xA = ((a * r * r) - n2) / (a * a + b * b);
14✔
59
    final p2xB = ((a * r * r) + n2) / (a * a + b * b);
14✔
60
    final p2yA = -math.sqrt(r * r - p2xA * p2xA);
10✔
61
    final p2yB = -math.sqrt(r * r - p2xB * p2xB);
10✔
62

63
    final p = List<Offset>.filled(6, Offset.zero);
2✔
64
    // p0, p1, and p2 are the control points for segment A.
65
    p[0] = Offset(a - s1, b);
6✔
66
    p[1] = Offset(a, b);
4✔
67
    final cmp = b < 0 ? -1.0 : 1.0;
4✔
68
    p[2] = cmp * p2yA > cmp * p2yB ? Offset(p2xA, p2yA) : Offset(p2xB, p2yB);
11✔
69

70
    // p3, p4, and p5 are the control points for segment B, which is a mirror
71
    // of segment A around the y axis.
72
    p[3] = Offset(-1.0 * p[2].dx, p[2].dy);
16✔
73
    p[4] = Offset(-1.0 * p[1].dx, p[1].dy);
16✔
74
    p[5] = Offset(-1.0 * p[0].dx, p[0].dy);
16✔
75

76
    // translate all points back to the absolute coordinate system.
77
    for (var i = 0; i < p.length; i += 1) {
6✔
78
      p[i] = p[i] + guest.center;
8✔
79
      //p[i] += padding;
80
    }
81

82
    return radius > 0
4✔
83
        ? (Path()
1✔
84
          ..moveTo(host.left, host.top + radius)
5✔
85
          ..arcToPoint(
1✔
86
            Offset(host.left + radius, host.top),
5✔
87
            radius: Radius.circular(radius),
2✔
88
          )
89
          ..lineTo(p[0].dx, p[0].dy)
5✔
90
          ..quadraticBezierTo(p[1].dx, p[1].dy, p[2].dx, p[2].dy)
9✔
91
          ..arcToPoint(
1✔
92
            p[3],
1✔
93
            radius: Radius.circular(notchRadius),
1✔
94
          )
95
          ..quadraticBezierTo(p[4].dx, p[4].dy, p[5].dx, p[5].dy)
9✔
96
          ..lineTo(host.right - radius, host.top)
5✔
97
          ..arcToPoint(
1✔
98
            Offset(host.right, host.top + radius),
5✔
99
            radius: Radius.circular(radius),
2✔
100
          )
101
          ..lineTo(host.right, host.bottom)
3✔
102
          ..lineTo(host.left, host.bottom)
3✔
103
          ..close())
1✔
104
        : (Path()
2✔
105
          ..moveTo(host.left, host.top)
6✔
106
          ..lineTo(p[0].dx, p[0].dy)
10✔
107
          ..quadraticBezierTo(p[1].dx, p[1].dy, p[2].dx, p[2].dy)
18✔
108
          ..arcToPoint(
2✔
109
            p[3],
2✔
110
            radius: Radius.circular(notchRadius),
2✔
111
          )
112
          ..quadraticBezierTo(p[4].dx, p[4].dy, p[5].dx, p[5].dy)
18✔
113
          ..lineTo(host.right, host.top)
6✔
114
          ..lineTo(host.right, host.bottom)
6✔
115
          ..lineTo(host.left, host.bottom)
6✔
116
          ..close());
2✔
117
  }
118
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc