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
67384627
Unverified
Commit
67384627
authored
Apr 27, 2021
by
Jim Graham
Committed by
GitHub
Apr 27, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add BackdropFilter blend mode (#80129)
parent
31559727
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
135 additions
and
4 deletions
+135
-4
layer.dart
packages/flutter/lib/src/rendering/layer.dart
+25
-1
proxy_box.dart
packages/flutter/lib/src/rendering/proxy_box.dart
+20
-1
basic.dart
packages/flutter/lib/src/widgets/basic.dart
+31
-2
backdrop_filter_test.dart
packages/flutter/test/widgets/backdrop_filter_test.dart
+59
-0
No files found.
packages/flutter/lib/src/rendering/layer.dart
View file @
67384627
...
@@ -1803,7 +1803,13 @@ class BackdropFilterLayer extends ContainerLayer {
...
@@ -1803,7 +1803,13 @@ class BackdropFilterLayer extends ContainerLayer {
///
///
/// The [filter] property must be non-null before the compositing phase of the
/// The [filter] property must be non-null before the compositing phase of the
/// pipeline.
/// pipeline.
BackdropFilterLayer
({
ui
.
ImageFilter
?
filter
})
:
_filter
=
filter
;
///
/// The [blendMode] property defaults to [BlendMode.srcOver].
BackdropFilterLayer
({
ui
.
ImageFilter
?
filter
,
BlendMode
blendMode
=
BlendMode
.
srcOver
,
})
:
_filter
=
filter
,
_blendMode
=
blendMode
;
/// The filter to apply to the existing contents of the scene.
/// The filter to apply to the existing contents of the scene.
///
///
...
@@ -1818,11 +1824,29 @@ class BackdropFilterLayer extends ContainerLayer {
...
@@ -1818,11 +1824,29 @@ class BackdropFilterLayer extends ContainerLayer {
}
}
}
}
/// The blend mode to use to apply the filtered background content onto the background
/// surface.
///
/// The default value of this property is [BlendMode.srcOver].
/// {@macro flutter.widgets.BackdropFilter.blendMode}
///
/// The scene must be explicitly recomposited after this property is changed
/// (as described at [Layer]).
BlendMode
get
blendMode
=>
_blendMode
;
BlendMode
_blendMode
;
set
blendMode
(
BlendMode
value
)
{
if
(
value
!=
_blendMode
)
{
_blendMode
=
value
;
markNeedsAddToScene
();
}
}
@override
@override
void
addToScene
(
ui
.
SceneBuilder
builder
,
[
Offset
layerOffset
=
Offset
.
zero
])
{
void
addToScene
(
ui
.
SceneBuilder
builder
,
[
Offset
layerOffset
=
Offset
.
zero
])
{
assert
(
filter
!=
null
);
assert
(
filter
!=
null
);
engineLayer
=
builder
.
pushBackdropFilter
(
engineLayer
=
builder
.
pushBackdropFilter
(
filter
!,
filter
!,
blendMode:
blendMode
,
oldLayer:
_engineLayer
as
ui
.
BackdropFilterEngineLayer
?,
oldLayer:
_engineLayer
as
ui
.
BackdropFilterEngineLayer
?,
);
);
addChildrenToScene
(
builder
,
layerOffset
);
addChildrenToScene
(
builder
,
layerOffset
);
...
...
packages/flutter/lib/src/rendering/proxy_box.dart
View file @
67384627
...
@@ -1141,9 +1141,13 @@ class RenderBackdropFilter extends RenderProxyBox {
...
@@ -1141,9 +1141,13 @@ class RenderBackdropFilter extends RenderProxyBox {
/// Creates a backdrop filter.
/// Creates a backdrop filter.
///
///
/// The [filter] argument must not be null.
/// The [filter] argument must not be null.
RenderBackdropFilter
({
RenderBox
?
child
,
required
ui
.
ImageFilter
filter
})
/// The [blendMode] argument, if provided, must not be null
/// and will default to [BlendMode.srcOver].
RenderBackdropFilter
({
RenderBox
?
child
,
required
ui
.
ImageFilter
filter
,
BlendMode
blendMode
=
BlendMode
.
srcOver
})
:
assert
(
filter
!=
null
),
:
assert
(
filter
!=
null
),
assert
(
blendMode
!=
null
),
_filter
=
filter
,
_filter
=
filter
,
_blendMode
=
blendMode
,
super
(
child
);
super
(
child
);
@override
@override
...
@@ -1164,6 +1168,20 @@ class RenderBackdropFilter extends RenderProxyBox {
...
@@ -1164,6 +1168,20 @@ class RenderBackdropFilter extends RenderProxyBox {
markNeedsPaint
();
markNeedsPaint
();
}
}
/// The blend mode to use to apply the filtered background content onto the background
/// surface.
///
/// {@macro flutter.widgets.BackdropFilter.blendMode}
BlendMode
get
blendMode
=>
_blendMode
;
BlendMode
_blendMode
;
set
blendMode
(
BlendMode
value
)
{
assert
(
value
!=
null
);
if
(
_blendMode
==
value
)
return
;
_blendMode
=
value
;
markNeedsPaint
();
}
@override
@override
bool
get
alwaysNeedsCompositing
=>
child
!=
null
;
bool
get
alwaysNeedsCompositing
=>
child
!=
null
;
...
@@ -1173,6 +1191,7 @@ class RenderBackdropFilter extends RenderProxyBox {
...
@@ -1173,6 +1191,7 @@ class RenderBackdropFilter extends RenderProxyBox {
assert
(
needsCompositing
);
assert
(
needsCompositing
);
layer
??=
BackdropFilterLayer
();
layer
??=
BackdropFilterLayer
();
layer
!.
filter
=
_filter
;
layer
!.
filter
=
_filter
;
layer
!.
blendMode
=
_blendMode
;
context
.
pushLayer
(
layer
!,
super
.
paint
,
offset
);
context
.
pushLayer
(
layer
!,
super
.
paint
,
offset
);
}
else
{
}
else
{
layer
=
null
;
layer
=
null
;
...
...
packages/flutter/lib/src/widgets/basic.dart
View file @
67384627
...
@@ -166,6 +166,12 @@ class Directionality extends InheritedWidget {
...
@@ -166,6 +166,12 @@ class Directionality extends InheritedWidget {
/// buffer. For the value 0.0, the child is simply not painted at all. For the
/// buffer. For the value 0.0, the child is simply not painted at all. For the
/// value 1.0, the child is painted immediately without an intermediate buffer.
/// value 1.0, the child is painted immediately without an intermediate buffer.
///
///
/// The presence of the intermediate buffer which has a transparent background
/// by default may cause some child widgets to behave differently. For example
/// a [BackdropFilter] child will only be able to apply its filter to the content
/// between this widget and the backdrop child and may require adjusting the
/// [BackdropFilter.blendMode] property to produce the desired results.
///
/// {@youtube 560 315 https://www.youtube.com/watch?v=9hltevOHQBw}
/// {@youtube 560 315 https://www.youtube.com/watch?v=9hltevOHQBw}
///
///
/// {@tool snippet}
/// {@tool snippet}
...
@@ -377,6 +383,18 @@ class ShaderMask extends SingleChildRenderObjectWidget {
...
@@ -377,6 +383,18 @@ class ShaderMask extends SingleChildRenderObjectWidget {
/// widget's clip. If there's no clip, the filter will be applied to the full
/// widget's clip. If there's no clip, the filter will be applied to the full
/// screen.
/// screen.
///
///
/// The results of the filter will be blended back into the background using
/// the [blendMode] parameter.
/// {@template flutter.widgets.BackdropFilter.blendMode}
/// The only value for [blendMode] that is supported on all platforms is
/// [BlendMode.srcOver] which works well for most scenes. But that value may
/// produce surprising results when a parent of the [BackdropFilter] uses a
/// temporary buffer, or save layer, as does an [Opacity] widget. In that
/// situation, a value of [BlendMode.src] can produce more pleasing results,
/// but at the cost of incompatibility with some platforms, most notably the
/// html renderer for web applications.
/// {@endtemplate}
///
/// {@youtube 560 315 https://www.youtube.com/watch?v=dYRs7Q1vfYI}
/// {@youtube 560 315 https://www.youtube.com/watch?v=dYRs7Q1vfYI}
///
///
/// {@tool snippet}
/// {@tool snippet}
...
@@ -427,10 +445,13 @@ class BackdropFilter extends SingleChildRenderObjectWidget {
...
@@ -427,10 +445,13 @@ class BackdropFilter extends SingleChildRenderObjectWidget {
/// Creates a backdrop filter.
/// Creates a backdrop filter.
///
///
/// The [filter] argument must not be null.
/// The [filter] argument must not be null.
/// The [blendMode] argument will default to [BlendMode.srcOver] and must not be
/// null if provided.
const
BackdropFilter
({
const
BackdropFilter
({
Key
?
key
,
Key
?
key
,
required
this
.
filter
,
required
this
.
filter
,
Widget
?
child
,
Widget
?
child
,
this
.
blendMode
=
BlendMode
.
srcOver
,
})
:
assert
(
filter
!=
null
),
})
:
assert
(
filter
!=
null
),
super
(
key:
key
,
child:
child
);
super
(
key:
key
,
child:
child
);
...
@@ -440,14 +461,22 @@ class BackdropFilter extends SingleChildRenderObjectWidget {
...
@@ -440,14 +461,22 @@ class BackdropFilter extends SingleChildRenderObjectWidget {
/// blur effect.
/// blur effect.
final
ui
.
ImageFilter
filter
;
final
ui
.
ImageFilter
filter
;
/// The blend mode to use to apply the filtered background content onto the background
/// surface.
///
/// {@macro flutter.widgets.BackdropFilter.blendMode}
final
BlendMode
blendMode
;
@override
@override
RenderBackdropFilter
createRenderObject
(
BuildContext
context
)
{
RenderBackdropFilter
createRenderObject
(
BuildContext
context
)
{
return
RenderBackdropFilter
(
filter:
filter
);
return
RenderBackdropFilter
(
filter:
filter
,
blendMode:
blendMode
);
}
}
@override
@override
void
updateRenderObject
(
BuildContext
context
,
RenderBackdropFilter
renderObject
)
{
void
updateRenderObject
(
BuildContext
context
,
RenderBackdropFilter
renderObject
)
{
renderObject
.
filter
=
filter
;
renderObject
..
filter
=
filter
..
blendMode
=
blendMode
;
}
}
}
}
...
...
packages/flutter/test/widgets/backdrop_filter_test.dart
View file @
67384627
...
@@ -45,4 +45,63 @@ void main() {
...
@@ -45,4 +45,63 @@ void main() {
matchesGoldenFile
(
'backdrop_filter_test.cull_rect.png'
),
matchesGoldenFile
(
'backdrop_filter_test.cull_rect.png'
),
);
);
});
});
testWidgets
(
'BackdropFilter blendMode on saveLayer'
,
(
WidgetTester
tester
)
async
{
tester
.
binding
.
addTime
(
const
Duration
(
seconds:
15
));
await
tester
.
pumpWidget
(
MaterialApp
(
home:
Scaffold
(
body:
Opacity
(
opacity:
0.9
,
child:
Stack
(
fit:
StackFit
.
expand
,
children:
<
Widget
>[
Text
(
'0 0 '
*
10000
),
Column
(
mainAxisAlignment:
MainAxisAlignment
.
spaceEvenly
,
// ClipRect needed for filtering the 200x200 area instead of the
// whole screen.
children:
<
Widget
>[
ClipRect
(
child:
BackdropFilter
(
filter:
ImageFilter
.
blur
(
sigmaX:
5.0
,
sigmaY:
5.0
,
),
child:
Container
(
alignment:
Alignment
.
center
,
width:
200.0
,
height:
200.0
,
color:
Colors
.
yellow
.
withAlpha
(
0x7
),
),
),
),
ClipRect
(
child:
BackdropFilter
(
filter:
ImageFilter
.
blur
(
sigmaX:
5.0
,
sigmaY:
5.0
,
),
blendMode:
BlendMode
.
src
,
child:
Container
(
alignment:
Alignment
.
center
,
width:
200.0
,
height:
200.0
,
color:
Colors
.
yellow
.
withAlpha
(
0x7
),
),
),
),
],
),
],
),
),
),
),
);
await
expectLater
(
find
.
byType
(
RepaintBoundary
).
first
,
matchesGoldenFile
(
'backdrop_filter_test.saveLayer.blendMode.png'
),
);
});
}
}
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