zhaoyadi 3 éve
szülő
commit
2fb317cbca

+ 49 - 40
example/lib/demo/demo3.dart

@@ -16,48 +16,54 @@ class _Demo3State extends State<Demo3> {
       color: Colors.black,
       child: SingleChildScrollView(
         child: Padding(
-          padding: const EdgeInsets.only(top: 20,left: 20,right: 20),
-          child: TrapezoidBox(
-            mainAxisSpacing: 16,
-            padding: const EdgeInsets.symmetric(
-              horizontal: 40,
-              vertical: 60,
-            ),
-            background: Colors.white,
-            children: const [
-              _HitTestBox(
-                size: Size(double.infinity, 300),
+          padding: const EdgeInsets.only(top: 20, left: 20, right: 20),
+          child: Column(
+            children: [
+              const SizedBox(height: 40),
+              AspectRatio(
+                aspectRatio: 3,
+                child: ColoredBox(
+                  color: Colors.white,
+                  child: Trapezoid2Box(
+                    spacing: 20,
+                    diff: 15,
+                    child1: const _HitTestBox(
+                      size: Size(double.infinity, 300),
+                    ),
+                    child2: const _HitTestBox(
+                      size: Size(double.infinity, 300),
+                    ),
+                  ),
+                ),
               ),
-              _HitTestBox(
-                size: Size(double.infinity, 100),
+              TrapezoidBox(
+                mainAxisSpacing: 16,
+                padding: const EdgeInsets.symmetric(
+                  horizontal: 40,
+                  vertical: 60,
+                ),
+                background: Colors.white,
+                children: const [
+                  _HitTestBox(
+                    size: Size(double.infinity, 300),
+                  ),
+                  _HitTestBox(
+                    size: Size(double.infinity, 100),
+                  ),
+                  _HitTestBox(
+                    size: Size(double.infinity, 200),
+                  ),
+                  _HitTestBox(
+                    size: Size(double.infinity, 400),
+                  ),
+                  _HitTestBox(
+                    size: Size(double.infinity, 200),
+                  ),
+                  _HitTestBox(
+                    size: Size(double.infinity, 200),
+                  ),
+                ],
               ),
-              _HitTestBox(
-                size: Size(double.infinity, 200),
-              ),
-              _HitTestBox(
-                size: Size(double.infinity, 400),
-              ),
-              _HitTestBox(
-                size: Size(double.infinity, 200),
-              ),
-              _HitTestBox(
-                size: Size(double.infinity, 200),
-              ),
-              // Container(
-              //   width: double.infinity,
-              //   height: 200,
-              //   color: Colors.green,
-              // ),
-              // Container(
-              //   width: double.infinity,
-              //   height: 200,
-              //   color: Colors.red,
-              // ),
-              // Container(
-              //   width: double.infinity,
-              //   height: 200,
-              //   color: Colors.orange,
-              // ),
             ],
           ),
         ),
@@ -124,5 +130,8 @@ class _RenderHitTestBox extends RenderBox {
   @override
   void paint(PaintingContext context, Offset offset) {
     context.canvas.drawRect(offset & size, Paint()..color = _color);
+    var tOffset = offset+Offset(10,10);
+    var tSize = size + Offset(-20,-20);
+    context.canvas.drawRect(tOffset & tSize, Paint()..color = Colors.green);
   }
 }

+ 51 - 0
example/lib/demo/demo4.dart

@@ -0,0 +1,51 @@
+import 'dart:math';
+
+import 'package:flutter/material.dart';
+import 'package:luojigou_thinking_core/luojigou_thinking_core.dart';
+
+class Demo4 extends StatefulWidget {
+  const Demo4({Key? key}) : super(key: key);
+
+  @override
+  State<Demo4> createState() => _Demo4State();
+}
+
+class _Demo4State extends State<Demo4> {
+  @override
+  Widget build(BuildContext context) {
+    return Center(
+      child: SizedBox(
+        width: MediaQuery.of(context).size.width,
+        height: MediaQuery.of(context).size.width,
+        child: CustomPaint(
+          painter: _Painter(),
+        ),
+      ),
+    );
+  }
+}
+
+class _Painter extends CustomPainter {
+  @override
+  void paint(Canvas canvas, Size size) {
+    Paint paint = Paint()
+      ..color = Colors.deepPurple
+      ..style = PaintingStyle.stroke
+      ..strokeWidth = 0.5;
+
+    final Offset o = Offset(50, 50);
+    final Offset o1 = Offset(200, 400);
+    final Offset o2 = Offset(400, 200);
+
+    final path = Path();
+    path.moveTo(o1.dx, o1.dy);
+    path.lineTo(o.dx, o.dy);
+    path.lineTo(o2.dx, o2.dy);
+
+    canvas.drawPath(path, paint);
+    canvas.drawCircle(PlaneGeometryUtils.origin(o, o1, o2, 40), 40, paint);
+  }
+
+  @override
+  bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
+}

+ 5 - 1
example/lib/main.dart

@@ -1,8 +1,11 @@
+import 'package:example/text_page.dart';
 import 'package:flutter/material.dart';
+import 'package:luojigou_thinking_core/luojigou_thinking_core.dart';
 
 import 'demo/demo1.dart';
 import 'demo/demo2.dart';
 import 'demo/demo3.dart';
+import 'demo/demo4.dart';
 
 void main() {
   runApp(const MyApp());
@@ -18,6 +21,7 @@ class MyApp extends StatelessWidget {
       theme: ThemeData(
         primarySwatch: Colors.blue,
       ),
+      // home: PlayroomPage(),
       home: const _TabDemo(),
     );
   }
@@ -35,7 +39,7 @@ class _TabDemoState extends State<_TabDemo> {
   Widget build(BuildContext context) {
     return const Scaffold(
       appBar: null,
-      body: Demo3(),
+      body: Demo4(),
     );
   }
 }

+ 9 - 10
example/lib/three_page.dart

@@ -10,14 +10,13 @@ import 'package:luojigou_thinking_core/src/view/bulletf_rame/report_generation/r
 import 'package:luojigou_thinking_core/src/view/bulletf_rame/album_selection/album_selection_bulletf_rame_factory.dart';
 import 'package:luojigou_thinking_core/src/view/bulletf_rame/ability_selection/ability_selection_bulletf_rame_factory.dart';
 
-
 class ThreePage extends StatefulWidget {
   @override
   ThreePageState createState() => new ThreePageState();
 }
 
 class ThreePageState extends State<ThreePage> {
-  IBulletfRameFactory _iBulletfRameFactory;
+  late IBulletfRameFactory _iBulletfRameFactory;
 
   @override
   void initState() {
@@ -44,13 +43,14 @@ class ThreePageState extends State<ThreePage> {
             child: Text("点击"),
             onPressed: () {
               Navigator.push(
-                  context,
-                  ActivateRouter(
-                    _iBulletfRameFactory.getBulletfRame().createBulletfRame(),
-                    _iBulletfRameFactory.getBulletfRameColor().getBulletfRameBarrierColor(),
-                  ));
-
-
+                context,
+                ActivateRouter(
+                  _iBulletfRameFactory.getBulletfRame().createBulletfRame(),
+                  _iBulletfRameFactory
+                      .getBulletfRameColor()
+                      .getBulletfRameBarrierColor(),
+                ),
+              );
             },
           ),
         ),
@@ -58,4 +58,3 @@ class ThreePageState extends State<ThreePage> {
     );
   }
 }
-

+ 2 - 2
example/pubspec.yaml

@@ -4,8 +4,8 @@ publish_to: 'none'
 version: 1.0.0+1
 
 environment:
-  sdk: ">=2.7.0 <3.0.0"
-#  flutter: ">=2.5.0 <3.0.0"
+  sdk: ">=2.14.0 <3.0.0"
+  flutter: ">=2.5.0 <3.0.0"
 
 dependencies:
   flutter:

+ 2 - 0
lib/luojigou_thinking_core.dart

@@ -7,3 +7,5 @@ export 'model.dart';
 export 'page.dart';
 export 'view.dart';
 export 'widget.dart';
+
+export 'src/utils/plane_geometry_utils.dart';

+ 1 - 0
lib/page.dart

@@ -0,0 +1 @@
+export 'src/page/playroom/playroom_page.dart';

+ 127 - 0
lib/src/utils/plane_geometry_utils.dart

@@ -1,3 +1,6 @@
+import "dart:math";
+
+import 'package:flutter/material.dart';
 import 'package:flutter/painting.dart';
 
 class PlaneGeometryUtils {
@@ -11,5 +14,129 @@ class PlaneGeometryUtils {
     return x1.dy - lineK(x1, x2) * x1.dx;
   }
 
+  static Offset origin(Offset p, Offset p1, Offset p2, double radius) {
+    double angle1 = atan((p1.dy - p.dy) / (p1.dx - p.dx));
+    double angle2 = atan((p2.dy - p.dy) / (p2.dx - p.dx));
+
+    double angle = (angle1 + angle2) / 2;
+    double k = tan(angle);
+    double c = p.dy - k * p.dx;
+
+    double k1 = lineK(p, p1);
+    double c1 = lineC(p, p1);
+
+    double k2 = lineK(p, p2);
+    double c2 = lineC(p, p2);
+
+    if ((c + c1) == 0) {
+      double originX = radius * (1 + k1 * k1) / (k1 - k).abs();
+      double originY = k * originX + c;
+
+      return Offset(originX, originY);
+    } else {
+      double absC = (c + c1).abs();
+      double t = ((k1 - k) / (c1 + c)).abs();
+
+      double originX = (radius * (1 + k1 * k1) / absC - 1) / t;
+      double originY = k * originX + c;
+
+      return Offset(originX, originY);
+    }
+  }
+}
+
+class Line {
+  ///y = kx + c
+  static double normalLine(x, {k = 0, c = 0}) {
+    return k * x + c;
+  }
+
+  ///Calculate the param K in y = kx +c
+  static double paramK(Point p1, Point p2) {
+    if (p1.x == p2.x) return 0;
+    return (p2.y - p1.y) / (p2.x - p1.x);
+  }
+
+  ///Calculate the param C in y = kx +c
+  static double paramC(Point p1, Point p2) {
+    return p1.y - paramK(p1, p2) * p1.x;
+  }
+}
+
+/// start point p1, end point p2,p2 is center of the circle,r is its radius.
+class LineInterCircle {
+  /// start point p1, end point p2,p2 is center of the circle,r is its radius.
+  /// param a: y = kx +c intersect with circle,which has the center with point2 and radius R .
+  /// when derive to x2+ ax +b = 0 equation. the param a is here.
+  static double paramA(Point p1, Point p2) {
+    return (2 * Line.paramK(p1, p2) * Line.paramC(p1, p2) -
+            2 * Line.paramK(p1, p2) * p2.y -
+            2 * p2.x) /
+        (Line.paramK(p1, p2) * Line.paramK(p1, p2) + 1);
+  }
+
+  /// start point p1, end point p2,p2 is center of the circle,r is its radius.
+  /// param b: y = kx +c intersect with circle,which has the center with point2 and radius R .
+  /// when derive to x2+ ax +b = 0 equation. the param b is here.
+  static double paramB(Point p1, Point p2, double r) {
+    return (p2.x * p2.x -
+            r * r +
+            (Line.paramC(p1, p2) - p2.y) * (Line.paramC(p1, p2) - p2.y)) /
+        (Line.paramK(p1, p2) * Line.paramK(p1, p2) + 1);
+  }
+
+  ///the circle has the intersection or not
+  static bool isIntersection(Point p1, Point p2, double r) {
+    var delta = sqrt(paramA(p1, p2) * paramA(p1, p2) - 4 * paramB(p1, p2, r));
+    return delta >= 0.0;
+  }
 
+  ///the x coordinate whether or not is between two point we give.
+  static bool _betweenPoint(x, Point p1, Point p2) {
+    if (p1.x > p2.x) {
+      return x > p2.x && x < p1.x;
+    } else {
+      return x > p1.x && x < p2.x;
+    }
+  }
+
+  static Point _equalX(Point p1, Point p2, double r) {
+    if (p1.y > p2.y) {
+      return Point(p2.x, p2.y + r);
+    } else if (p1.y < p2.y) {
+      return Point(p2.x, p2.y - r);
+    } else {
+      return p2;
+    }
+  }
+
+  static Point _equalY(Point p1, Point p2, double r) {
+    if (p1.x > p2.x) {
+      return Point(p2.x + r, p2.y);
+    } else if (p1.x < p2.x) {
+      return Point(p2.x - r, p2.y);
+    } else {
+      return p2;
+    }
+  }
+
+  ///intersection point
+  static Point intersectionPoint(Point p1, Point p2, double r) {
+    if (p1.x == p2.x) return _equalX(p1, p2, r);
+    if (p1.y == p2.y) return _equalY(p1, p2, r);
+    var delta = sqrt(paramA(p1, p2) * paramA(p1, p2) - 4 * paramB(p1, p2, r));
+    if (delta < 0.0) {
+      //when no intersection, i will return the center of the circ  le.
+      return p2;
+    }
+    var a_2 = -paramA(p1, p2) / 2.0;
+    var x1 = a_2 + delta / 2;
+    if (_betweenPoint(x1, p1, p2)) {
+      var y1 = Line.paramK(p1, p2) * x1 + Line.paramC(p1, p2);
+      return Point(x1, y1);
+    }
+    var x2 = a_2 - delta / 2;
+    var y2 = Line.paramK(p1, p2) * x2 + Line.paramC(p1, p2);
+    return Point(x2, y2);
+  }
 }

+ 263 - 0
lib/src/widget/trapezoid2.dart

@@ -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();
+  }
+}

+ 1 - 0
lib/widget.dart

@@ -3,3 +3,4 @@ export 'src/widget/radar_chart.dart';
 export 'src/widget/reverse_flex.dart';
 export 'src/widget/vertical_tab_bar.dart';
 export 'src/widget/trapezoid.dart';
+export 'src/widget/trapezoid2.dart';