Flutter使用ColorFiltered组件做介绍功能

2021-09-08  本文已影响0人  DerekTime

1.混合模式的详解
https://blog.csdn.net/chenlove1/article/details/84574237

2.基础代码
大概思路:
1.可以使用OverlayEntry覆盖到最外层,我直接用showDialog了。
2.使用ColorFiltered做一个蒙版,child:Stack()。
3.BlendMode.srcOut, // 显示源图像,但仅显示两个图像不重叠的位置。目标图像不会渲染,仅将其视为蒙版。目标的颜色通道被忽略,只有不透明度有效。
4.在上面的Stack上添加透明的Container()就显示colorFilter的颜色。
5.使用globalKey获取你想空出的位置。
6.在在上面的Stack上获取到的位置,添加不透明的Container(),就会显示目标图像,但不会显示目标图像的颜色,所以就空出来了。

借鉴了部分flutter_intro的部分代码,各自的需求再自己实现了,或者直接使用flutter_intro(https://pub.flutter-io.cn/packages/flutter_intro

@override
  Widget build(BuildContext context) {
    return Material(
      color: Colors.transparent,
      child: Stack(
        children: [
          ColorFiltered(
            colorFilter: ColorFilter.mode(
              Colors.black54,
              BlendMode.srcOut, // 显示源图像,但仅显示两个图像不重叠的位置。目标图像不会渲染,仅将其视为蒙版。目标的颜色通道被忽略,只有不透明度有效。
            ),
            child: Stack(
              children: [
                //用透明色把上面的蒙版颜色显示出来
                Container(
                  width: ScreenUtil.screenWidth / 2,
                  height: ScreenUtil.screenHeight / 2,
                  color: Colors.transparent,
                ),
                // 下面添加需要空出来的位置,默认颜色是白色,所以该位置不会渲染源图像
                Visibility(
                  visible: step == 0,
                  child: _maskBuilder(
                    width: 100,
                    height: 100,
                    left: 100,
                    top: 100,
                    child: GestureDetector(
                      onTap: (){
                        setState(() {
                          step = 1;
                        });
                      },
                    )
                  ),
                ),
                Visibility(
                  visible: step == 1,
                  child: _maskBuilder(
                    width: 100,
                    height: 100,
                    left: 300,
                    top: 300,
                      child: GestureDetector(
                        onTap: (){
                          setState(() {
                            step = 2;
                          });
                        },
                      )
                  ),
                ),
                Visibility(
                  visible: step == 2,
                  child: _maskBuilder(
                      width: 100,
                      height: 100,
                      left: 300,
                      top: 300,
                      child: GestureDetector(
                        onTap: (){
                          Navigator.pop(context, 'finish');
                        },
                      )
                  ),
                ),
              ],
            ),
          ),
          Positioned(
            left: 450,
            top: 250,
            child: Container(
              child: Text('10000000000', style: TextStyle(
                fontSize: 30,
                color: Colors.white
              ),),
            ),
          ),
        ],
      ),
    );
  }
Widget _maskBuilder({
    double width,
    double height,
    @required double top,
    @required double left,
    double bottom,
    double right,
    BlendMode backgroundBlendMode,
    BorderRadiusGeometry borderRadiusGeometry,
    Widget child,
  }) {
    final decoration = BoxDecoration(
      color: Colors.white,
      backgroundBlendMode: backgroundBlendMode,
      borderRadius: borderRadiusGeometry,
    );
    return AnimatedPositioned(
      duration: Duration(milliseconds: 300),
      child: AnimatedContainer(
        decoration: decoration,
        width: width,
        height: height,
        child: child,
        duration: Duration(milliseconds: 300),
      ),
      top: top,
      left: left,
      bottom: bottom,
      right: right,
    );
  }
上一篇下一篇

猜你喜欢

热点阅读