Skip to content

Instantly share code, notes, and snippets.

@Abion47
Last active April 1, 2022 14:45
Show Gist options
  • Save Abion47/8e75be2a1d5737decbc88b829ee75bb3 to your computer and use it in GitHub Desktop.
Save Abion47/8e75be2a1d5737decbc88b829ee75bb3 to your computer and use it in GitHub Desktop.
Flutter Pixel Vertex Painter
// ignore_for_file: prefer_const_constructors_in_immutables
import 'dart:async';
import 'dart:math' as math;
import 'dart:ui';
import 'dart:typed_data';
import 'package:flutter/material.dart';
void main() {
runApp(const HomePage());
}
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
void initState() {
super.initState();
Timer.periodic(const Duration(milliseconds: 1), (_) => setState(() {}));
}
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(
title: FPSCounter(),
),
body: Center(
child: SizedBox(
width: 200,
height: 200,
child: CustomPaint(
painter: NoisePainter(),
),
),
),
),
);
}
}
class FPSCounter extends StatefulWidget {
FPSCounter({Key? key}) : super(key: key);
@override
State<FPSCounter> createState() => _FPSCounterState();
}
class _FPSCounterState extends State<FPSCounter> {
static const sampleCount = 100;
late List<double> samples;
late int lastTimestamp;
int index = 0;
@override
void initState() {
samples = List.filled(sampleCount, 0);
lastTimestamp = DateTime.now().microsecondsSinceEpoch;
super.initState();
}
String calculateMs() {
final timestamp = DateTime.now().microsecondsSinceEpoch;
final diff = (timestamp - lastTimestamp) / 1000;
samples[index] = diff;
lastTimestamp = timestamp;
index++;
if (index >= samples.length) index = 0;
var average = 0.0;
for (int i = 0; i < samples.length; i++) {
if (samples[i] == 0) return '...';
average += samples[i];
}
return (average / samples.length).toStringAsFixed(1);
}
@override
Widget build(BuildContext context) {
final ms = calculateMs();
return Text("$ms average ms");
}
}
class NoisePainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final iw = size.width.toInt();
final ih = size.height.toInt();
final r = math.Random();
final stride = ih * 6;
final length = iw * stride;
final positions = Float32List(length * 2);
final colors = Int32List(length);
int pidx, cidx, color;
for (var y = 0.0; y < ih; y++) {
for (var x = 0.0; x < iw; x++) {
cidx = (y * stride + x * 6).toInt();
pidx = cidx * 2;
positions[pidx] = x;
positions[pidx + 1] = y;
positions[pidx + 2] = x + 1;
positions[pidx + 3] = y;
positions[pidx + 4] = x + 1;
positions[pidx + 5] = y + 1;
positions[pidx + 6] = x;
positions[pidx + 7] = y;
positions[pidx + 8] = x + 1;
positions[pidx + 9] = y + 1;
positions[pidx + 10] = x;
positions[pidx + 11] = y + 1;
color = 0xFF000000 | r.nextInt(0x00FFFFFF);
colors[cidx] = color;
colors[cidx + 1] = color;
colors[cidx + 2] = color;
colors[cidx + 3] = color;
colors[cidx + 4] = color;
colors[cidx + 5] = color;
}
}
canvas.drawVertices(
Vertices.raw(VertexMode.triangles, positions, colors: colors),
BlendMode.src,
Paint(),
);
}
@override
bool shouldRepaint(NoisePainter oldDelegate) {
return true;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment