|
@@ -0,0 +1,263 @@
|
|
|
+// import 'package:flutter/material.dart';
|
|
|
+//
|
|
|
+// class _RenderTrapezoid2 extends RenderBox{
|
|
|
+//
|
|
|
+//
|
|
|
+// Path _trapezoidPath1() {
|
|
|
+// Path path = Path();
|
|
|
+// final radius = _radius;
|
|
|
+// final rectSize = Size(radius * 2, radius * 2);
|
|
|
+// double alpha = _alpha;
|
|
|
+//
|
|
|
+// double ox1 = childWidth - radius / math.tan(math.pi / 4 - alpha / 2);
|
|
|
+// double oy1 = radius;
|
|
|
+//
|
|
|
+// double ox2 = childWidth - childHeight * math.tan(alpha) - radius * math.tan(math.pi / 4 - alpha / 2);
|
|
|
+// double oy2 = childHeight - radius;
|
|
|
+//
|
|
|
+// double x1 = ox1 + radius * math.cos(alpha);
|
|
|
+// double y1 = oy1 + radius * math.sin(alpha);
|
|
|
+//
|
|
|
+// double x2 = ox2 + radius * math.sin(math.pi / 2 - alpha);
|
|
|
+// double y2 = oy2 + radius * math.cos(math.pi / 2 - alpha);
|
|
|
+//
|
|
|
+// path.moveTo(0, radius);
|
|
|
+// path.arcTo(Offset.zero & rectSize, math.pi, math.pi / 2, false);
|
|
|
+//
|
|
|
+// path.lineTo(ox1, 0);
|
|
|
+// path.arcTo(Offset(ox1 - radius, oy1 - radius) & rectSize, -math.pi / 2, math.pi / 2 + alpha, false);
|
|
|
+//
|
|
|
+// path.lineTo(x2, y2);
|
|
|
+// path.arcTo(Offset(ox2 - radius, oy2 - radius) & rectSize, alpha, math.pi / 2 - alpha, false);
|
|
|
+//
|
|
|
+// path.lineTo(radius, childHeight);
|
|
|
+// path.arcTo(Offset(0, childHeight - 2 * radius) & rectSize, math.pi / 2, math.pi / 2, true);
|
|
|
+//
|
|
|
+// path.lineTo(0, radius);
|
|
|
+// path.close();
|
|
|
+// return path;
|
|
|
+// }
|
|
|
+//
|
|
|
+// Path _trapezoidPath2() {
|
|
|
+// Path path = Path();
|
|
|
+// final radius = _radius;
|
|
|
+// final rectSize = Size(radius * 2, radius * 2);
|
|
|
+// double alpha = _alpha;
|
|
|
+// double ox1 = childHeight * math.tan(alpha) + radius * math.sin(math.pi / 4 - alpha / 2);
|
|
|
+// double oy1 = radius;
|
|
|
+//
|
|
|
+// double ox2 = radius / math.tan(math.pi / 4 - alpha / 2);
|
|
|
+// double oy2 = childHeight - radius;
|
|
|
+//
|
|
|
+// double x1 = ox1 - radius * math.sin(math.pi / 2 - alpha);
|
|
|
+// double y1 = oy1 - radius * math.cos(math.pi / 2 - alpha);
|
|
|
+//
|
|
|
+// double x2 = ox2 + radius * math.sin(math.pi / 2 + alpha);
|
|
|
+// double y2 = oy2 + radius * math.cos(math.pi / 2 + alpha);
|
|
|
+//
|
|
|
+// path.moveTo(ox1, 0);
|
|
|
+//
|
|
|
+// path.lineTo(childWidth - radius, 0);
|
|
|
+// path.arcTo(Offset(childWidth - 2 * radius, 0) & rectSize, -math.pi / 2, math.pi / 2, false);
|
|
|
+//
|
|
|
+// path.lineTo(childWidth, childHeight - radius);
|
|
|
+// path.arcTo(Offset(childWidth - 2 * radius, childHeight - 2 * radius) & rectSize, 0, math.pi / 2, false);
|
|
|
+//
|
|
|
+// path.lineTo(ox2, childHeight);
|
|
|
+// path.arcTo(Offset(ox2 - radius, oy2 - radius) & rectSize, math.pi / 2, math.pi / 2 + alpha, false);
|
|
|
+//
|
|
|
+// path.lineTo(x1, y1);
|
|
|
+// path.arcTo(Offset(ox1 - radius, oy1 - radius) & rectSize, math.pi + alpha, math.pi / 2 - alpha, false);
|
|
|
+//
|
|
|
+// return path;
|
|
|
+// }
|
|
|
+// }
|
|
|
+
|
|
|
+import 'package:flutter/material.dart';
|
|
|
+import 'package:flutter/rendering.dart';
|
|
|
+import 'dart:math' show max;
|
|
|
+
|
|
|
+import 'package:luojigou_thinking_core/src/widget/trapezoid.dart';
|
|
|
+
|
|
|
+class Trapezoid2Box extends MultiChildRenderObjectWidget {
|
|
|
+ final double radius;
|
|
|
+ final double diff;
|
|
|
+ final double spacing;
|
|
|
+
|
|
|
+ Trapezoid2Box({
|
|
|
+ Key? key,
|
|
|
+ this.radius = 0,
|
|
|
+ this.diff = 0,
|
|
|
+ this.spacing = 0,
|
|
|
+ required Widget child1,
|
|
|
+ required Widget child2,
|
|
|
+ }) : super(key: key, children: [child1, child2]);
|
|
|
+
|
|
|
+ @override
|
|
|
+ _RenderTrapezoid2Box createRenderObject(BuildContext context) {
|
|
|
+ return _RenderTrapezoid2Box(radius, diff, spacing);
|
|
|
+ }
|
|
|
+
|
|
|
+ @override
|
|
|
+ void updateRenderObject(
|
|
|
+ BuildContext context, covariant _RenderTrapezoid2Box renderObject) {
|
|
|
+ renderObject
|
|
|
+ ..spacing = spacing
|
|
|
+ ..radius = radius
|
|
|
+ ..diff = diff;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+class Trapezoid2ParentData extends ContainerBoxParentData<RenderBox> {
|
|
|
+ Offset a = Offset.zero;
|
|
|
+ Offset b = Offset.zero;
|
|
|
+ Offset c = Offset.zero;
|
|
|
+ Offset d = Offset.zero;
|
|
|
+}
|
|
|
+
|
|
|
+class _RenderTrapezoid2Box extends RenderBox
|
|
|
+ with
|
|
|
+ ContainerRenderObjectMixin<RenderBox, Trapezoid2ParentData>,
|
|
|
+ RenderBoxContainerDefaultsMixin<RenderBox, Trapezoid2ParentData> {
|
|
|
+ _RenderTrapezoid2Box(this._radius, this._diff, this._spacing);
|
|
|
+
|
|
|
+ double _radius;
|
|
|
+
|
|
|
+ set radius(double value) {
|
|
|
+ if (value != _radius) {
|
|
|
+ _radius = value;
|
|
|
+ markNeedsPaint();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ double _diff;
|
|
|
+
|
|
|
+ set diff(double value) {
|
|
|
+ if (_diff != value) {
|
|
|
+ _diff = value;
|
|
|
+ markNeedsPaint();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ double _spacing;
|
|
|
+
|
|
|
+ set spacing(double value) {
|
|
|
+ if (_spacing != value) {
|
|
|
+ _spacing = value;
|
|
|
+ markNeedsLayout();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @override
|
|
|
+ void setupParentData(covariant RenderObject child) {
|
|
|
+ if (child.parentData is! Trapezoid2ParentData) {
|
|
|
+ child.parentData = Trapezoid2ParentData();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @override
|
|
|
+ void performLayout() {
|
|
|
+ final childConstraints = BoxConstraints(
|
|
|
+ minWidth: 0,
|
|
|
+ minHeight: 0,
|
|
|
+ maxWidth: max((constraints.maxWidth - _spacing) / 2 + _diff / 2,0),
|
|
|
+ maxHeight: constraints.maxHeight,
|
|
|
+ );
|
|
|
+
|
|
|
+ ChildLayoutHelper.layoutChild(firstChild!, childConstraints);
|
|
|
+ ChildLayoutHelper.layoutChild(lastChild!, childConstraints);
|
|
|
+
|
|
|
+ size = Size(constraints.maxWidth, constraints.maxHeight);
|
|
|
+
|
|
|
+ final firstChildParentData = firstChild!.parentData as Trapezoid2ParentData;
|
|
|
+ final lastChildParentData = lastChild!.parentData as Trapezoid2ParentData;
|
|
|
+
|
|
|
+ firstChildParentData.a = Offset.zero;
|
|
|
+ firstChildParentData.b = Offset(
|
|
|
+ (constraints.maxWidth - _spacing) / 2 + _diff / 2,
|
|
|
+ 0,
|
|
|
+ );
|
|
|
+ firstChildParentData.c = Offset(0, size.height);
|
|
|
+ firstChildParentData.d = Offset(
|
|
|
+ (constraints.maxWidth - _spacing) / 2 - _diff / 2,
|
|
|
+ size.height,
|
|
|
+ );
|
|
|
+ firstChildParentData.offset = Offset.zero;
|
|
|
+
|
|
|
+ lastChildParentData.a = Offset(
|
|
|
+ (constraints.maxWidth - _spacing) / 2 + _diff / 2 + _spacing,
|
|
|
+ 0,
|
|
|
+ );
|
|
|
+ lastChildParentData.b = Offset(size.width, 0);
|
|
|
+ lastChildParentData.c = Offset(
|
|
|
+ (constraints.maxWidth - _spacing) / 2 - _diff / 2 + _spacing,
|
|
|
+ size.height,
|
|
|
+ );
|
|
|
+ lastChildParentData.d = Offset(size.width, size.height);
|
|
|
+ lastChildParentData.offset = Offset(
|
|
|
+ (constraints.maxWidth - _spacing) / 2 - _diff / 2 + _spacing,
|
|
|
+ 0,
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ @override
|
|
|
+ bool hitTestChildren(BoxHitTestResult result, {required Offset position}) {
|
|
|
+ RenderBox? child = firstChild;
|
|
|
+ while (child != null) {
|
|
|
+ final Trapezoid2ParentData childParentData =
|
|
|
+ child.parentData! as Trapezoid2ParentData;
|
|
|
+ final Quadrilateral quadrilateral = Quadrilateral(
|
|
|
+ a: childParentData.a,
|
|
|
+ b: childParentData.b,
|
|
|
+ c: childParentData.d,
|
|
|
+ d: childParentData.c,
|
|
|
+ );
|
|
|
+
|
|
|
+ bool isIn = quadrilateral.contains(position);
|
|
|
+ if (isIn) {
|
|
|
+ final bool isHit = result.addWithPaintOffset(
|
|
|
+ offset: childParentData.offset,
|
|
|
+ position: position,
|
|
|
+ hitTest: (BoxHitTestResult result, Offset? transformed) {
|
|
|
+ assert(transformed == position - childParentData.offset);
|
|
|
+ return child!.hitTest(result, position: transformed!);
|
|
|
+ },
|
|
|
+ );
|
|
|
+ if (isHit) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ child = childParentData.nextSibling;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ @override
|
|
|
+ void paint(PaintingContext context, Offset offset) {
|
|
|
+ context.canvas.save();
|
|
|
+ context.canvas.translate(offset.dx, offset.dy);
|
|
|
+ for (var child in getChildrenAsList()) {
|
|
|
+ _paintChild(context, child);
|
|
|
+ }
|
|
|
+ context.canvas.restore();
|
|
|
+ }
|
|
|
+
|
|
|
+ void _paintChild(PaintingContext context, RenderBox child) {
|
|
|
+ Trapezoid2ParentData parentData = child.parentData as Trapezoid2ParentData;
|
|
|
+
|
|
|
+ for(var offset in [parentData.a,parentData.b,parentData.c,parentData.d]){
|
|
|
+ context.canvas.drawCircle(offset, 2, Paint()..color = Colors.red);
|
|
|
+ }
|
|
|
+
|
|
|
+ context.canvas.save();
|
|
|
+ Path path = Path();
|
|
|
+ path.moveTo(parentData.a.dx, parentData.a.dy);
|
|
|
+ path.lineTo(parentData.b.dx, parentData.b.dy);
|
|
|
+ path.lineTo(parentData.d.dx, parentData.d.dy);
|
|
|
+ path.lineTo(parentData.c.dx, parentData.c.dy);
|
|
|
+ path.close();
|
|
|
+ context.canvas.clipPath(path);
|
|
|
+ context.paintChild(child, parentData.offset);
|
|
|
+ context.canvas.restore();
|
|
|
+ }
|
|
|
+}
|