Skip to content

Instantly share code, notes, and snippets.

@yeasin50
Created September 24, 2024 22:10
Show Gist options
  • Save yeasin50/f4d5217b7dbe42fb1c5b703d7ad2621a to your computer and use it in GitHub Desktop.
Save yeasin50/f4d5217b7dbe42fb1c5b703d7ad2621a to your computer and use it in GitHub Desktop.
Playing with canvas to render NxN grid [1000^2]
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
void main() => runApp(MaterialApp(home: Scaffold(body: Foo())));
class Foo extends StatefulWidget {
@override
State<Foo> createState() => _FooState();
}
class _FooState extends State<Foo> {
int numberOfItem = 500; ///! can be expensive for your cpu
@override
Widget build(BuildContext context) {
print("rebuid");
final gridSize = MediaQuery.sizeOf(context).width / numberOfItem;
final recorder = ui.PictureRecorder();
final canvas = Canvas(recorder);
const ShapeDecoration(color: Colors.black, shape: RoundedRectangleBorder())
.createBoxPainter(() {})
.paint(canvas, Offset.zero,
ImageConfiguration(size: Size.square(gridSize)));
final ui.Image image = recorder
.endRecording()
.toImageSync((gridSize).ceil(), (gridSize).ceil());
return Column(
children: [
TextFormField(
initialValue: numberOfItem.toString(),
textAlign: ui.TextAlign.center,
onChanged: (value) {
final nb = int.tryParse(value) ?? 0;
if (nb == 0) return;
setState(() {
numberOfItem = nb;
});
},
),
Expanded(
child: InteractiveViewer(
maxScale: 100,
child: ClipRect(
child: RepaintBoundary(
child: CustomPaint(
key: ValueKey("${numberOfItem}"),
painter: FooPainter(
image: image,
numberOfItem: numberOfItem,
gridSize: gridSize,
),
child: const SizedBox.expand(),
),
),
),
),
),
],
);
}
}
// https://stackoverflow.com/a/78769595/10157127
class FooPainter extends CustomPainter {
final int numberOfItem;
final double gridSize;
FooPainter({
required this.image,
required this.numberOfItem,
required this.gridSize,
});
final ui.Image image;
@override
void paint(Canvas canvas, Size size) {
final rects = List.filled(
numberOfItem * numberOfItem, Offset.zero & Size.square(gridSize));
final colors = List.generate(numberOfItem * numberOfItem,
(i) => Colors.primaries[i % Colors.primaries.length ~/ 2]);
List<ui.Offset> offsets = [];
for (int y = 0; y < numberOfItem; y++) {
for (int x = 0; x < numberOfItem; x++) {
offsets.add(Offset(x * gridSize, y * gridSize));
}
}
List<ui.RSTransform> transforms = [
...offsets.map(
(o) => ui.RSTransform(1, 0, o.dx, o.dy),
),
];
canvas.drawAtlas(
image, transforms, rects, colors, BlendMode.dstATop, null, Paint());
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment