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 fitSize = applyBoxFit(fit, entry.displaySize, availableSize).destination;
final offset = fitSize / 2 - availableSize / 2;
final child = DecoratedBox(
decoration: CheckeredDecoration(checkSize: extent / 8, offset: offset),
final child = CustomPaint(
painter: CheckeredPainter(checkSize: extent / 8, offset: offset),
child: SvgPicture(
UriPicture(
uri: entry.uri,

View file

@ -1,57 +1,40 @@
import 'package:flutter/material.dart';
class CheckeredDecoration extends Decoration {
final Color light, dark;
class CheckeredPainter extends CustomPainter {
final Paint lightPaint, darkPaint;
final double checkSize;
final Offset offset;
const CheckeredDecoration({
this.light = const Color(0xFF999999),
this.dark = const Color(0xFF666666),
CheckeredPainter({
Color light = const Color(0xFF999999),
Color dark = const Color(0xFF666666),
this.checkSize = 20,
this.offset = Offset.zero,
});
}) : lightPaint = Paint()..color = light,
darkPaint = Paint()..color = dark;
@override
_CheckeredDecorationPainter createBoxPainter([VoidCallback onChanged]) {
return _CheckeredDecorationPainter(this, onChanged);
}
}
void paint(Canvas canvas, Size size) {
final background = Rect.fromLTWH(0, 0, size.width, size.height);
canvas.drawRect(background, lightPaint);
class _CheckeredDecorationPainter extends BoxPainter {
final CheckeredDecoration decoration;
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 dx = offset.dx % (checkSize * 2);
final dy = offset.dy % (checkSize * 2);
final xMax = size.width / checkSize;
final yMax = size.height / checkSize;
for (var x = -2; x < xMax; x++) {
for (var y = -2; y < yMax; y++) {
if ((x + y) % 2 == 0) {
final rect = Rect.fromLTWH(dx + x * checkSize, dy + y * checkSize, checkSize, checkSize);
canvas.drawRect(rect, darkPaint);
final check = Rect.fromLTWH(dx + x * checkSize, dy + y * checkSize, checkSize, checkSize);
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;
case EntryBackground.checkered:
child = ClipOval(
child: DecoratedBox(
decoration: CheckeredDecoration(
child: CustomPaint(
painter: CheckeredPainter(
checkSize: radius,
),
),

View file

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

View file

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