From 60243a20fd8495c57536ba671d88e566383c8bb8 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Thu, 21 Jan 2021 17:09:25 +0900 Subject: [PATCH] improved checkered background performance --- lib/widgets/collection/thumbnail/vector.dart | 4 +- .../common/fx/checkered_decoration.dart | 55 +++++++------------ lib/widgets/settings/entry_background.dart | 4 +- lib/widgets/viewer/visual/raster.dart | 6 +- lib/widgets/viewer/visual/vector.dart | 4 +- 5 files changed, 28 insertions(+), 45 deletions(-) diff --git a/lib/widgets/collection/thumbnail/vector.dart b/lib/widgets/collection/thumbnail/vector.dart index 1c58c72ee..c930d9afa 100644 --- a/lib/widgets/collection/thumbnail/vector.dart +++ b/lib/widgets/collection/thumbnail/vector.dart @@ -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, diff --git a/lib/widgets/common/fx/checkered_decoration.dart b/lib/widgets/common/fx/checkered_decoration.dart index 4d541eaee..c5bc26520 100644 --- a/lib/widgets/common/fx/checkered_decoration.dart +++ b/lib/widgets/common/fx/checkered_decoration.dart @@ -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; } diff --git a/lib/widgets/settings/entry_background.dart b/lib/widgets/settings/entry_background.dart index ade54d894..51b0a9326 100644 --- a/lib/widgets/settings/entry_background.dart +++ b/lib/widgets/settings/entry_background.dart @@ -50,8 +50,8 @@ class _EntryBackgroundSelectorState extends State { break; case EntryBackground.checkered: child = ClipOval( - child: DecoratedBox( - decoration: CheckeredDecoration( + child: CustomPaint( + painter: CheckeredPainter( checkSize: radius, ), ), diff --git a/lib/widgets/viewer/visual/raster.dart b/lib/widgets/viewer/visual/raster.dart index 477ce2ad5..72098fb99 100644 --- a/lib/widgets/viewer/visual/raster.dart +++ b/lib/widgets/viewer/visual/raster.dart @@ -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 { builder: (context, fullImageLoaded, child) { if (!fullImageLoaded) return SizedBox.shrink(); - return DecoratedBox( - decoration: CheckeredDecoration( + return CustomPaint( + painter: CheckeredPainter( checkSize: checkSize, offset: offset, ), diff --git a/lib/widgets/viewer/visual/vector.dart b/lib/widgets/viewer/visual/vector.dart index 443b01602..1fe9d3e28 100644 --- a/lib/widgets/viewer/visual/vector.dart +++ b/lib/widgets/viewer/visual/vector.dart @@ -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, ),