ShaderMask LinearGradient停止了奇怪的行为 [英] ShaderMask LinearGradient's stops strange behavior

查看:163
本文介绍了ShaderMask LinearGradient停止了奇怪的行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使内容的两面(边缘)褪色.

I want to fade both side (edges) of a content.

我将 ShaderMask LinearGradient 一起使用,除了我不理解为什么我的 stops 不能正确居中之外,它的工作原理非常好,我使用了 stops:[0.0,0.05,0.95,1.0] ,因此应该在每侧将其逐渐淡化 0.05 ,但是我得到了以下信息(我添加了容器渐变以进行比较):

I use a ShaderMask along with a LinearGradient, it works great except that I don't understand why my stops are not centered correctly, I use stops: [0.0, 0.05, 0.95, 1.0] so that it should be faded 0.05 on each side, but I get the following (I added a Container gradient with same configuration for comparison):

使用调试绘制模式:

对于 Container ShaderMask ,我使用完全相同的停止点,但是得到的结果却不同.

I use exactly the same stops for the Container and for the ShaderMask but get different results.

当然,我可以为 ShaderMask 渐变尝试不同的 stops 值,直到将其居中放置,但这似乎很容易.

Of course I can try different stops values for the ShaderMask gradient until I got it centered but it seems like a hack.

有人可以解释吗?

如果有人想尝试一下,这里是代码:

Here's the code if anyone want to give it a try :

return Container(
  height: 200,
  child: Column(
    children: <Widget>[
      Expanded(
        child: ShaderMask(
          blendMode: BlendMode.modulate,
          shaderCallback: (Rect bounds) {
            return LinearGradient(
              begin: Alignment.centerLeft,
              end: Alignment.centerRight,
              colors: <Color>[Colors.transparent, Colors.white, Colors.white, Colors.transparent],
              stops: [0.0, 0.05, 0.95, 1.0],
              tileMode: TileMode.clamp,
            ).createShader(bounds);
          },
          child: Container(
            color: Colors.blue,
            child: ListView(
              children: <Widget>[
                Text(
                  "I'm a ShaderMask and I don't understand why my gradient don't behave like container's gradient. I'm a ShaderMask and I don't understand why my gradient don't behave like container's gradient.",
                  textAlign: TextAlign.justify,
                )
              ],
            ),
          ),
        ),
      ),
      Expanded(
        child: Container(
          decoration: BoxDecoration(
            gradient: LinearGradient(
              begin: Alignment.centerLeft,
              end: Alignment.centerRight,
              colors: [Colors.transparent, Colors.blue, Colors.blue, Colors.transparent],
              stops: [0.0, 0.05, 0.95, 1.0],
              tileMode: TileMode.clamp,
            ),
          ),
          child: ListView(
            children: <Widget>[
              Text(
                "I'm a Container and I don't understand why ShaderMask's gradient don't behave like mine. I'm a Container and I don't understand why ShaderMask's gradient don't behave like mine.",
                textAlign: TextAlign.justify,
              )
            ],
          ),
        ),
      )
    ],
  ),
);

使用 FractionalOffset 而不是 Alignment.centerRight Alignment.centerRight ,我得到了相同的结果.

I got the same result using FractionalOffset instead of Alignment.centerRight and Alignment.centerRight.

推荐答案

shaderCallback 为给定的 Rect 创建一个 Shader ,而 Rect 坐标相对于给定的原点.

shaderCallback creates a Shader for a given Rect, and the Rect coordinates are relative to a given origin.

使用子级的当前大小调用着色器回调,以便可以根据子级的大小和位置自定义着色器.

The shader callback is called with the current size of the child so that it can customize the shader to the size and location of the child.

这意味着我们必须基于子窗口小部件的大小(不带偏移)创建具有 Rect 的着色器(基本上,传递给 shaderCallback 的边界在全局坐标中而 createShader 正在等待本地 Rect ).

It means we have to create the shader with a Rect based on the size of the child widget with no offset (basically the bounds passed to shaderCallback are in global coordinates while createShader is waiting for a local Rect).

因此一个简单的解决方案是使用正确的原点(偏移)和边界创建一个新的 Rect : createShader(Rect.fromLTRB(0,0,bounds.width,bounds.height)).

So a simple solution is to create a new Rect with the right origin (offset) and bounds : createShader(Rect.fromLTRB(0, 0, bounds.width, bounds.height)).

或更性感的速记: createShader(Offset.zero& bounds.size):

shaderCallback: (Rect bounds) {
  return LinearGradient(
    begin: Alignment.centerLeft,
    end: Alignment.centerRight,
    colors: <Color>[Colors.transparent, Colors.blue, Colors.blue, Colors.transparent],
    stops: [0.0, 0.04, 0.96, 1.0],
    tileMode: TileMode.clamp,
  ).createShader(Offset.zero & bounds.size);
},

pskink的积分!

Credits to pskink !

这篇关于ShaderMask LinearGradient停止了奇怪的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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