使用 RenderProxyBox 和一些绘画,我能够在 CSS 网站上重新创建确切的示例,而无需在 Flutter 代码中异步加载图像。
使用 CSS 的图像(左)与使用 Flutter 的图像(右)。
阅读我在这里写的关于这个的文章
首先,创建一个 BlendMask SingleChildRenderObject,它创建一个名为 RenderBlendMask 的 RenderProxyBox 渲染对象。使用 BlendMode 和不透明度绘制孩子。
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
class BlendMask extends SingleChildRenderObjectWidget {
final BlendMode blendMode;
final double opacity;
BlendMask({
@required this.blendMode,
this.opacity = 1.0,
Key key,
Widget child,
}) : super(key: key, child: child);
@override
RenderObject createRenderObject(context) {
return RenderBlendMask(blendMode, opacity);
}
@override
void updateRenderObject(BuildContext context, RenderBlendMask renderObject) {
renderObject.blendMode = blendMode;
renderObject.opacity = opacity;
}
}
class RenderBlendMask extends RenderProxyBox {
BlendMode blendMode;
double opacity;
RenderBlendMask(this.blendMode, this.opacity);
@override
void paint(context, offset) {
context.canvas.saveLayer(
offset & size,
Paint()
..blendMode = blendMode
..color = Color.fromARGB((opacity * 255).round(), 255, 255, 255));
super.paint(context, offset);
context.canvas.restore();
}
}
现在要混合两个小部件(不限于图像),只需使用堆栈将要混合的小部件添加到另一个之上,然后将其包装在 BlendMode 中。
class ImageMixer extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: SizedBox.expand(
child: Stack(
children: [
SizedBox.expand(
child: Image.asset(
'images/sky.jpg',
),
),
BlendMask(
opacity: 1.0,
blendMode: BlendMode.softLight,
child: SizedBox.expand(
child: Image.asset(
'images/monkey.jpg',
),
),
),
],
)),
);
}
}
这产生了上面的图像,它的工作方式与 CSS 示例完全相同。