• 2047阅读
  • 1回复

Qml特效10-进场动画-轮子 [复制链接]

上一主题 下一主题
离线dd759378563
 

只看楼主 倒序阅读 楼主  发表于: 2019-06-09
Qml特效10-进场动画-轮子
目录
(放个目录方便预览。这个目录是从博客复制过来的,点击会跳转到博客)


简介

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


关于文章

文章主要发布在涛哥的博客涛哥的知乎专栏-Qt进阶之路


轮子效果预览

轮子效果,支持顺时针、逆时针两个反向,以及扇形方向







实现原理

通过数值动画,控制百分比属性percent从0 到100变化
  1. import QtQuick 2.12
  2. import QtQuick.Controls 2.12
  3. ShaderEffect {
  4.     ...
  5.     enum Direct {
  6.         Clockwise = 0,
  7.         CounterClockwise = 1
  8.     }
  9.     property int dir : AWheel.Direct.Clockwise
  10.     property int percent: 0
  11.     opacity: percent > 0 ? 1 : 0
  12.     NumberAnimation {
  13.         id: animation
  14.         target: r
  15.         property: "percent"
  16.         from: 0
  17.         to: 100
  18.         alwaysRunToEnd: true
  19.         loops: 1
  20.         duration: 1000
  21.     }
  22.     ...
  23. }



在Shader中,使用glsl片段着色器实现像素的控制:
  1. fragmentShader: TCommon.fragmentShaderCommon + (dir === AWheel.Direct.CounterClockwise ? "
  2.         in vec2 qt_TexCoord0;
  3.         uniform float qt_Opacity;
  4.         uniform sampler2D effectSource;
  5.         uniform int dir;
  6.         uniform int percent;
  7.         out vec4 fragColor;
  8.         void main()
  9.         {
  10.             vec4 color = texture2D(effectSource, qt_TexCoord0);
  11.             float per = float(percent) / 100.0 * -360.0;
  12.             const vec2 origin = vec2(0.5, 0.5);
  13.             const vec2 a = vec2(0.5, 0.0);
  14.             vec2 c = qt_TexCoord0 - origin;
  15.             float alpha = 0.0;
  16.             if (per >= -180.0) {
  17.                 if (qt_TexCoord0.y > 0.5) {
  18.                     if (cos(radians(per))* length(c) * length(a) < dot(c, a)) {
  19.                         alpha = 1.0;
  20.                     }
  21.                 }
  22.             } else {
  23.                 if (qt_TexCoord0.y < 0.5) {
  24.                     if (cos(radians(per))* length(c) * length(a) > dot(c, a)) {
  25.                         alpha = 1.0;
  26.                     }
  27.                 } else {
  28.                     alpha = 1.0;
  29.                 }
  30.             }
  31.             alpha *= qt_Opacity;
  32.             fragColor = vec4(color.rgb * alpha, alpha);
  33.        }
  34. " : "
  35.         in vec2 qt_TexCoord0;
  36.         uniform float qt_Opacity;
  37.         uniform sampler2D effectSource;
  38.         uniform int dir;
  39.         uniform int percent;
  40.         out vec4 fragColor;
  41.         void main()
  42.         {
  43.             vec4 color = texture2D(effectSource, qt_TexCoord0);
  44.             float per = float(percent) / 100.0 * 360.0;
  45.             const vec2 origin = vec2(0.5, 0.5);
  46.             const vec2 a = vec2(0.5, 0.0);
  47.             vec2 c = qt_TexCoord0 - origin;
  48.             float alpha = 0.0;
  49.             if (per <= 180.0) {
  50.                 if (qt_TexCoord0.y < 0.5) {
  51.                     if (cos(radians(per))* length(c) * length(a) < dot(c, a)) {
  52.                         alpha = 1.0;
  53.                     }
  54.                 }
  55.             } else {
  56.                 if (qt_TexCoord0.y > 0.5) {
  57.                     if (cos(radians(per))* length(c) * length(a) > dot(c, a)) {
  58.                         alpha = 1.0;
  59.                     }
  60.                 } else {
  61.                     alpha = 1.0;
  62.                 }
  63.             }
  64.             alpha *= qt_Opacity;
  65.             fragColor = vec4(color.rgb * alpha, alpha);
  66.        }
  67. ")



扇形效果:
  1. in vec2 qt_TexCoord0;
  2. uniform float qt_Opacity;
  3. uniform sampler2D effectSource;
  4. uniform int percent;
  5. out vec4 fragColor;
  6. void main()
  7. {
  8.      vec4 color = texture2D(effectSource, qt_TexCoord0);
  9.      float per = float(percent) / 100.0 * 180;
  10.      const vec2 origin = vec2(0.5, 0.5);
  11.      const vec2 a = vec2(0.5, 0.0);
  12.      vec2 c = qt_TexCoord0 - origin;
  13.      float alpha = 0.0;
  14.      if (cos(radians(per))* length(c) * length(a) < dot(c, a)) {
  15.          alpha = 1.0;
  16.      }
  17.      alpha *= qt_Opacity;
  18.      fragColor = vec4(color.rgb * alpha, alpha);
  19. }




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

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