Slint C++ 开幕动画

Slint C++ 图片开幕动画

按照小游戏的设定,一开始图片是被挡住的,当鼠标点击了所在图片之后,图片就被掀开。现在我们需要做一个类似开幕的效果,他的实现方式也不是很困难:给这个矩形上面附加两个1/2大小的矩形,再叠加一个透明矩形用来接受鼠标事件,当点击之后左边的矩形往左走,右边的矩形往右走,为他们两个顺便加上过度动画效果。

动画设计

  • 左幕布
    • 高度设置为磁贴块的大小
    • 宽度设置为磁贴块的一半大小
    • 位置设置在磁贴块的左边
    • 当点击之后宽度逐渐到0,到0后设置为不可见
  • 右幕布
    • 高度设置为磁贴块的大小
    • 宽度设置为磁贴块的一半大小
    • 位置设置在磁贴块的右边
    • 当点击之后宽度逐渐到0,到0后设置为不可见

添加一块幕布

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
component MemoryTile inherits Rectangle{
width: 64px;
height: 64px;
background: gray;

Image {
width: parent.width;
height: parent.height;
source: @image-url("icons/bus.png");
}

// 左幕布
Rectangle {
width: parent.width / 2;
height: parent.height;
x: 0px;
background: darkgray;
}
}
export component MainWindow inherits Window {
MemoryTile {}
}

添加一块的效果
添加一块的效果

添加两块幕布

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
component MemoryTile inherits Rectangle{
width: 64px;
height: 64px;
background: gray;

Image {
width: parent.width;
height: parent.height;
source: @image-url("icons/bus.png");
}

// 左幕布
Rectangle {
width: parent.width / 2;
height: parent.height;
x: 0px;
background: darkgray;
}

// 右幕布
Rectangle {
width: parent.width / 2;
height: parent.height;
x: parent.width / 2;
background: darkgray;
}
}
export component MainWindow inherits Window {
MemoryTile {}
}

最终代码

定义了一个名为MemoryTile的组件,以及一个名为MainWindow的窗口组件。MemoryTile组件继承自Rectangle,具有以下属性和回调函数:

  1. callback clicked:定义了一个名为clicked的回调函数。
  2. in property <bool> open_curtain:定义了一个名为open_curtain的属性,类型为布尔值,表示幕布的打开状态。
  3. in property <bool> solved:定义了一个名为solved的属性,类型为布尔值,表示组件的状态。
  4. in property <image> icon:定义了一个名为icon的属性,类型为图像,表示组件的图标。

组件的宽度和高度分别为64像素,背景颜色根据solved属性的值来决定,如果是solved则为深灰色,否则为灰色。

接下来,代码定义了一个名为animate的动画属性,用于改变组件的背景颜色。动画的持续时间为800毫秒,使用ease-inease-in` easing函数。

然后,代码定义了一个名为Image的子组件,其宽度、高度和源图像都来自父组件的icon属性。

接下来,代码定义了两个名为Rectangle的子组件,分别表示左幕布和右幕布。左幕布的宽度根据open_curtain属性的值来决定,如果是open_curtain则为0像素,否则为父组件宽度的一半。背景颜色为深灰色。当open_curtain属性改变时,宽度会通过动画进行更新。

右幕布的宽度、高度和背景颜色与左幕布相同。此外,当open_curtain属性改变时,还会通过动画更新位置和宽度。

最后,代码定义了一个名为TouchArea的子组件,当用户点击时,会调用父组件的clicked回调函数。

最后,代码导出了MainWindow组件,并在其中定义了一个MemoryTile组件,其icon属性为icons/bus.png,当点击时会改变open_curtain属性的值。

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
component MemoryTile inherits Rectangle{
callback clicked;
in property <bool> open_curtain;
in property <bool> solved;
in property <image> icon;

width: 64px;
height: 64px;
background: solved? darkgrey : grey;

animate background {
duration: 800ms;
}

Image {
width: parent.width;
height: parent.height;
source: icon;
}

// 左幕布
Rectangle {
width: open_curtain ? 0px : (parent.width / 2);
height: parent.height;
x: 0px;
background: darkgrey;
animate width {
duration: 250ms;
easing: ease-in;
}
}

// 右幕布
Rectangle {
width: open_curtain ? 0px : (parent.width / 2);
height: parent.height;
x: open_curtain ? parent.width : (parent.width / 2);
background: darkgrey;
animate width {
duration: 250ms;
easing: ease-in;
}
animate x {
duration: 250ms;
easing: ease-in;
}
}

TouchArea {
clicked => {
root.clicked();
}
}
}
export component MainWindow inherits Window {
MemoryTile {
icon: @image-url("icons/bus.png");
clicked => {
self.open-curtain = !self.open-curtain;
}
}
}

Slint C++ 开幕动画
http://cvrain.cloudvl.cn/2023/12/10/Slint/slint-polish-tile/
作者
ClaudeRainer
发布于
2023年12月10日
许可协议