blob: 5b0cc417e13972e08600163508f77fef6f816c44 [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.6
import 'dart:html' as html;
import 'package:ui/ui.dart';
import 'package:ui/src/engine.dart';
import 'package:test/test.dart';
import 'package:web_engine_tester/golden_tester.dart';
final Rect region = Rect.fromLTWH(0, 0, 500, 500);
void main() async {
setUp(() async {
debugShowClipLayers = true;
SurfaceSceneBuilder.debugForgetFrameScene();
for (html.Node scene in html.document.querySelectorAll('flt-scene')) {
scene.remove();
}
await webOnlyInitializePlatform();
webOnlyFontCollection.debugRegisterTestFonts();
await webOnlyFontCollection.ensureFontsLoaded();
});
// The black circle on the left should not be blurred since it is outside
// the clip boundary around backdrop filter. However there should be only
// one red dot since the other one should be blurred by filter.
test('Background should only blur at ancestor clip boundary', () async {
final SurfaceSceneBuilder builder = SurfaceSceneBuilder();
final Picture backgroundPicture = _drawBackground();
builder.addPicture(Offset.zero, backgroundPicture);
builder.pushClipRect(
const Rect.fromLTRB(10, 10, 300, 300),
);
final Picture circles1 = _drawTestPictureWithCircles(30, 30);
builder.addPicture(Offset.zero, circles1);
builder.pushClipRect(
const Rect.fromLTRB(60, 10, 300, 300),
);
builder.pushBackdropFilter(ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0),
oldLayer: null);
final Picture circles2 = _drawTestPictureWithCircles(90, 30);
builder.addPicture(Offset.zero, circles2);
builder.pop();
builder.pop();
builder.pop();
html.document.body.append(builder
.build()
.webOnlyRootElement);
await matchGoldenFile('backdrop_filter_clip.png', region: region);
});
test('Background should only blur at ancestor clip boundary after move', () async {
final SurfaceSceneBuilder builder = SurfaceSceneBuilder();
final Picture backgroundPicture = _drawBackground();
builder.addPicture(Offset.zero, backgroundPicture);
ClipRectEngineLayer clipEngineLayer = builder.pushClipRect(
const Rect.fromLTRB(10, 10, 300, 300),
);
final Picture circles1 = _drawTestPictureWithCircles(30, 30);
builder.addPicture(Offset.zero, circles1);
ClipRectEngineLayer clipEngineLayer2 = builder.pushClipRect(
const Rect.fromLTRB(60, 10, 300, 300),
);
BackdropFilterEngineLayer oldBackdropFilterLayer =
builder.pushBackdropFilter(ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0),
oldLayer: null);
final Picture circles2 = _drawTestPictureWithCircles(90, 30);
builder.addPicture(Offset.zero, circles2);
builder.pop();
builder.pop();
builder.pop();
builder.build();
// Now reparent filter layer in next scene.
final SurfaceSceneBuilder builder2 = SurfaceSceneBuilder();
builder2.addPicture(Offset.zero, backgroundPicture);
builder2.pushClipRect(
const Rect.fromLTRB(10, 10, 300, 300),
oldLayer: clipEngineLayer
);
builder2.addPicture(Offset.zero, circles1);
builder2.pushClipRect(
const Rect.fromLTRB(10, 75, 300, 300),
oldLayer: clipEngineLayer2
);
builder2.pushBackdropFilter(ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0),
oldLayer: oldBackdropFilterLayer);
builder2.addPicture(Offset.zero, circles2);
builder2.pop();
builder2.pop();
builder2.pop();
html.document.body.append(builder2
.build()
.webOnlyRootElement);
await matchGoldenFile('backdrop_filter_clip_moved.png', region: region);
});
}
Picture _drawTestPictureWithCircles(double offsetX, double offsetY) {
final EnginePictureRecorder recorder = PictureRecorder();
final RecordingCanvas canvas =
recorder.beginRecording(const Rect.fromLTRB(0, 0, 400, 400));
canvas.drawCircle(
Offset(offsetX + 10, offsetY + 10), 10, Paint()..style = PaintingStyle.fill);
canvas.drawCircle(
Offset(offsetX + 60, offsetY + 10),
10,
Paint()
..style = PaintingStyle.fill
..color = const Color.fromRGBO(255, 0, 0, 1));
canvas.drawCircle(
Offset(offsetX + 10, offsetY + 60),
10,
Paint()
..style = PaintingStyle.fill
..color = const Color.fromRGBO(0, 255, 0, 1));
canvas.drawCircle(
Offset(offsetX + 60, offsetY + 60),
10,
Paint()
..style = PaintingStyle.fill
..color = const Color.fromRGBO(0, 0, 255, 1));
return recorder.endRecording();
}
Picture _drawBackground() {
final EnginePictureRecorder recorder = PictureRecorder();
final RecordingCanvas canvas =
recorder.beginRecording(const Rect.fromLTRB(0, 0, 400, 400));
canvas.drawRect(
Rect.fromLTWH(8, 8, 400.0 - 16, 400.0 - 16),
Paint()
..style = PaintingStyle.fill
..color = Color(0xFFE0FFE0)
);
return recorder.endRecording();
}