时序与组合
本页介绍如何安排元素之间的先后时序,以及如何用多个组拼出一个加载动画。
元素时间
每个元素都有一个启动偏移(来自 stagger)和一个周期长度(来自 durations、部件的 duration 或 spec 的 duration)。在时间 t:
local = t - offset。- 如果
local为负,说明元素还没启动,显示它的静止值。 - 否则周期进度为
(local mod cycle) / cycle,取值 0 到 1,所有 track 都在这个位置采样。
Stagger
stagger 让元素错开启动、依次运动。它有两种写法。
{ "each": 0.1, "start": 0 } 让元素 i 的偏移为 start + each × i 秒,start 可以省略。
{
"$schema": "https://maitrungduc1410.github.io/loader-kit/schema/v1.json",
"schemaVersion": 1,
"name": "TimingWave",
"duration": 1.2,
"layout": { "type": "row", "count": 5, "gap": 0.06 },
"shape": { "type": "circle" },
"stagger": { "each": 0.1 },
"tracks": [
{
"property": "translateY",
"keyTimes": [0, 0.25, 0.5, 1],
"values": [0, -0.2, 0, 0],
"easing": ["easeOut", "easeIn", "linear"]
}
]
}TimingWave在 playground 中打开 - 元素 0, 从 0 秒开始
- 元素 1, 从 0.1 秒开始
- 元素 2, 从 0.2 秒开始
- 元素 3, 从 0.3 秒开始
- 元素 4, 从 0.4 秒开始
数组写法则按索引为每个元素单独指定偏移,数组长度不能少于元素个数。grid 示例就是用数组让波浪从一角开始的。
负偏移
偏移可以为负。偏移为负的元素在 t = 0 时已经走完了周期的一部分。如果希望每个元素从第一帧起就可见,就用负偏移,比如 stack 涟漪:周期为 1.5 秒,[0, -0.5, -1] 让三个圆均匀错开。
如何选择偏移
要均匀分布,偏移取 cycle / count。比如 8 个元素的圆环、周期 1 秒时,each: 0.125 恰好在每个周期形成一整轮波浪。
静止值
元素启动之前,以及没有 track 的属性,都显示静止值:scale、scaleX、scaleY、opacity 和 strokeEnd 为 1,其他属性为 0。
rest 可以为一组元素修改静止值。这里的 rest: { "scale": 0 } 会把每个点隐藏到它的 stagger 延迟结束,所以开头时点会一个个出现:
{
"$schema": "https://maitrungduc1410.github.io/loader-kit/schema/v1.json",
"schemaVersion": 1,
"name": "TimingRest",
"duration": 1.2,
"layout": { "type": "row", "count": 4, "gap": 0.08 },
"shape": { "type": "circle" },
"stagger": { "each": 0.3 },
"rest": { "scale": 0 },
"tracks": [
{ "property": "scale", "keyTimes": [0, 0.5, 1], "values": [0, 1, 0], "easing": "easeInOut" }
]
}TimingRest在 playground 中打开 rest 还能用来摆放元素:没有 track 的属性会一直保持静止值。部件示例就用 rest.translateY 把一个点放在中心上方。
定格的画面会跳过等待
当视图用 cycleProgress 定格一帧时,引擎会先跳过若干个完整周期,直到所有元素都已启动。所以定格的画面里,不会出现元素还停在启动前静止值的情况。
时长
durations 按索引为每个元素单独指定周期长度。它会覆盖部件和 spec 的 duration,长度不能少于元素个数。周期不同的元素会时而同步、时而错开:
{
"$schema": "https://maitrungduc1410.github.io/loader-kit/schema/v1.json",
"schemaVersion": 1,
"name": "TimingDurations",
"duration": 1,
"layout": { "type": "row", "count": 3, "gap": 0.1 },
"shape": { "type": "circle" },
"durations": [0.8, 1, 1.3],
"tracks": [
{ "property": "scale", "keyTimes": [0, 0.5, 1], "values": [1, 0.3, 1], "easing": "easeInOut" }
]
}TimingDurations在 playground 中打开 部件
一份 spec 默认就是一组元素,直接写在顶层。如果要组合布局、形状或 track 各不相同的多个组,就把它们列在 parts 中。每个部件都可以设置 layout、shape、tracks、stagger、duration、durations、rest 和 groupTracks。
- 部件按顺序绘制,后面的部件在上层。
- 元素索引跨部件连续:部件 1 的第一个元素紧接在部件 0 的最后一个元素之后。
colors设置用的就是这些索引。 - 部件的
duration设置它自己的周期长度,默认是 spec 的duration。 - 使用了
parts的 spec,不能在顶层再设置组字段。
这里部件 0 是一个会脉动的大圆。部件 1 是用 rest 放在它上方的小点,以快一倍的周期闪烁:
{
"$schema": "https://maitrungduc1410.github.io/loader-kit/schema/v1.json",
"schemaVersion": 1,
"name": "TimingParts",
"duration": 1.2,
"parts": [
{
"layout": { "type": "single", "size": 0.4 },
"shape": { "type": "circle" },
"tracks": [
{ "property": "scale", "keyTimes": [0, 0.5, 1], "values": [1, 0.7, 1], "easing": "easeInOut" }
]
},
{
"layout": { "type": "single", "size": 0.16 },
"shape": { "type": "circle" },
"duration": 0.6,
"rest": { "translateY": -0.4 },
"tracks": [
{ "property": "opacity", "keyTimes": [0, 0.5, 1], "values": [1, 0.4, 1] }
]
}
]
}TimingParts在 playground 中打开 组 track
groupTracks 让整组元素绕方框中心运动,支持 scale、scaleX、scaleY、opacity、rotate、translateX 和 translateY。它们按组的周期运行,从 t = 0 开始,不受 stagger 影响,组的 rest 对它们也不生效。
把小点的闪烁换成组旋转,它就会绕着中心转圈:
{
"$schema": "https://maitrungduc1410.github.io/loader-kit/schema/v1.json",
"schemaVersion": 1,
"name": "TimingGroupTracks",
"duration": 1.2,
"parts": [
{
"layout": { "type": "single", "size": 0.4 },
"shape": { "type": "circle" },
"tracks": [
{ "property": "scale", "keyTimes": [0, 0.5, 1], "values": [1, 0.7, 1], "easing": "easeInOut" }
]
},
{
"layout": { "type": "single", "size": 0.16 },
"shape": { "type": "circle" },
"rest": { "translateY": -0.4 },
"groupTracks": [
{ "property": "rotate", "keyTimes": [0, 1], "values": [0, 6.283185307] }
]
}
]
}TimingGroupTracks在 playground 中打开 组 track 在元素变换之后应用。所以元素 track 在组内移动元素,组 track 移动整个组。
透视
rotateX 和 rotateY 让元素做 3D 翻转。perspective 是观察者到方框的距离,以方框为单位(默认 2.5)。值越小,3D 效果越强。它对整份 spec 只设置一次。
{
"$schema": "https://maitrungduc1410.github.io/loader-kit/schema/v1.json",
"schemaVersion": 1,
"name": "TimingPerspective",
"duration": 2,
"perspective": 1.5,
"layout": { "type": "single", "size": 0.6 },
"shape": { "type": "rect", "cornerRadius": 0.1 },
"tracks": [
{ "property": "rotateX", "keyTimes": [0, 0.5, 1], "values": [0, 3.141592654, 3.141592654], "easing": "easeInOut" },
{ "property": "rotateY", "keyTimes": [0, 0.5, 1], "values": [0, 0, 3.141592654], "easing": "easeInOut" }
]
}TimingPerspective在 playground 中打开 内置的 SquareSpin 用的是同样的思路,透视距离为 2.5。
变换顺序
对形状上的每个点,引擎依次应用:缩放、rotateX、rotateY、rotate、透视、平移到元素位置,最后是组变换。具体矩阵见规范。