未验证 提交 5a074882 编写于 作者: F Ferhat 提交者: GitHub

[web] Add HtmlCodec progress callback (#17139)

* Wire up htmlcodec chunkcallback for progress events

* Add test for HtmlCodec
上级 fddb0c27
......@@ -4,16 +4,21 @@
// @dart = 2.6
part of engine;
final bool _supportsDecode = js_util.getProperty(
js_util.getProperty(
js_util.getProperty(html.window, 'Image'), 'prototype'),
'decode') !=
null;
typedef WebOnlyImageCodecChunkCallback = void Function(
int cumulativeBytesLoaded, int expectedTotalBytes);
class HtmlCodec implements ui.Codec {
final String src;
final WebOnlyImageCodecChunkCallback chunkCallback;
HtmlCodec(this.src);
HtmlCodec(this.src, {this.chunkCallback});
@override
int get frameCount => 1;
......@@ -24,11 +29,20 @@ class HtmlCodec implements ui.Codec {
@override
Future<ui.FrameInfo> getNextFrame() async {
final Completer<ui.FrameInfo> completer = Completer<ui.FrameInfo>();
// Currently there is no way to watch decode progress, so
// we add 0/100 , 100/100 progress callbacks to enable loading progress
// builders to create UI.
if (chunkCallback != null) {
chunkCallback(0, 100);
}
if (_supportsDecode) {
final html.ImageElement imgElement = html.ImageElement();
imgElement.src = src;
js_util.setProperty(imgElement, 'decoding', 'async');
imgElement.decode().then((dynamic _) {
if (chunkCallback != null) {
chunkCallback(100, 100);
}
final HtmlImage image = HtmlImage(
imgElement,
imgElement.naturalWidth,
......@@ -61,6 +75,9 @@ class HtmlCodec implements ui.Codec {
completer.completeError(event);
});
loadSubscription = imgElement.onLoad.listen((html.Event event) {
if (chunkCallback != null) {
chunkCallback(100, 100);
}
loadSubscription.cancel();
errorSubscription.cancel();
final HtmlImage image = HtmlImage(
......
......@@ -899,9 +899,8 @@ enum Clip {
abstract class Paint {
/// Constructs an empty [Paint] object with all fields initialized to
/// their defaults.
factory Paint() => engine.experimentalUseSkia
? engine.SkPaint()
: engine.SurfacePaint();
factory Paint() =>
engine.experimentalUseSkia ? engine.SkPaint() : engine.SurfacePaint();
/// Whether to dither the output when drawing images.
///
......@@ -1604,13 +1603,17 @@ String _instantiateImageCodec(
return null;
}
Future<Codec> webOnlyInstantiateImageCodecFromUrl(Uri uri) {
Future<Codec> webOnlyInstantiateImageCodecFromUrl(Uri uri,
{engine.WebOnlyImageCodecChunkCallback chunkCallback}) {
return engine.futurize((engine.Callback<Codec> callback) =>
_instantiateImageCodecFromUrl(uri, callback));
_instantiateImageCodecFromUrl(uri, chunkCallback, callback));
}
String _instantiateImageCodecFromUrl(Uri uri, engine.Callback<Codec> callback) {
callback(engine.HtmlCodec(uri.toString()));
String _instantiateImageCodecFromUrl(
Uri uri,
engine.WebOnlyImageCodecChunkCallback chunkCallback,
engine.Callback<Codec> callback) {
callback(engine.HtmlCodec(uri.toString(), chunkCallback: chunkCallback));
return null;
}
......
// 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 'package:test/test.dart';
import 'package:ui/ui.dart' as ui;
import 'package:ui/src/engine.dart';
Future<void> main() async {
await ui.webOnlyInitializeTestDomRenderer();
group('HtmCodec', () {
test('loads sample image', () async {
final HtmlCodec codec = HtmlCodec('sample_image1.png');
final ui.FrameInfo frameInfo = await codec.getNextFrame();
expect(frameInfo.image, isNotNull);
expect(frameInfo.image.width, 100);
});
test('provides image loading progress', () async {
StringBuffer buffer = new StringBuffer();
final HtmlCodec codec = HtmlCodec('sample_image1.png',
chunkCallback: (int loaded, int total) {
buffer.write('$loaded/$total,');
});
final ui.FrameInfo frameInfo = await codec.getNextFrame();
expect(buffer.toString(), '0/100,100/100,');
});
});
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册