如何在颤动中使用混合混合模式? [英] How to use mix blend mode in flutter?

查看:89
本文介绍了如何在颤动中使用混合混合模式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试了似乎仅适用于颜色的混合模式,即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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆