Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
15739345
Unverified
Commit
15739345
authored
Jul 07, 2022
by
Jonah Williams
Committed by
GitHub
Jul 07, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[framework] don't composite with a scale of 0.0 (#106982)
parent
c51bf2fa
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
200 additions
and
5 deletions
+200
-5
proxy_box.dart
packages/flutter/lib/src/rendering/proxy_box.dart
+7
-0
basic.dart
packages/flutter/lib/src/widgets/basic.dart
+34
-1
transform_test.dart
packages/flutter/test/widgets/transform_test.dart
+147
-0
transitions_test.dart
packages/flutter/test/widgets/transitions_test.dart
+12
-4
No files found.
packages/flutter/lib/src/rendering/proxy_box.dart
View file @
15739345
...
...
@@ -2604,6 +2604,13 @@ class RenderTransform extends RenderProxyBox {
if
(
filterQuality
==
null
)
{
final
Offset
?
childOffset
=
MatrixUtils
.
getAsTranslation
(
transform
);
if
(
childOffset
==
null
)
{
// if the matrix is singular the children would be compressed to a line or
// single point, instead short-circuit and paint nothing.
final
double
det
=
transform
.
determinant
();
if
(
det
==
0
||
!
det
.
isFinite
)
{
layer
=
null
;
return
;
}
layer
=
context
.
pushTransform
(
needsCompositing
,
offset
,
...
...
packages/flutter/lib/src/widgets/basic.dart
View file @
15739345
...
...
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:math'
as
math
;
import
'dart:ui'
as
ui
show
Image
,
ImageFilter
,
TextHeightBehavior
;
import
'package:flutter/animation.dart'
;
...
...
@@ -1304,7 +1305,7 @@ class Transform extends SingleChildRenderObjectWidget {
this
.
transformHitTests
=
true
,
this
.
filterQuality
,
super
.
child
,
})
:
transform
=
Matrix4
.
rotationZ
(
angle
);
})
:
transform
=
_computeRotation
(
angle
);
/// Creates a widget that transforms its child using a translation.
///
...
...
@@ -1381,6 +1382,38 @@ class Transform extends SingleChildRenderObjectWidget {
assert
(
scale
==
null
||
(
scaleX
==
null
&&
scaleY
==
null
),
"If 'scale' is non-null then 'scaleX' and 'scaleY' must be left null"
),
transform
=
Matrix4
.
diagonal3Values
(
scale
??
scaleX
??
1.0
,
scale
??
scaleY
??
1.0
,
1.0
);
// Computes a rotation matrix for an angle in radians, attempting to keep rotations
// at integral values for angles of 0, π/2, π, 3π/2.
static
Matrix4
_computeRotation
(
double
radians
)
{
assert
(
radians
.
isFinite
,
'Cannot compute the rotation matrix for a non-finite angle:
$radians
'
);
if
(
radians
==
0.0
)
{
return
Matrix4
.
identity
();
}
final
double
sin
=
math
.
sin
(
radians
);
if
(
sin
==
1.0
)
{
return
_createZRotation
(
1.0
,
0.0
);
}
if
(
sin
==
-
1.0
)
{
return
_createZRotation
(-
1.0
,
0.0
);
}
final
double
cos
=
math
.
cos
(
radians
);
if
(
cos
==
-
1.0
)
{
return
_createZRotation
(
0.0
,
-
1.0
);
}
return
_createZRotation
(
sin
,
cos
);
}
static
Matrix4
_createZRotation
(
double
sin
,
double
cos
)
{
final
Matrix4
result
=
Matrix4
.
zero
();
result
.
storage
[
0
]
=
cos
;
result
.
storage
[
1
]
=
sin
;
result
.
storage
[
4
]
=
-
sin
;
result
.
storage
[
5
]
=
cos
;
result
.
storage
[
10
]
=
1.0
;
result
.
storage
[
15
]
=
1.0
;
return
result
;
}
/// The matrix to transform the child by during painting.
final
Matrix4
transform
;
...
...
packages/flutter/test/widgets/transform_test.dart
View file @
15739345
...
...
@@ -338,6 +338,153 @@ void main() {
]);
});
testWidgets
(
'Transform with nan value short-circuits rendering'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
Transform
(
transform:
Matrix4
.
identity
()
..
storage
[
0
]
=
double
.
nan
,
child:
RepaintBoundary
(
child:
Container
()),
),
);
expect
(
tester
.
layers
,
hasLength
(
1
));
});
testWidgets
(
'Transform with inf value short-circuits rendering'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
Transform
(
transform:
Matrix4
.
identity
()
..
storage
[
0
]
=
double
.
infinity
,
child:
RepaintBoundary
(
child:
Container
()),
),
);
expect
(
tester
.
layers
,
hasLength
(
1
));
});
testWidgets
(
'Transform with -inf value short-circuits rendering'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
Transform
(
transform:
Matrix4
.
identity
()
..
storage
[
0
]
=
double
.
negativeInfinity
,
child:
RepaintBoundary
(
child:
Container
()),
),
);
expect
(
tester
.
layers
,
hasLength
(
1
));
});
testWidgets
(
'Transform.rotate does not remove layers due to singular short-circuit'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
Transform
.
rotate
(
angle:
math
.
pi
/
2
,
child:
RepaintBoundary
(
child:
Container
()),
),
);
expect
(
tester
.
layers
,
hasLength
(
3
));
});
testWidgets
(
'Transform.rotate creates nice rotation matrices for 0, 90, 180, 270 degrees'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
Transform
.
rotate
(
angle:
math
.
pi
/
2
,
child:
RepaintBoundary
(
child:
Container
()),
),
);
expect
(
tester
.
layers
[
1
],
isA
<
TransformLayer
>()
.
having
((
TransformLayer
layer
)
=>
layer
.
transform
,
'transform'
,
equals
(
Matrix4
.
fromList
(<
double
>[
0.0
,
-
1.0
,
0.0
,
700.0
,
1.0
,
0.0
,
0.0
,
-
100.0
,
0.0
,
0.0
,
1.0
,
0.0
,
0.0
,
0.0
,
0.0
,
1.0
,
])..
transpose
()))
);
await
tester
.
pumpWidget
(
Transform
.
rotate
(
angle:
math
.
pi
,
child:
RepaintBoundary
(
child:
Container
()),
),
);
expect
(
tester
.
layers
[
1
],
isA
<
TransformLayer
>()
.
having
((
TransformLayer
layer
)
=>
layer
.
transform
,
'transform'
,
equals
(
Matrix4
.
fromList
(<
double
>[
-
1.0
,
0.0
,
0.0
,
800.0
,
0.0
,
-
1.0
,
0.0
,
600.0
,
0.0
,
0.0
,
1.0
,
0.0
,
0.0
,
0.0
,
0.0
,
1.0
,
])..
transpose
()))
);
await
tester
.
pumpWidget
(
Transform
.
rotate
(
angle:
3
*
math
.
pi
/
2
,
child:
RepaintBoundary
(
child:
Container
()),
),
);
expect
(
tester
.
layers
[
1
],
isA
<
TransformLayer
>()
.
having
((
TransformLayer
layer
)
=>
layer
.
transform
,
'transform'
,
equals
(
Matrix4
.
fromList
(<
double
>[
0.0
,
1.0
,
0.0
,
100.0
,
-
1.0
,
0.0
,
0.0
,
700.0
,
0.0
,
0.0
,
1.0
,
0.0
,
0.0
,
0.0
,
0.0
,
1.0
,
])..
transpose
()))
);
await
tester
.
pumpWidget
(
Transform
.
rotate
(
angle:
0
,
child:
RepaintBoundary
(
child:
Container
()),
),
);
// No transform layer created
expect
(
tester
.
layers
[
1
],
isA
<
OffsetLayer
>());
expect
(
tester
.
layers
,
hasLength
(
2
));
});
testWidgets
(
'Transform.scale with 0.0 does not paint child layers'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
Transform
.
scale
(
scale:
0.0
,
child:
RepaintBoundary
(
child:
Container
()),
),
);
expect
(
tester
.
layers
,
hasLength
(
1
));
// root transform layer
await
tester
.
pumpWidget
(
Transform
.
scale
(
scaleX:
0.0
,
child:
RepaintBoundary
(
child:
Container
()),
),
);
expect
(
tester
.
layers
,
hasLength
(
1
));
await
tester
.
pumpWidget
(
Transform
.
scale
(
scaleY:
0.0
,
child:
RepaintBoundary
(
child:
Container
()),
),
);
expect
(
tester
.
layers
,
hasLength
(
1
));
await
tester
.
pumpWidget
(
Transform
.
scale
(
scale:
0.01
,
// small but non-zero
child:
RepaintBoundary
(
child:
Container
()),
),
);
expect
(
tester
.
layers
,
hasLength
(
3
));
});
testWidgets
(
'Translated child into translated box - hit test'
,
(
WidgetTester
tester
)
async
{
final
GlobalKey
key1
=
GlobalKey
();
bool
pointerDown
=
false
;
...
...
packages/flutter/test/widgets/transitions_test.dart
View file @
15739345
...
...
@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:math'
as
math
;
import
'package:flutter/material.dart'
;
import
'package:flutter/rendering.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
...
...
@@ -318,13 +316,23 @@ void main() {
await
tester
.
pump
();
actualRotatedBox
=
tester
.
widget
(
find
.
byType
(
Transform
));
actualTurns
=
actualRotatedBox
.
transform
;
expect
(
actualTurns
,
Matrix4
.
rotationZ
(
math
.
pi
));
expect
(
actualTurns
,
Matrix4
.
fromList
(<
double
>[
-
1.0
,
0.0
,
0.0
,
0.0
,
0.0
,
-
1.0
,
0.0
,
0.0
,
0.0
,
0.0
,
1.0
,
0.0
,
0.0
,
0.0
,
0.0
,
1.0
,
])..
transpose
());
controller
.
value
=
0.75
;
await
tester
.
pump
();
actualRotatedBox
=
tester
.
widget
(
find
.
byType
(
Transform
));
actualTurns
=
actualRotatedBox
.
transform
;
expect
(
actualTurns
,
Matrix4
.
rotationZ
(
math
.
pi
*
1.5
));
expect
(
actualTurns
,
Matrix4
.
fromList
(<
double
>[
0.0
,
1.0
,
0.0
,
0.0
,
-
1.0
,
0.0
,
0.0
,
0.0
,
0.0
,
0.0
,
1.0
,
0.0
,
0.0
,
0.0
,
0.0
,
1.0
,
])..
transpose
());
});
testWidgets
(
'RotationTransition maintains chosen alignment during animation'
,
(
WidgetTester
tester
)
async
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment