logo头像

传承工匠精神

Qml特效10-进场动画-轮子

gallery-img

简介

这是《Qml特效-进场动画》系列文章的第10篇,涛哥将会教大家一些Qml进场动画相关的知识。

进场动画效果 参考了WPS版ppt的动画,基本效果已经全部实现,可以到github TaoQuick项目中预览:

进场动画预览

关于文章

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

轮子效果预览

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

实现原理

通过数值动画,控制百分比属性percent从0 到100变化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import QtQuick 2.12
import QtQuick.Controls 2.12
ShaderEffect {
...
enum Direct {
Clockwise = 0,
CounterClockwise = 1
}
property int dir : AWheel.Direct.Clockwise
property int percent: 0
opacity: percent > 0 ? 1 : 0
NumberAnimation {
id: animation
target: r
property: "percent"
from: 0
to: 100
alwaysRunToEnd: true
loops: 1
duration: 1000
}
...
}

在Shader中,使用glsl片段着色器实现像素的控制:

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

扇形效果:

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

赞赏是不耍流氓的鼓励