improved checkered background performance

This commit is contained in:
Thibault Deckers 2021-01-21 17:09:25 +09:00
parent 07de79fe84
commit 60243a20fd
5 changed files with 28 additions and 45 deletions

View file

@ -31,8 +31,8 @@ class VectorImageThumbnail extends StatelessWidget {
final availableSize = constraints.biggest; final availableSize = constraints.biggest;
final fitSize = applyBoxFit(fit, entry.displaySize, availableSize).destination; final fitSize = applyBoxFit(fit, entry.displaySize, availableSize).destination;
final offset = fitSize / 2 - availableSize / 2; final offset = fitSize / 2 - availableSize / 2;
final child = DecoratedBox( final child = CustomPaint(
decoration: CheckeredDecoration(checkSize: extent / 8, offset: offset), painter: CheckeredPainter(checkSize: extent / 8, offset: offset),
child: SvgPicture( child: SvgPicture(
UriPicture( UriPicture(
uri: entry.uri, uri: entry.uri,

View file

@ -1,57 +1,40 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class CheckeredDecoration extends Decoration { class CheckeredPainter extends CustomPainter {
final Color light, dark; final Paint lightPaint, darkPaint;
final double checkSize; final double checkSize;
final Offset offset; final Offset offset;
const CheckeredDecoration({ CheckeredPainter({
this.light = const Color(0xFF999999), Color light = const Color(0xFF999999),
this.dark = const Color(0xFF666666), Color dark = const Color(0xFF666666),
this.checkSize = 20, this.checkSize = 20,
this.offset = Offset.zero, this.offset = Offset.zero,
}); }) : lightPaint = Paint()..color = light,
darkPaint = Paint()..color = dark;
@override @override
_CheckeredDecorationPainter createBoxPainter([VoidCallback onChanged]) { void paint(Canvas canvas, Size size) {
return _CheckeredDecorationPainter(this, onChanged); final background = Rect.fromLTWH(0, 0, size.width, size.height);
} canvas.drawRect(background, lightPaint);
}
class _CheckeredDecorationPainter extends BoxPainter { final dx = offset.dx % (checkSize * 2);
final CheckeredDecoration decoration; final dy = offset.dy % (checkSize * 2);
const _CheckeredDecorationPainter(this.decoration, VoidCallback onChanged) : super(onChanged);
@override
void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {
final size = configuration.size;
var dx = offset.dx;
var dy = offset.dy;
final lightPaint = Paint()..color = decoration.light;
final darkPaint = Paint()..color = decoration.dark;
final checkSize = decoration.checkSize;
// save/restore because of the clip
canvas.save();
canvas.clipRect(Rect.fromLTWH(dx, dy, size.width, size.height));
canvas.drawPaint(lightPaint);
dx += decoration.offset.dx % (decoration.checkSize * 2);
dy += decoration.offset.dy % (decoration.checkSize * 2);
final xMax = size.width / checkSize; final xMax = size.width / checkSize;
final yMax = size.height / checkSize; final yMax = size.height / checkSize;
for (var x = -2; x < xMax; x++) { for (var x = -2; x < xMax; x++) {
for (var y = -2; y < yMax; y++) { for (var y = -2; y < yMax; y++) {
if ((x + y) % 2 == 0) { if ((x + y) % 2 == 0) {
final rect = Rect.fromLTWH(dx + x * checkSize, dy + y * checkSize, checkSize, checkSize); final check = Rect.fromLTWH(dx + x * checkSize, dy + y * checkSize, checkSize, checkSize);
canvas.drawRect(rect, darkPaint); if (check.overlaps(background)) {
canvas.drawRect(check.intersect(background), darkPaint);
}
} }
} }
} }
canvas.restore();
} }
@override
bool shouldRepaint(CustomPainter oldDelegate) => false;
} }

View file

@ -50,8 +50,8 @@ class _EntryBackgroundSelectorState extends State<EntryBackgroundSelector> {
break; break;
case EntryBackground.checkered: case EntryBackground.checkered:
child = ClipOval( child = ClipOval(
child: DecoratedBox( child: CustomPaint(
decoration: CheckeredDecoration( painter: CheckeredPainter(
checkSize: radius, checkSize: radius,
), ),
), ),

View file

@ -1,8 +1,8 @@
import 'dart:math'; import 'dart:math';
import 'package:aves/image_providers/region_provider.dart'; import 'package:aves/image_providers/region_provider.dart';
import 'package:aves/model/entry_images.dart';
import 'package:aves/model/entry.dart'; import 'package:aves/model/entry.dart';
import 'package:aves/model/entry_images.dart';
import 'package:aves/model/settings/entry_background.dart'; import 'package:aves/model/settings/entry_background.dart';
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
import 'package:aves/utils/math_utils.dart'; import 'package:aves/utils/math_utils.dart';
@ -199,8 +199,8 @@ class _RasterImageViewState extends State<RasterImageView> {
builder: (context, fullImageLoaded, child) { builder: (context, fullImageLoaded, child) {
if (!fullImageLoaded) return SizedBox.shrink(); if (!fullImageLoaded) return SizedBox.shrink();
return DecoratedBox( return CustomPaint(
decoration: CheckeredDecoration( painter: CheckeredPainter(
checkSize: checkSize, checkSize: checkSize,
offset: offset, offset: offset,
), ),

View file

@ -36,8 +36,8 @@ class VectorViewCheckeredBackground extends StatelessWidget {
Positioned( Positioned(
width: decorationSize.width, width: decorationSize.width,
height: decorationSize.height, height: decorationSize.height,
child: DecoratedBox( child: CustomPaint(
decoration: CheckeredDecoration( painter: CheckeredPainter(
checkSize: checkSize, checkSize: checkSize,
offset: offset, offset: offset,
), ),