grid.dart 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. import 'dart:async';
  2. import 'dart:math';
  3. import 'package:flutter/material.dart';
  4. import 'package:grpc/grpc_web.dart';
  5. import 'package:cyclop/cyclop.dart';
  6. import 'src/color_ref.dart';
  7. import 'src/connection/ws.dart';
  8. import 'src/widget/square.dart';
  9. class TransformationsDemo extends StatefulWidget {
  10. const TransformationsDemo({Key? key}) : super(key: key);
  11. @override
  12. State<TransformationsDemo> createState() => _TransformationsDemoState();
  13. }
  14. class _TransformationsDemoState extends State<TransformationsDemo>
  15. with TickerProviderStateMixin {
  16. final GlobalKey _targetKey = GlobalKey();
  17. final Map<Point<int>, Widget> elements = <Point<int>, Widget>{};
  18. Set<Color> swatches = Colors.primaries.map((e) => Color(e.value)).toSet();
  19. final double minScale = 2;
  20. final ColorRef cc = ColorRef(Colors.blueGrey);
  21. final TransformationController _transformationController =
  22. TransformationController();
  23. Animation<Matrix4>? _animationReset;
  24. late AnimationController _controllerReset;
  25. Matrix4? _homeMatrix;
  26. final channel = GrpcWebClientChannel.xhr(Uri.parse('http://localhost:8080'));
  27. @override
  28. void initState() {
  29. super.initState();
  30. WebRTCChannels().connect((x) {});
  31. }
  32. @override
  33. Widget build(BuildContext context) {
  34. // The scene is drawn by a CustomPaint, but user interaction is handled by
  35. // the InteractiveViewer parent widget.
  36. return Scaffold(
  37. backgroundColor: Theme.of(context).colorScheme.primary,
  38. // appBar: AppBar(
  39. // automaticallyImplyLeading: false,
  40. // title: const Text('title'),
  41. // ),
  42. body: Container(
  43. color: Colors.white,
  44. child: LayoutBuilder(
  45. builder: (context, constraints) {
  46. // Start the first render, start the scene centered in the viewport.
  47. if (_homeMatrix == null) {
  48. _homeMatrix = Matrix4.identity() * minScale
  49. ..translate(0, 0);
  50. _transformationController.value = _homeMatrix!;
  51. createComponentMap();
  52. }
  53. return ClipRect(
  54. child: MouseRegion(
  55. cursor: SystemMouseCursors.click,
  56. child: GestureDetector(
  57. behavior: HitTestBehavior.opaque,
  58. // onTapUp: _onTapUp,
  59. child: InteractiveViewer(
  60. constrained: false,
  61. key: _targetKey,
  62. transformationController: _transformationController,
  63. boundaryMargin: const EdgeInsets.all(0),
  64. minScale: minScale,
  65. maxScale: 30,
  66. // onInteractionStart: _onScaleStart,
  67. onInteractionUpdate: _onInteractionUpdate,
  68. onInteractionEnd: _onInteractionEnd,
  69. child: SizedBox(
  70. width: 256 * 90,
  71. height: 256 * 53,
  72. child: GridPaper(
  73. child: Stack(children: elements.values.toList()),
  74. ),
  75. ),
  76. ),
  77. ),
  78. ),
  79. );
  80. },
  81. ),
  82. ),
  83. // persistentFooterButtons: [],
  84. floatingActionButton: ColorButton(
  85. darkMode: true,
  86. key: const Key('c2'),
  87. color: cc.getColor(),
  88. boxShape: BoxShape.circle,
  89. swatches: swatches,
  90. size: 64,
  91. config: const ColorPickerConfig(
  92. enableOpacity: false,
  93. enableLibrary: true,
  94. ),
  95. onColorChanged: (value) => setState(() {
  96. cc.setColor(value);
  97. }),
  98. onSwatchesChanged: (newSwatches) =>
  99. setState(() => swatches = newSwatches),
  100. ),
  101. );
  102. }
  103. @override
  104. void dispose() {
  105. // _controllerReset.dispose();
  106. super.dispose();
  107. }
  108. void _onInteractionUpdate(ScaleUpdateDetails details) => _onUpdate();
  109. void _onInteractionEnd(ScaleEndDetails details) {
  110. _onUpdate();
  111. Timer(const Duration(milliseconds: 250), () => _onUpdate());
  112. Timer(const Duration(milliseconds: 500), () => _onUpdate());
  113. }
  114. void _onUpdate() {
  115. setState(() {
  116. createComponentMap();
  117. });
  118. }
  119. void createComponentMap() {
  120. var bounds = MediaQuery.of(context).size;
  121. var topLeft =
  122. _transformationController.toScene(bounds.topLeft(Offset.zero));
  123. var bottomRight =
  124. _transformationController.toScene(bounds.bottomRight(Offset.zero));
  125. var newSet = <Point<int>>{};
  126. var rec = Rectangle<int>.fromPoints(
  127. _offsetToIndex(topLeft), _offsetToIndex(bottomRight));
  128. for (var i = rec.left; i <= rec.right; i++) {
  129. for (var j = rec.top; j <= rec.bottom; j++) {
  130. newSet.add(Point<int>(i, j));
  131. }
  132. }
  133. final oldKeys = Set.from(elements.keys);
  134. final newPoints = newSet.difference(oldKeys);
  135. final disposePoints = oldKeys.difference(newSet);
  136. for (var point in newPoints) {
  137. elements[point] = Container(
  138. key: Key(point.toString()),
  139. margin: EdgeInsets.only(left: 256.0 * point.x, top: 256.0 * point.y),
  140. child: Stack(children: [
  141. CustomPaint(
  142. painter: OpenPainter(point),
  143. ),
  144. Text(point.toString()),
  145. SquareComponent(color: cc, tile: point, key: Key(point.toString())),
  146. ])
  147. // child: SquareComponent(point, cc),
  148. );
  149. }
  150. for (var point in disposePoints) {
  151. elements.remove(point);
  152. }
  153. }
  154. }
  155. Point<int> _offsetToIndex(Offset offset) {
  156. offset = offset / 256.0;
  157. var x = offset.dx.floor();
  158. var y = offset.dy.floor();
  159. if (x < 0) x = 0;
  160. if (y < 0) y = 0;
  161. return Point<int>(x, y);
  162. }
  163. class OpenPainter extends CustomPainter {
  164. Point<int> point;
  165. OpenPainter(Point<int> this.point);
  166. @override
  167. void paint(Canvas canvas, Size size) {
  168. var paint1 = Paint()
  169. ..color = Color.fromARGB(
  170. 100,
  171. ((point.x * point.y * 7) % 64) * 4,
  172. ((point.x * 10039) % 64) * 4,
  173. ((point.y * 10061) % 64) * 4,
  174. )
  175. ..style = PaintingStyle.fill;
  176. canvas.drawRect(const Offset(0, 0) & const Size(256, 256), paint1);
  177. }
  178. @override
  179. bool shouldRepaint(CustomPainter oldDelegate) => true;
  180. }