mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
Mirror before scaling in _AnimatedIconPainter (#93312)
This commit is contained in:
parent
32122480b5
commit
42a8122314
1
AUTHORS
1
AUTHORS
@ -91,3 +91,4 @@ Denis Grafov <grafov.denis@gmail.com>
|
|||||||
TheOneWithTheBraid <the-one@with-the-braid.cf>
|
TheOneWithTheBraid <the-one@with-the-braid.cf>
|
||||||
Alberto Miola <betoman96@gmail.com>
|
Alberto Miola <betoman96@gmail.com>
|
||||||
Twin Sun, LLC <google-contrib@twinsunsolutions.com>
|
Twin Sun, LLC <google-contrib@twinsunsolutions.com>
|
||||||
|
Taskulu LDA <contributions@taskulu.com>
|
||||||
|
@ -156,11 +156,11 @@ class _AnimatedIconPainter extends CustomPainter {
|
|||||||
void paint(ui.Canvas canvas, Size size) {
|
void paint(ui.Canvas canvas, Size size) {
|
||||||
// The RenderCustomPaint render object performs canvas.save before invoking
|
// The RenderCustomPaint render object performs canvas.save before invoking
|
||||||
// this and canvas.restore after, so we don't need to do it here.
|
// this and canvas.restore after, so we don't need to do it here.
|
||||||
canvas.scale(scale, scale);
|
|
||||||
if (shouldMirror) {
|
if (shouldMirror) {
|
||||||
canvas.rotate(math.pi);
|
canvas.rotate(math.pi);
|
||||||
canvas.translate(-size.width, -size.height);
|
canvas.translate(-size.width, -size.height);
|
||||||
}
|
}
|
||||||
|
canvas.scale(scale, scale);
|
||||||
|
|
||||||
final double clampedProgress = progress.value.clamp(0.0, 1.0);
|
final double clampedProgress = progress.value.clamp(0.0, 1.0);
|
||||||
for (final _PathFrames path in paths)
|
for (final _PathFrames path in paths)
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
@Tags(<String>['reduced-test-set'])
|
||||||
|
|
||||||
import 'dart:math' as math show pi;
|
import 'dart:math' as math show pi;
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@ -26,6 +28,7 @@ class MockCanvas extends Fake implements Canvas {
|
|||||||
void scale(double sx, [double? sy]) {
|
void scale(double sx, [double? sy]) {
|
||||||
capturedSx = sx;
|
capturedSx = sx;
|
||||||
capturedSy = sy!;
|
capturedSy = sy!;
|
||||||
|
invocations.add(RecordedScale(sx, sy));
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<RecordedCanvasCall> invocations = <RecordedCanvasCall>[];
|
final List<RecordedCanvasCall> invocations = <RecordedCanvasCall>[];
|
||||||
@ -75,6 +78,21 @@ class RecordedTranslate extends RecordedCanvasCall {
|
|||||||
int get hashCode => hashValues(dx, dy);
|
int get hashCode => hashValues(dx, dy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class RecordedScale extends RecordedCanvasCall {
|
||||||
|
const RecordedScale(this.sx, this.sy);
|
||||||
|
|
||||||
|
final double sx;
|
||||||
|
final double sy;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return other is RecordedScale && other.sx == sx && other.sy == sy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => hashValues(sx, sy);
|
||||||
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
testWidgets('IconTheme color', (WidgetTester tester) async {
|
testWidgets('IconTheme color', (WidgetTester tester) async {
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
@ -218,9 +236,11 @@ void main() {
|
|||||||
data: IconThemeData(
|
data: IconThemeData(
|
||||||
color: Color(0xFF666666),
|
color: Color(0xFF666666),
|
||||||
),
|
),
|
||||||
child: AnimatedIcon(
|
child: RepaintBoundary(
|
||||||
progress: AlwaysStoppedAnimation<double>(0.0),
|
child: AnimatedIcon(
|
||||||
icon: AnimatedIcons.arrow_menu,
|
progress: AlwaysStoppedAnimation<double>(0.0),
|
||||||
|
icon: AnimatedIcons.arrow_menu,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -231,7 +251,10 @@ void main() {
|
|||||||
expect(canvas.invocations, const <RecordedCanvasCall>[
|
expect(canvas.invocations, const <RecordedCanvasCall>[
|
||||||
RecordedRotate(math.pi),
|
RecordedRotate(math.pi),
|
||||||
RecordedTranslate(-48, -48),
|
RecordedTranslate(-48, -48),
|
||||||
|
RecordedScale(0.5, 0.5),
|
||||||
]);
|
]);
|
||||||
|
await expectLater(find.byType(AnimatedIcon),
|
||||||
|
matchesGoldenFile('animated_icons_test.icon.rtl.png'));
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Inherited text direction ltr', (WidgetTester tester) async {
|
testWidgets('Inherited text direction ltr', (WidgetTester tester) async {
|
||||||
@ -242,9 +265,11 @@ void main() {
|
|||||||
data: IconThemeData(
|
data: IconThemeData(
|
||||||
color: Color(0xFF666666),
|
color: Color(0xFF666666),
|
||||||
),
|
),
|
||||||
child: AnimatedIcon(
|
child: RepaintBoundary(
|
||||||
progress: AlwaysStoppedAnimation<double>(0.0),
|
child: AnimatedIcon(
|
||||||
icon: AnimatedIcons.arrow_menu,
|
progress: AlwaysStoppedAnimation<double>(0.0),
|
||||||
|
icon: AnimatedIcons.arrow_menu,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -252,7 +277,11 @@ void main() {
|
|||||||
final CustomPaint customPaint = tester.widget(find.byType(CustomPaint));
|
final CustomPaint customPaint = tester.widget(find.byType(CustomPaint));
|
||||||
final MockCanvas canvas = MockCanvas();
|
final MockCanvas canvas = MockCanvas();
|
||||||
customPaint.painter!.paint(canvas, const Size(48.0, 48.0));
|
customPaint.painter!.paint(canvas, const Size(48.0, 48.0));
|
||||||
expect(canvas.invocations, isEmpty);
|
expect(canvas.invocations, const <RecordedCanvasCall>[
|
||||||
|
RecordedScale(0.5, 0.5),
|
||||||
|
]);
|
||||||
|
await expectLater(find.byType(AnimatedIcon),
|
||||||
|
matchesGoldenFile('animated_icons_test.icon.ltr.png'));
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Inherited text direction overridden', (WidgetTester tester) async {
|
testWidgets('Inherited text direction overridden', (WidgetTester tester) async {
|
||||||
@ -277,8 +306,25 @@ void main() {
|
|||||||
expect(canvas.invocations, const <RecordedCanvasCall>[
|
expect(canvas.invocations, const <RecordedCanvasCall>[
|
||||||
RecordedRotate(math.pi),
|
RecordedRotate(math.pi),
|
||||||
RecordedTranslate(-48, -48),
|
RecordedTranslate(-48, -48),
|
||||||
|
RecordedScale(0.5, 0.5),
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('Direction has no effect on position of widget', (WidgetTester tester) async {
|
||||||
|
const AnimatedIcon icon = AnimatedIcon(
|
||||||
|
progress: AlwaysStoppedAnimation<double>(0.0),
|
||||||
|
icon: AnimatedIcons.arrow_menu,
|
||||||
|
);
|
||||||
|
await tester.pumpWidget(
|
||||||
|
const Directionality(textDirection: TextDirection.rtl, child: icon),
|
||||||
|
);
|
||||||
|
final Rect rtlRect = tester.getRect(find.byType(AnimatedIcon));
|
||||||
|
await tester.pumpWidget(
|
||||||
|
const Directionality(textDirection: TextDirection.ltr, child: icon),
|
||||||
|
);
|
||||||
|
final Rect ltrRect = tester.getRect(find.byType(AnimatedIcon));
|
||||||
|
expect(rtlRect, ltrRect);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
PaintColorMatcher hasColor(int color) {
|
PaintColorMatcher hasColor(int color) {
|
||||||
|
@ -187,9 +187,9 @@ void main() {
|
|||||||
);
|
);
|
||||||
painter.paint(mockCanvas, size);
|
painter.paint(mockCanvas, size);
|
||||||
mockCanvas.verifyCallsInOrder(<MockCall>[
|
mockCanvas.verifyCallsInOrder(<MockCall>[
|
||||||
MockCall('scale', <dynamic>[1.0, 1.0]),
|
|
||||||
MockCall('rotate', <dynamic>[math.pi]),
|
MockCall('rotate', <dynamic>[math.pi]),
|
||||||
MockCall('translate', <dynamic>[-48.0, -48.0]),
|
MockCall('translate', <dynamic>[-48.0, -48.0]),
|
||||||
|
MockCall('scale', <dynamic>[1.0, 1.0]),
|
||||||
MockCall.any('drawPath'),
|
MockCall.any('drawPath'),
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user