public override Path getOuterPath(Rect host, Rect guest) { if (guest == null || !host.overlaps(guest)) { Path path = new Path(); path.addRect(host); return(path); } D.assert(guest.width > 0.0f); Rect intersection = guest.intersect(host); float notchToCenter = intersection.height * (guest.height / 2.0f) / (guest.width / 2.0f); Path ret = new Path(); ret.moveTo(host.left, host.top); ret.lineTo(guest.center.dx - notchToCenter, host.top); ret.lineTo(guest.left + guest.width / 2.0f, guest.bottom); ret.lineTo(guest.center.dx + notchToCenter, host.top); ret.lineTo(host.right, host.top); ret.lineTo(host.right, host.bottom); ret.lineTo(host.left, host.bottom); ret.close(); return(ret); }
public override Path getOuterPath(Rect host, Rect guest) { if (!host.overlaps(guest)) { Path path = new Path(); path.addRect(host); return(path); } float notchRadius = guest.width / 2.0f; const float s1 = 15.0f; const float s2 = 1.0f; float r = notchRadius; float a = -1.0f * r - s2; float b = host.top - guest.center.dy; float n2 = Mathf.Sqrt(b * b * r * r * (a * a + b * b - r * r)); float p2xA = ((a * r * r) - n2) / (a * a + b * b); float p2xB = ((a * r * r) + n2) / (a * a + b * b); float p2yA = Mathf.Sqrt(r * r - p2xA * p2xA); float p2yB = Mathf.Sqrt(r * r - p2xB * p2xB); List <Offset> p = new List <Offset>(6); p[0] = new Offset(a - s1, b); p[1] = new Offset(a, b); float cmp = b < 0 ? -1.0f : 1.0f; p[2] = cmp * p2yA > cmp * p2yB ? new Offset(p2xA, p2yA) : new Offset(p2xB, p2yB); p[3] = new Offset(-1.0f * p[2].dx, p[2].dy); p[4] = new Offset(-1.0f * p[1].dx, p[1].dy); p[5] = new Offset(-1.0f * p[0].dx, p[0].dy); for (int i = 0; i < p.Count; i += 1) { p[i] += guest.center; } Path ret = new Path(); ret.moveTo(host.left, host.top); ret.lineTo(p[0].dx, p[0].dy); ret.quadraticBezierTo(p[1].dx, p[1].dy, p[2].dx, p[2].dy); // TODO: replace this lineTo() with arcToPoint when arcToPoint is ready ret.lineTo(p[3].dx, p[3].dy); // ret.arcToPoint(p[3], p[3], radius: Radius.circular(notchRadius), clockwise: false); ret.quadraticBezierTo(p[4].dx, p[4].dy, p[5].dx, p[5].dy); ret.lineTo(host.right, host.top); ret.lineTo(host.right, host.bottom); ret.lineTo(host.left, host.bottom); ret.close(); return(ret); }
public override Path getOuterPath(Rect host, Rect guest) { //there is a bug in flutter when guest == null, we fix it here if (guest == null || !host.overlaps(guest)) { var path = new Path(); path.addRect(host); return(path); } D.assert(guest.width > 0.0f); var intersection = guest.intersect(host); // We are computing a "V" shaped notch, as in this diagram: // -----\**** /----- // \ / // \ / // \ / // // "-" marks the top edge of the bottom app bar. // "\" and "/" marks the notch outline // // notchToCenter is the horizontal distance between the guest's center and // the host's top edge where the notch starts (marked with "*"). // We compute notchToCenter by similar triangles: var notchToCenter = intersection.height * (guest.height / 2.0f) / (guest.width / 2.0f); var retPath = new Path(); retPath.moveTo(host.left, host.top); retPath.lineTo(guest.center.dx - notchToCenter, host.top); retPath.lineTo(guest.left + guest.width / 2.0f, guest.bottom); retPath.lineTo(guest.center.dx + notchToCenter, host.top); retPath.lineTo(host.right, host.top); retPath.lineTo(host.right, host.bottom); retPath.lineTo(host.left, host.bottom); retPath.close(); return(retPath); }