dsh-motion 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICE.md +3 -1
- package/README.md +37 -5
- package/docs/ai-native-motion.md +127 -16
- package/docs/dev-loop.md +1 -1
- package/docs/performance-budget.md +73 -0
- package/lib/ops.js +44 -2
- package/package.json +7 -2
- package/skills/animation-router/SKILL.md +83 -16
- package/skills/animation-router/references/confirmation.md +82 -0
- package/skills/design-spec/SKILL.md +18 -4
- package/skills/qa-rubric/SKILL.md +13 -0
- package/styles/3b1b/STYLE.md +68 -0
- package/styles/3b1b/preview.jpg +0 -0
- package/styles/3b1b/style.json +50 -0
- package/styles/3b1b/theme.py +46 -0
- package/styles/3b1b/tokens.json +32 -0
- package/styles/README.md +13 -6
- package/styles/blueprint/style.json +39 -3
- package/styles/blueprint/theme.py +3 -0
- package/styles/dataviz/style.json +42 -2
- package/styles/dataviz/theme.py +3 -0
- package/styles/registry.json +213 -0
- package/styles/swiss-motion/style.json +38 -2
- package/styles/swiss-motion/theme.py +3 -0
- package/styles/whiteboard/STYLE.md +58 -0
- package/styles/whiteboard/preview.jpg +0 -0
- package/styles/whiteboard/style.json +47 -0
- package/styles/whiteboard/theme.py +56 -0
- package/styles/whiteboard/tokens.json +27 -0
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"generated": true,
|
|
4
|
+
"default": "swiss-motion",
|
|
5
|
+
"styles": [
|
|
6
|
+
{
|
|
7
|
+
"slug": "swiss-motion",
|
|
8
|
+
"num": "01",
|
|
9
|
+
"name_cn": "瑞士动态排版",
|
|
10
|
+
"name_en": "Swiss Motion Graphics",
|
|
11
|
+
"category_cn": "图形与排版",
|
|
12
|
+
"uses": [
|
|
13
|
+
"Formula",
|
|
14
|
+
"Definition",
|
|
15
|
+
"Data conclusion",
|
|
16
|
+
"Typography"
|
|
17
|
+
],
|
|
18
|
+
"uses_cn": [
|
|
19
|
+
"公式",
|
|
20
|
+
"定义",
|
|
21
|
+
"数据结论",
|
|
22
|
+
"排版"
|
|
23
|
+
],
|
|
24
|
+
"keywords": [
|
|
25
|
+
"公式",
|
|
26
|
+
"欧拉",
|
|
27
|
+
"定理",
|
|
28
|
+
"定义",
|
|
29
|
+
"恒等式",
|
|
30
|
+
"推导",
|
|
31
|
+
"排版",
|
|
32
|
+
"方程"
|
|
33
|
+
],
|
|
34
|
+
"avoid": [
|
|
35
|
+
"图表",
|
|
36
|
+
"几何证明"
|
|
37
|
+
],
|
|
38
|
+
"aspect": [
|
|
39
|
+
"16:9"
|
|
40
|
+
],
|
|
41
|
+
"fps": 30,
|
|
42
|
+
"complexity": "low",
|
|
43
|
+
"demo": "showcase/swiss-euler",
|
|
44
|
+
"source": "https://github.com/lemomo-ai/lemo-opuscar/tree/main/styles/swiss-motion"
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"slug": "dataviz",
|
|
48
|
+
"num": "02",
|
|
49
|
+
"name_cn": "数据叙事",
|
|
50
|
+
"name_en": "Data Storytelling",
|
|
51
|
+
"category_cn": "信息与发布",
|
|
52
|
+
"uses": [
|
|
53
|
+
"Trends",
|
|
54
|
+
"Comparison",
|
|
55
|
+
"Distribution",
|
|
56
|
+
"Scientific data"
|
|
57
|
+
],
|
|
58
|
+
"uses_cn": [
|
|
59
|
+
"趋势",
|
|
60
|
+
"比较",
|
|
61
|
+
"分布",
|
|
62
|
+
"科学数据"
|
|
63
|
+
],
|
|
64
|
+
"keywords": [
|
|
65
|
+
"数据",
|
|
66
|
+
"图表",
|
|
67
|
+
"趋势",
|
|
68
|
+
"比较",
|
|
69
|
+
"分布",
|
|
70
|
+
"导数",
|
|
71
|
+
"斜率",
|
|
72
|
+
"切线",
|
|
73
|
+
"割线",
|
|
74
|
+
"函数",
|
|
75
|
+
"变化率",
|
|
76
|
+
"统计"
|
|
77
|
+
],
|
|
78
|
+
"avoid": [
|
|
79
|
+
"纯文字排版",
|
|
80
|
+
"角色叙事"
|
|
81
|
+
],
|
|
82
|
+
"aspect": [
|
|
83
|
+
"16:9"
|
|
84
|
+
],
|
|
85
|
+
"fps": 30,
|
|
86
|
+
"complexity": "low",
|
|
87
|
+
"demo": "showcase/dataviz-secant",
|
|
88
|
+
"source": "https://github.com/lemomo-ai/lemo-opuscar/tree/main/styles/dataviz"
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"slug": "blueprint",
|
|
92
|
+
"num": "03",
|
|
93
|
+
"name_cn": "蓝图工程制图",
|
|
94
|
+
"name_en": "Blueprint",
|
|
95
|
+
"category_cn": "图形与排版",
|
|
96
|
+
"uses": [
|
|
97
|
+
"Geometry proof",
|
|
98
|
+
"Structures",
|
|
99
|
+
"Dimensions"
|
|
100
|
+
],
|
|
101
|
+
"uses_cn": [
|
|
102
|
+
"几何证明",
|
|
103
|
+
"结构",
|
|
104
|
+
"尺寸关系"
|
|
105
|
+
],
|
|
106
|
+
"keywords": [
|
|
107
|
+
"几何",
|
|
108
|
+
"证明",
|
|
109
|
+
"三角形",
|
|
110
|
+
"圆",
|
|
111
|
+
"角度",
|
|
112
|
+
"尺寸",
|
|
113
|
+
"工程",
|
|
114
|
+
"结构",
|
|
115
|
+
"作图",
|
|
116
|
+
"勾股"
|
|
117
|
+
],
|
|
118
|
+
"avoid": [
|
|
119
|
+
"图表",
|
|
120
|
+
"手绘"
|
|
121
|
+
],
|
|
122
|
+
"aspect": [
|
|
123
|
+
"16:9"
|
|
124
|
+
],
|
|
125
|
+
"fps": 30,
|
|
126
|
+
"complexity": "medium",
|
|
127
|
+
"demo": "showcase/blueprint-pythagoras",
|
|
128
|
+
"source": "https://github.com/lemomo-ai/lemo-opuscar/tree/main/styles/blueprint"
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
"slug": "whiteboard",
|
|
132
|
+
"num": "04",
|
|
133
|
+
"name_cn": "白板讲解",
|
|
134
|
+
"name_en": "Whiteboard Explainer",
|
|
135
|
+
"category_cn": "手绘与绘画",
|
|
136
|
+
"uses": [
|
|
137
|
+
"Explainers",
|
|
138
|
+
"Online courses",
|
|
139
|
+
"Science"
|
|
140
|
+
],
|
|
141
|
+
"uses_cn": [
|
|
142
|
+
"科学解释",
|
|
143
|
+
"课程",
|
|
144
|
+
"机制说明"
|
|
145
|
+
],
|
|
146
|
+
"keywords": [
|
|
147
|
+
"讲解",
|
|
148
|
+
"课程",
|
|
149
|
+
"科学",
|
|
150
|
+
"机制",
|
|
151
|
+
"流程",
|
|
152
|
+
"为什么",
|
|
153
|
+
"原理",
|
|
154
|
+
"物理",
|
|
155
|
+
"化学",
|
|
156
|
+
"生物"
|
|
157
|
+
],
|
|
158
|
+
"avoid": [
|
|
159
|
+
"高密度公式",
|
|
160
|
+
"暗场"
|
|
161
|
+
],
|
|
162
|
+
"aspect": [
|
|
163
|
+
"16:9"
|
|
164
|
+
],
|
|
165
|
+
"fps": 30,
|
|
166
|
+
"complexity": "medium",
|
|
167
|
+
"demo": "showcase/whiteboard-derivative",
|
|
168
|
+
"source": "https://github.com/lemomo-ai/lemo-opuscar/tree/main/styles/whiteboard"
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
"slug": "3b1b",
|
|
172
|
+
"num": "05",
|
|
173
|
+
"name_cn": "3b1b 数学动画",
|
|
174
|
+
"name_en": "3Blue1Brown Style",
|
|
175
|
+
"category_cn": "数学讲解",
|
|
176
|
+
"uses": [
|
|
177
|
+
"Linear algebra",
|
|
178
|
+
"Calculus",
|
|
179
|
+
"Probability",
|
|
180
|
+
"Neural networks"
|
|
181
|
+
],
|
|
182
|
+
"uses_cn": [
|
|
183
|
+
"线代",
|
|
184
|
+
"微积分",
|
|
185
|
+
"概率",
|
|
186
|
+
"神经网络"
|
|
187
|
+
],
|
|
188
|
+
"keywords": [
|
|
189
|
+
"向量",
|
|
190
|
+
"矩阵",
|
|
191
|
+
"特征值",
|
|
192
|
+
"旋转",
|
|
193
|
+
"复数",
|
|
194
|
+
"单位圆",
|
|
195
|
+
"线代",
|
|
196
|
+
"概率",
|
|
197
|
+
"微积分",
|
|
198
|
+
"神经网络"
|
|
199
|
+
],
|
|
200
|
+
"avoid": [
|
|
201
|
+
"产品发布",
|
|
202
|
+
"纯排版"
|
|
203
|
+
],
|
|
204
|
+
"aspect": [
|
|
205
|
+
"16:9"
|
|
206
|
+
],
|
|
207
|
+
"fps": 30,
|
|
208
|
+
"complexity": "medium",
|
|
209
|
+
"demo": "showcase/3b1b-unit-circle",
|
|
210
|
+
"source": "https://github.com/subinium/3b1b-style-animation-skill"
|
|
211
|
+
}
|
|
212
|
+
]
|
|
213
|
+
}
|
|
@@ -4,8 +4,44 @@
|
|
|
4
4
|
"cn": "瑞士动态排版",
|
|
5
5
|
"category_en": "Graphic & Type",
|
|
6
6
|
"category_cn": "图形与排版",
|
|
7
|
-
"uses": [
|
|
7
|
+
"uses": [
|
|
8
|
+
"Formula",
|
|
9
|
+
"Definition",
|
|
10
|
+
"Data conclusion",
|
|
11
|
+
"Typography"
|
|
12
|
+
],
|
|
8
13
|
"source": "https://github.com/lemomo-ai/lemo-opuscar/tree/main/styles/swiss-motion",
|
|
9
14
|
"license": "style doc MIT; demo stills CC BY 4.0 (LemoLab)",
|
|
10
|
-
"implementation": "manimgx (theme.py + tokens.json)"
|
|
15
|
+
"implementation": "manimgx (theme.py + tokens.json)",
|
|
16
|
+
"num": "01",
|
|
17
|
+
"film": "Euler Formula",
|
|
18
|
+
"line": "A formula on a Swiss grid: one red accent, five constants.",
|
|
19
|
+
"line_cn": "瑞士网格上的一个公式:一个红色信号色,五个常数。",
|
|
20
|
+
"uses_cn": [
|
|
21
|
+
"公式",
|
|
22
|
+
"定义",
|
|
23
|
+
"数据结论",
|
|
24
|
+
"排版"
|
|
25
|
+
],
|
|
26
|
+
"keywords": [
|
|
27
|
+
"公式",
|
|
28
|
+
"欧拉",
|
|
29
|
+
"定理",
|
|
30
|
+
"定义",
|
|
31
|
+
"恒等式",
|
|
32
|
+
"推导",
|
|
33
|
+
"排版",
|
|
34
|
+
"方程"
|
|
35
|
+
],
|
|
36
|
+
"avoid": [
|
|
37
|
+
"图表",
|
|
38
|
+
"几何证明"
|
|
39
|
+
],
|
|
40
|
+
"demo": "showcase/swiss-euler",
|
|
41
|
+
"demo_duration_sec": 6.2,
|
|
42
|
+
"aspect": [
|
|
43
|
+
"16:9"
|
|
44
|
+
],
|
|
45
|
+
"fps": 30,
|
|
46
|
+
"complexity": "low"
|
|
11
47
|
}
|
|
@@ -13,6 +13,9 @@ import manimgx as m
|
|
|
13
13
|
|
|
14
14
|
TOKENS = json.loads(Path(__file__).with_name("tokens.json").read_text(encoding="utf-8"))
|
|
15
15
|
|
|
16
|
+
# inspect 在 import 时读 config.frame_rate;必须放在模块层,不能只在 construct 里。
|
|
17
|
+
m.config.frame_rate = int(TOKENS["motion"]["fps"])
|
|
18
|
+
|
|
16
19
|
GROUND = TOKENS["colors"]["ground"]
|
|
17
20
|
PAPER = TOKENS["colors"]["paper"]
|
|
18
21
|
INK = TOKENS["colors"]["ink"]
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: whiteboard
|
|
3
|
+
version: 1.0.0
|
|
4
|
+
source: https://github.com/lemomo-ai/lemo-opuscar/tree/main/styles/whiteboard
|
|
5
|
+
license: MIT(上游风格文档);demo 静帧 CC BY 4.0(LemoLab)
|
|
6
|
+
status: adapted
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Whiteboard Explainer · 白板讲解
|
|
10
|
+
|
|
11
|
+
> 上游:Lemo-Opuscar `styles/whiteboard`(MIT)。保留“一块板 + 三支马克笔 + 书写顺序”的语法;
|
|
12
|
+
> manimgx 版省掉手/浮空笔/相机旅行,用 draw-on 与固定机位近似。
|
|
13
|
+
|
|
14
|
+
## 1. 定位
|
|
15
|
+
|
|
16
|
+
一块暖白干擦板,所有内容都是马克笔“写”出来的:
|
|
17
|
+
|
|
18
|
+
- 适合:科学解释、课程、机制/流程说明;
|
|
19
|
+
- 不适合:需要真实材质、角色表演、复杂 3D 的题材。
|
|
20
|
+
|
|
21
|
+
## 2. 不变量
|
|
22
|
+
|
|
23
|
+
| 项 | 规则 |
|
|
24
|
+
|---|---|
|
|
25
|
+
| 板面 | 暖白 `#F7F5EF`,可有轻微不均与旧字痕 |
|
|
26
|
+
| 墨色 | 黑 `#23262C`:结构与文字 |
|
|
27
|
+
| 过程色 | 蓝 `#2A5CB3`:测量、过程、正在变化 |
|
|
28
|
+
| 强调 | 橙 `#D97757`:结论、最终答案;每区最多一次 |
|
|
29
|
+
| 字体 | 手写体(Chalkboard SE);公式 New Computer Modern |
|
|
30
|
+
| 运动 | 按书写顺序 draw-on;一笔接一笔;不弹跳 |
|
|
31
|
+
| 版面 | 一个想法一个区域;距离=论证距离;标签要么全在画面内,要么不出现 |
|
|
32
|
+
|
|
33
|
+
## 3. manimgx 映射
|
|
34
|
+
|
|
35
|
+
- `theme.py`:`apply_config()`、`backdrop()`(暖白渐变 + 细噪点);
|
|
36
|
+
- 线条与文字用 `Create` / `Write` 按顺序出现;没有笔、手、橡皮、相机;
|
|
37
|
+
- 字体替换:EMS Tech / Architects Daughter → `Chalkboard SE`;
|
|
38
|
+
- 旧字痕用低透明度 `Text`/`Line` 近似。
|
|
39
|
+
|
|
40
|
+
## 4. Do / Don't
|
|
41
|
+
|
|
42
|
+
**Do**
|
|
43
|
+
|
|
44
|
+
- 先写标题,再按“定义 → 例子 → 结论”在板面上展开;
|
|
45
|
+
- 蓝色只给“正在变化”的对象,橙色只给结论;
|
|
46
|
+
- 结论出现后停住,给读者读完。
|
|
47
|
+
|
|
48
|
+
**Don't**
|
|
49
|
+
|
|
50
|
+
- 不画手、笔、光标;
|
|
51
|
+
- 不用第四种马克笔颜色;
|
|
52
|
+
- 不做镜头急推/急拉;文字不压线。
|
|
53
|
+
|
|
54
|
+
## 5. 与上游的差异
|
|
55
|
+
|
|
56
|
+
- 上游有浮空马克笔、笔影、干擦纹理、相机旅行;这里只保留书写顺序与三色语义;
|
|
57
|
+
- 上游 24 fps、板面可远大于画幅;本实现 30 fps、固定画幅;
|
|
58
|
+
- 字体与纹理均为近似,验收以帧为准。
|
|
Binary file
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"slug": "whiteboard",
|
|
3
|
+
"en": "Whiteboard Explainer",
|
|
4
|
+
"cn": "白板讲解",
|
|
5
|
+
"category_en": "Hand-drawn & Painting",
|
|
6
|
+
"category_cn": "手绘与绘画",
|
|
7
|
+
"uses": [
|
|
8
|
+
"Explainers",
|
|
9
|
+
"Online courses",
|
|
10
|
+
"Science"
|
|
11
|
+
],
|
|
12
|
+
"source": "https://github.com/lemomo-ai/lemo-opuscar/tree/main/styles/whiteboard",
|
|
13
|
+
"license": "style doc MIT; demo stills CC BY 4.0 (LemoLab)",
|
|
14
|
+
"implementation": "manimgx (theme.py + tokens.json)",
|
|
15
|
+
"num": "04",
|
|
16
|
+
"film": "Secant on a Whiteboard",
|
|
17
|
+
"line": "A derivative explained on one warm whiteboard with three markers.",
|
|
18
|
+
"line_cn": "在一块暖白板上,用三支马克笔讲清导数。",
|
|
19
|
+
"uses_cn": [
|
|
20
|
+
"科学解释",
|
|
21
|
+
"课程",
|
|
22
|
+
"机制说明"
|
|
23
|
+
],
|
|
24
|
+
"keywords": [
|
|
25
|
+
"讲解",
|
|
26
|
+
"课程",
|
|
27
|
+
"科学",
|
|
28
|
+
"机制",
|
|
29
|
+
"流程",
|
|
30
|
+
"为什么",
|
|
31
|
+
"原理",
|
|
32
|
+
"物理",
|
|
33
|
+
"化学",
|
|
34
|
+
"生物"
|
|
35
|
+
],
|
|
36
|
+
"avoid": [
|
|
37
|
+
"高密度公式",
|
|
38
|
+
"暗场"
|
|
39
|
+
],
|
|
40
|
+
"demo": "showcase/whiteboard-derivative",
|
|
41
|
+
"demo_duration_sec": 9.6,
|
|
42
|
+
"aspect": [
|
|
43
|
+
"16:9"
|
|
44
|
+
],
|
|
45
|
+
"fps": 30,
|
|
46
|
+
"complexity": "medium"
|
|
47
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"""whiteboard 1.0.0 — Lemo-Opuscar 的 Whiteboard Explainer,manimgx 实现层。
|
|
2
|
+
|
|
3
|
+
上游规范(MIT):styles/whiteboard/STYLE.md
|
|
4
|
+
暖白板 + 三支马克笔;manimgx 版省掉笔/手/相机旅行,只保留书写与结构。
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import json
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
import numpy as np
|
|
13
|
+
|
|
14
|
+
import manimgx as m
|
|
15
|
+
|
|
16
|
+
TOKENS = json.loads(Path(__file__).with_name("tokens.json").read_text(encoding="utf-8"))
|
|
17
|
+
|
|
18
|
+
# inspect 在 import 时读 config.frame_rate;必须放在模块层,不能只在 construct 里。
|
|
19
|
+
m.config.frame_rate = int(TOKENS["motion"]["fps"])
|
|
20
|
+
|
|
21
|
+
BOARD = TOKENS["colors"]["board"]
|
|
22
|
+
BOARD_EDGE = TOKENS["colors"]["board_edge"]
|
|
23
|
+
INK = TOKENS["colors"]["ink"]
|
|
24
|
+
BLUE = TOKENS["colors"]["blue"]
|
|
25
|
+
ORANGE = TOKENS["colors"]["orange"]
|
|
26
|
+
MUTED = TOKENS["colors"]["muted"]
|
|
27
|
+
GHOST = TOKENS["colors"]["ghost"]
|
|
28
|
+
LAYOUT = TOKENS["layout"]
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def apply_config(width: int = 1920, height: int = 1080, fps: int = 30) -> None:
|
|
32
|
+
m.config.pixel_width = width
|
|
33
|
+
m.config.pixel_height = height
|
|
34
|
+
m.config.frame_rate = fps
|
|
35
|
+
m.config.background_color = BOARD
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def backdrop(seed: int = 5) -> m.ImageMobject:
|
|
39
|
+
"""暖白板:轻微渐变 + 细噪点,避免大块纯白。"""
|
|
40
|
+
w, h = m.config.pixel_width, m.config.pixel_height
|
|
41
|
+
yy, xx = np.mgrid[0:h, 0:w]
|
|
42
|
+
u = xx / (w - 1)
|
|
43
|
+
v = yy / (h - 1)
|
|
44
|
+
glow = np.exp(-(((u - 0.45) ** 2) / 0.30 + ((v - 0.42) ** 2) / 0.30))
|
|
45
|
+
rgb = np.empty((h, w, 3), dtype=float)
|
|
46
|
+
base = np.array([247, 245, 239], dtype=float)
|
|
47
|
+
edge = np.array([233, 228, 216], dtype=float)
|
|
48
|
+
rgb[:] = edge + glow[..., None] * (base - edge)
|
|
49
|
+
rng = np.random.default_rng(seed)
|
|
50
|
+
rgb = np.clip(rgb + rng.normal(0, 1.0, rgb.shape), 0, 255).astype(np.uint8)
|
|
51
|
+
img = m.ImageMobject(rgb, scale_to_resolution=min(w, h), resampling_algorithm=3)
|
|
52
|
+
return img.move_to(m.ORIGIN)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def board_line(y: float, x0: float, x1: float, color: str = INK, width: float = 2.4) -> m.Line:
|
|
56
|
+
return m.Line([x0, y, 0], [x1, y, 0], color=color, stroke_width=width)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "whiteboard",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"source": "https://github.com/lemomo-ai/lemo-opuscar/tree/main/styles/whiteboard",
|
|
5
|
+
"license": "style doc MIT; demo stills CC BY 4.0 (LemoLab)",
|
|
6
|
+
"colors": {
|
|
7
|
+
"board": "#F7F5EF",
|
|
8
|
+
"board_edge": "#E9E4D8",
|
|
9
|
+
"ink": "#23262C",
|
|
10
|
+
"blue": "#2A5CB3",
|
|
11
|
+
"orange": "#D97757",
|
|
12
|
+
"muted": "#8A857C",
|
|
13
|
+
"ghost": "#C9C3B6"
|
|
14
|
+
},
|
|
15
|
+
"typography": {
|
|
16
|
+
"hand": { "family": "Chalkboard SE", "size": 34 },
|
|
17
|
+
"label": { "family": "Chalkboard SE", "size": 24 },
|
|
18
|
+
"math": { "family": "New Computer Modern", "size": 54 }
|
|
19
|
+
},
|
|
20
|
+
"layout": {
|
|
21
|
+
"aspect": "16:9",
|
|
22
|
+
"frame": { "width": 14.222, "height": 8.0 },
|
|
23
|
+
"margin": 0.55
|
|
24
|
+
},
|
|
25
|
+
"motion": { "fps": 30, "easing": "hand-speed", "hold_min_seconds": 1.4 },
|
|
26
|
+
"audio": { "target_lufs": -14, "true_peak_db": -1 }
|
|
27
|
+
}
|