flutter - ShaderMask LinearGradient 停止奇怪的行为
问题描述
我想淡化内容的两侧(边缘)。
我使用 aShaderMask
和 a LinearGradient
,它工作得很好,除了我不明白为什么我stops
没有正确居中,我使用stops: [0.0, 0.05, 0.95, 1.0]
它应该0.05
在每一侧褪色,但我得到以下(我添加了一个Container
具有相同配置的渐变比较):
使用调试绘画模式:
Container
我对和使用完全相同的停靠点,ShaderMask
但得到不同的结果。
当然,我可以尝试不同stops
的渐变值,ShaderMask
直到它居中,但这似乎是一个 hack。
有人可以解释一下吗?
如果有人想尝试一下,这是代码:
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
and得到了相同的结果Alignment.centerRight
。
解决方案
shaderCallback
Shader
为给定的创建一个Rect
,并且Rect
坐标相对于给定的原点。
着色器回调以子项的当前大小调用,以便它可以将着色器自定义为子项的大小和位置。
这意味着我们必须根据没有偏移的子部件的大小来创建着色器Rect
(基本上传递给的边界shaderCallback
在全局坐标中,同时createShader
等待一个局部的Rect
)。
所以一个简单的解决方案是创建一个Rect
具有正确原点(偏移量)和边界的新的: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 !
推荐阅读
- vue.js - 如何使用 Nuxt-Auth 设置会话?
- excel - 将工作表拆分为工作簿
- wordpress - 如何将带有 git sync 的 sidecar 容器添加到 wordpress helm 部署?
- mysql - 为什么会死锁(使用innodb)?
- visual-studio-code - vscode:设置窗口大小的最快方法
- reactjs - ReactNative TCP 套接字
- python - os.environ 没有显示一些环境变量
- python - 当我尝试通过 paramiko 模块 python 的 exec 命令运行 npm install 时出现错误
- vue.js - 如何计算 Vue.js 中嵌套数组中的值?
- docker - docker-compose:注册层失败:处理 tar 文件时出错 - 找不到 Windows DLL MUI 文件