|
@@ -1,3 +1,4 @@
|
|
|
+import 'dart:async';
|
|
|
import 'dart:math';
|
|
|
import 'package:flutter/material.dart';
|
|
|
import 'package:grpc/grpc_web.dart';
|
|
@@ -15,15 +16,13 @@ class TransformationsDemo extends StatefulWidget {
|
|
|
State<TransformationsDemo> createState() => _TransformationsDemoState();
|
|
|
}
|
|
|
|
|
|
-
|
|
|
class _TransformationsDemoState extends State<TransformationsDemo>
|
|
|
with TickerProviderStateMixin {
|
|
|
final GlobalKey _targetKey = GlobalKey();
|
|
|
- Map<Point<int>, Widget> elements = <Point<int>, Widget>{};
|
|
|
- Color appbarColor = Colors.blueGrey;
|
|
|
+ final Map<Point<int>, Widget> elements = <Point<int>, Widget>{};
|
|
|
Set<Color> swatches = Colors.primaries.map((e) => Color(e.value)).toSet();
|
|
|
- double minScale = 2;
|
|
|
- ColorRef cc = ColorRef();
|
|
|
+ final double minScale = 2;
|
|
|
+ final ColorRef cc = ColorRef(Colors.blueGrey);
|
|
|
|
|
|
final TransformationController _transformationController =
|
|
|
TransformationController();
|
|
@@ -37,9 +36,6 @@ class _TransformationsDemoState extends State<TransformationsDemo>
|
|
|
void initState() {
|
|
|
super.initState();
|
|
|
WebRTCChannels().connect((x) {});
|
|
|
- // _controllerReset = AnimationController(
|
|
|
- // vsync: this,
|
|
|
- // );
|
|
|
}
|
|
|
|
|
|
@override
|
|
@@ -61,13 +57,7 @@ class _TransformationsDemoState extends State<TransformationsDemo>
|
|
|
_homeMatrix = Matrix4.identity() * minScale
|
|
|
..translate(0, 0);
|
|
|
_transformationController.value = _homeMatrix!;
|
|
|
-
|
|
|
- elements = _start(
|
|
|
- context: context,
|
|
|
- channel: channel,
|
|
|
- transformationController: _transformationController);
|
|
|
-
|
|
|
- // _onUpdate(context: context);
|
|
|
+ createComponentMap();
|
|
|
}
|
|
|
|
|
|
return ClipRect(
|
|
@@ -80,7 +70,7 @@ class _TransformationsDemoState extends State<TransformationsDemo>
|
|
|
constrained: false,
|
|
|
key: _targetKey,
|
|
|
transformationController: _transformationController,
|
|
|
- boundaryMargin: EdgeInsets.all(0),
|
|
|
+ boundaryMargin: const EdgeInsets.all(0),
|
|
|
minScale: minScale,
|
|
|
maxScale: 30,
|
|
|
// onInteractionStart: _onScaleStart,
|
|
@@ -89,7 +79,9 @@ class _TransformationsDemoState extends State<TransformationsDemo>
|
|
|
child: SizedBox(
|
|
|
width: 256 * 90,
|
|
|
height: 256 * 53,
|
|
|
- child: Stack(children: elements.values.toList()),
|
|
|
+ child: GridPaper(
|
|
|
+ child: Stack(children: elements.values.toList()),
|
|
|
+ ),
|
|
|
),
|
|
|
),
|
|
|
),
|
|
@@ -102,7 +94,7 @@ class _TransformationsDemoState extends State<TransformationsDemo>
|
|
|
floatingActionButton: ColorButton(
|
|
|
darkMode: true,
|
|
|
key: const Key('c2'),
|
|
|
- color: appbarColor,
|
|
|
+ color: cc.getColor(),
|
|
|
boxShape: BoxShape.circle,
|
|
|
swatches: swatches,
|
|
|
size: 64,
|
|
@@ -110,10 +102,9 @@ class _TransformationsDemoState extends State<TransformationsDemo>
|
|
|
enableOpacity: false,
|
|
|
enableLibrary: true,
|
|
|
),
|
|
|
- onColorChanged: (value) => setState(() {
|
|
|
- appbarColor = value;
|
|
|
- cc.setColor(appbarColor);
|
|
|
- }),
|
|
|
+ onColorChanged: (value) => setState(() {
|
|
|
+ cc.setColor(value);
|
|
|
+ }),
|
|
|
onSwatchesChanged: (newSwatches) =>
|
|
|
setState(() => swatches = newSwatches),
|
|
|
),
|
|
@@ -126,31 +117,26 @@ class _TransformationsDemoState extends State<TransformationsDemo>
|
|
|
super.dispose();
|
|
|
}
|
|
|
|
|
|
- void _onInteractionUpdate(ScaleUpdateDetails details) {
|
|
|
+ void _onInteractionUpdate(ScaleUpdateDetails details) => _onUpdate();
|
|
|
+ void _onInteractionEnd(ScaleEndDetails details) {
|
|
|
_onUpdate();
|
|
|
+ Timer(const Duration(milliseconds: 250), () => _onUpdate());
|
|
|
+ Timer(const Duration(milliseconds: 500), () => _onUpdate());
|
|
|
}
|
|
|
|
|
|
- void _onUpdate({BuildContext? context}) {
|
|
|
- var context2 = context ?? _targetKey.currentContext!;
|
|
|
+ void _onUpdate() {
|
|
|
setState(() {
|
|
|
- _start(
|
|
|
- context: context2,
|
|
|
- channel: channel,
|
|
|
- transformationController: _transformationController,
|
|
|
- elements: elements);
|
|
|
+ createComponentMap();
|
|
|
});
|
|
|
}
|
|
|
|
|
|
- Map<Point<int>, Widget> _start(
|
|
|
- {required BuildContext context,
|
|
|
- required GrpcWebClientChannel channel,
|
|
|
- required TransformationController transformationController,
|
|
|
- Map<Point<int>, Widget>? elements}) {
|
|
|
+ void createComponentMap() {
|
|
|
var bounds = MediaQuery.of(context).size;
|
|
|
|
|
|
- var topLeft = transformationController.toScene(bounds.topLeft(Offset.zero));
|
|
|
+ var topLeft =
|
|
|
+ _transformationController.toScene(bounds.topLeft(Offset.zero));
|
|
|
var bottomRight =
|
|
|
- transformationController.toScene(bounds.bottomRight(Offset.zero));
|
|
|
+ _transformationController.toScene(bounds.bottomRight(Offset.zero));
|
|
|
|
|
|
var newSet = <Point<int>>{};
|
|
|
|
|
@@ -162,25 +148,29 @@ class _TransformationsDemoState extends State<TransformationsDemo>
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- var elements2 = elements ?? <Point<int>, Widget>{};
|
|
|
- newSet
|
|
|
- .difference(Set.from(elements2.keys))
|
|
|
- .forEach((point) => elements2[point] ??= Container(
|
|
|
- margin:
|
|
|
- EdgeInsets.only(left: 256.0 * point.x, top: 256.0 * point.y),
|
|
|
- child: SquareComponent(point, cc),
|
|
|
- ));
|
|
|
-
|
|
|
- Set.from(elements2.keys).difference(newSet).forEach(
|
|
|
- (point) => elements2.remove(point),
|
|
|
- );
|
|
|
- // print(elements2.length);
|
|
|
- // WebRTCChannels().connect();
|
|
|
-
|
|
|
- return elements2;
|
|
|
- }
|
|
|
+ final oldKeys = Set.from(elements.keys);
|
|
|
+ final newPoints = newSet.difference(oldKeys);
|
|
|
+ final disposePoints = oldKeys.difference(newSet);
|
|
|
+
|
|
|
+ for (var point in newPoints) {
|
|
|
+ elements[point] = Container(
|
|
|
+ key: Key(point.toString()),
|
|
|
+ margin: EdgeInsets.only(left: 256.0 * point.x, top: 256.0 * point.y),
|
|
|
+ child: Stack(children: [
|
|
|
+ CustomPaint(
|
|
|
+ painter: OpenPainter(point),
|
|
|
+ ),
|
|
|
+ Text(point.toString()),
|
|
|
+ SquareComponent(color: cc, tile: point, key: Key(point.toString())),
|
|
|
+ ])
|
|
|
+ // child: SquareComponent(point, cc),
|
|
|
+ );
|
|
|
+ }
|
|
|
|
|
|
- void _onInteractionEnd(ScaleEndDetails details) => _onUpdate();
|
|
|
+ for (var point in disposePoints) {
|
|
|
+ elements.remove(point);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
Point<int> _offsetToIndex(Offset offset) {
|
|
@@ -191,3 +181,25 @@ Point<int> _offsetToIndex(Offset offset) {
|
|
|
if (y < 0) y = 0;
|
|
|
return Point<int>(x, y);
|
|
|
}
|
|
|
+
|
|
|
+class OpenPainter extends CustomPainter {
|
|
|
+ Point<int> point;
|
|
|
+
|
|
|
+ OpenPainter(Point<int> this.point);
|
|
|
+
|
|
|
+ @override
|
|
|
+ void paint(Canvas canvas, Size size) {
|
|
|
+ var paint1 = Paint()
|
|
|
+ ..color = Color.fromARGB(
|
|
|
+ 100,
|
|
|
+ ((point.x * point.y * 7) % 64) * 4,
|
|
|
+ ((point.x * 10039) % 64) * 4,
|
|
|
+ ((point.y * 10061) % 64) * 4,
|
|
|
+ )
|
|
|
+ ..style = PaintingStyle.fill;
|
|
|
+ canvas.drawRect(const Offset(0, 0) & const Size(256, 256), paint1);
|
|
|
+ }
|
|
|
+
|
|
|
+ @override
|
|
|
+ bool shouldRepaint(CustomPainter oldDelegate) => true;
|
|
|
+}
|