• 1631阅读
  • 1回复

Qml特效2-进场动画-梯度 [复制链接]

上一主题 下一主题
离线dd759378563
 

只看楼主 倒序阅读 楼主  发表于: 2019-06-09


Qml特效2-进场动画-梯度


目录
(放个目录方便预览。这个目录是从博客复制过来的,点击会跳转到博客)


简介

这是《Qml特效-进场动画》系列文章的第二篇,涛哥将会教大家一些Qml进场动画相关的知识。
进场动画效果 参考了WPS版ppt的动画,基本效果已经全部实现,可以到github TaoQuick项目中预览:
进场动画预览


关于文章

《Qml组件化编程》系列文章,已经发布了10篇,暂时没有更多内容了,后续可能会更新,看情况。
涛哥开始了新的系列文章《Qml特效》,计划是三部曲《Qml特效-进场动画》
《Qml特效-页面切换动画》《Qml特效-3D特效》,欢迎大家关注。
文章主要发布在涛哥的博客涛哥的知乎专栏-Qt进阶之路
转载声明:文章采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可, 转载请注明出处, 谢谢合作 ©涛哥


梯度效果预览

梯度效果,支持从四个方向梯度出现







实现原理

通过数值动画,控制百分比属性percent从0 到100变化
  1. //AGrad.qml
  2. import QtQuick 2.12
  3. import QtQuick.Controls 2.12
  4. ShaderEffect {
  5.     ...
  6.     //枚举声明四种方向
  7.     enum Direct {
  8.         FromLeft = 0,
  9.         FromRight = 1,
  10.         FromTop = 2,
  11.         FromBottom = 3
  12.     }
  13.     property int dir: ASlowEnter.Direct.FromLeft
  14.     property int percent: 0
  15.     opacity: percent > 0 ? 1 : 0
  16.     NumberAnimation {
  17.         id: animation
  18.         target: r
  19.         property: "percent"
  20.         from: 0
  21.         to: 100
  22.         alwaysRunToEnd: true
  23.         loops: 1
  24.         duration: 1000
  25.     }
  26.     ...
  27. }



在Shader中,使用glsl片段着色器实现像素的控制:
  1. in vec2 qt_TexCoord0;
  2. uniform float qt_Opacity;
  3. uniform sampler2D effectSource;
  4. uniform int dir;
  5. uniform int percent;
  6. out vec4 fragColor;
  7. void main()
  8. {
  9.     vec4 color = texture2D(effectSource, qt_TexCoord0);
  10.     float p = float(percent) / 100.0f;
  11.     float alpha = 1.0f;
  12.     if (dir == 0 ) {
  13.         alpha = 1.0 - step(p, qt_TexCoord0.x);
  14.     } else if (dir == 1){
  15.         alpha = 1.0 - step(p, 1.0 - qt_TexCoord0.x);
  16.     } else if (dir == 2) {
  17.         alpha = 1.0f - step(p, qt_TexCoord0.y);
  18.     } else if (dir == 3) {
  19.         alpha = 1.0f - step(p, 1.0 - qt_TexCoord0.y);
  20.     }
  21.     fragColor = vec4(color.rgb, alpha);
  22. }



效果比较简单,以从左向右为例(dir == 0), 说明一下:
先是把percent 归一化处理 (float p = percent / 100.0),
纹理坐标qt_TexCoord0.x的取值范围为 0 - 1,按照Qml的坐标系统,左边为0,右边为1。
之后纹理坐标与p进行比较,坐标小于p则显示(透明度为1),大于p则不显示(透明度为0). (也可以直接用discard丢弃片段)
step是glsl内置函数,step(p, qt_TexCoord0.x) 就是x小于p返回0,大于等于p返回1。 结果正好与上面分析的相反,用1 减去即可: alpha = 1.0 - step(p, qt_TexCoord0.x);
最终输出颜色即可:
fragColor = vec4(color.rgb, alpha);

涛哥是个Qml高手,著有《Qml组件化编程》《Qml特效》系列教程,见知乎专栏-Qt进阶之路:https://zhuanlan.zhihu.com/TaoQt
或微信公众号:Qt进阶之路
离线big_mouse

只看该作者 1楼 发表于: 2020-04-14
快速回复
限100 字节
 
上一个 下一个