如何在颤动中使用混合混合模式? [英] How to use mix blend mode in flutter?
问题描述
我尝试了似乎仅适用于颜色的混合模式,即colorblendmode.有什么方法可以实现CSS的
首先,将创建一个BlendMask SingleChildRenderObject,该对象将创建一个称为RenderBlendMask的RenderProxyBox渲染对象.该子项具有BlendMode和不透明度绘制.
import'package:flutter/rendering.dart';导入'package:flutter/widgets.dart';类BlendMask扩展了SingleChildRenderObjectWidget {最终的BlendMode blendMode;最终的双重不透明性;BlendMask({@需要this.blendMode,this.opacity = 1.0,关键小部件子代,}):super(key:key,child:child);@overrideRenderObject createRenderObject(context){返回RenderBlendMask(blendMode,opacity);}@overridevoid updateRenderObject(BuildContext context,RenderBlendMask renderObject){renderObject.blendMode = blendMode;renderObject.opacity =不透明度;}}类RenderBlendMask扩展了RenderProxyBox {BlendMode blendMode;双重不透明RenderBlendMask(this.blendMode,this.opacity);@override无效绘画(上下文,偏移量){context.canvas.saveLayer(偏移量尺寸,画()..blendMode = blendMode..color = Color.fromARGB((opacity * 255).round(),255,255,255));super.paint(上下文,偏移量);context.canvas.restore();}}
现在要混合两个窗口小部件(不限于图像),只需使用堆栈将要混合的窗口小部件添加到另一个窗口之上,然后将其包装在BlendMode中即可.
class ImageMixer扩展了StatelessWidget {@override窗口小部件build(BuildContext context){返回脚手架(正文:SizedBox.expand(子代:Stack(孩子们: [SizedBox.expand(子:Image.asset('images/sky.jpg',),),BlendMask(不透明度:1.0,blendMode:BlendMode.softLight,子级:SizedBox.expand(子:Image.asset('images/monkey.jpg',),),),],)),);}}
这将产生上面的图像,并且其工作原理与CSS示例完全相同.
I have tried the blend mode that seems to be working for only color i.e colorblendmode. Is there any way to achieve the mix-blend-mode as of CSS?
Stack(
children: <Widget>[
Image.asset(
"asset/text.PNG",
height: double.maxFinite,
width: double.maxFinite,
fit: BoxFit.fitHeight,
color: Colors.red,
colorBlendMode: BlendMode.multiply,
),
Image.asset("asset/face.jpg",
width: double.maxFinite,
fit: BoxFit.fitHeight,
color: Colors.red,
colorBlendMode: BlendMode.multiply),
],
),
This results in something like: The output of code above
What i want to get Output from CSS
Using RenderProxyBox and some painting, I was able to recreate the exact sample on the CSS website without asynchronously loading the image in your Flutter code.
Image using CSS (left) vs image using Flutter(right).
To start, a BlendMask SingleChildRenderObject is created that creates a RenderProxyBox render object called RenderBlendMask is created. The child is painted with a BlendMode and an opacity.
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();
}
}
Now to blend two widgets (Not restricted to images), just add the widget you want to blend above another using a stack, and wrap it in your 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',
),
),
),
],
)),
);
}
}
That produces the image above, and it works exactly like the CSS example.
这篇关于如何在颤动中使用混合混合模式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!