news 2026/9/10 6:18:02

OpenMAIC 幻灯片页面设计规范指南:slide-craft 技能详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
OpenMAIC 幻灯片页面设计规范指南:slide-craft 技能详解

OpenMAIC 幻灯片页面设计规范指南:slide-craft 技能详解

【免费下载链接】OpenMAICOpen Multi-Agent Interactive Classroom — Get an immersive, multi-agent learning experience in just one click项目地址: https://gitcode.com/GitHub_Trending/op/OpenMAIC

导读

slide-craft是 OpenMAIC 多智能体交互课堂中定义"一页幻灯片长什么样才算好"的设计法则文档。它不是操作流程,而是页面设计定律:画布几何、文字高度表、字号阶梯、对比度配对、间距节奏,以及十种元素类型各自应承载何种内容。本文以该技能文档为主体,结合 slide-dsl 字段手册、page-clone 与 pro-editing 编辑流程,以及仓库中结构校验与 latex 重渲染的真实实现,为你完整还原这套"用数字而非眼睛"设计幻灯片页面的规则。读完你将掌握:如何在 1000 × 562.5 的画布上精确落位元素、如何按高度表重算文本框、如何用对比度配对而非凭感觉改色、以及如何让富文本与公式在播放器里真正按预期渲染。

适用场景:逐元素修补幻灯片、修正颜色或对比度问题、让文字在框内生长或收缩、页面显得拥挤或空旷、或需要用真实富文本结构替换内容时,都应加载本技能。它是page-clonepro-editing两个流程的评判标准——那两个技能决定改哪些页、按什么顺序改,本技能决定改完之后一页好页面应该长什么样。

正在编辑的画布

画布尺寸与安全边距

OpenMAIC 运行时中的每张幻灯片都是在同一套规则下绘制的,画布几何是这套规则的起点:

  • 画布为 1000 × 562.5(设计像素)。这一数值在底层由viewportSize: 1000(画布宽,px)与viewportRatio: 0.5625(高 ÷ 宽)共同决定,在 element-schema.ts 的滑动画布结构 schema 中两者均为必填字段,并被 slide-dsl 明确记录为 "canvaswidth in px1000in this product"。
  • 所有元素遵守 50px 边距。因此有效区域为left ∈ [50, 950]top ∈ [50, 512.5],元素的右边缘(left + width)必须 ≤ 950,底边缘必须 ≤ 512.5。
  • 画布边缘不裁剪 DOM 中的元素,但快照/导出捕获会裁剪画布外的内容,所以画布外的几何本身就是 bug。

页面对齐网格

页面上已有的元素都落在同一个对齐网格上,修补时应当读取邻居的框,落在它们已经在用的那一列上

对齐方式left 取值
左对齐内容left = 60left = 80
居中对齐内容left = (1000 - width) / 2—— 重新计算,绝不靠猜
右对齐内容left = 1000 - width - 60

需要注意:居中的内容改变width会连带改变left,且这是两次独立的写入。一个孤立的元素相对共享左边缘偏差 8px,即使没有任何溢出,看起来也像一次错误。

不存在"对齐操作"

这套运行时没有对齐操作。每个位置都是一个显式数字,通过该元素自身的left/top/width/height写入,一次调用一个路径,数值由你读取到的邻居计算得出。对齐一行意味着给每个元素赋予这一行已经在用的数字——而不是请求页面自己整理。这正是 slide-dsl 强调的 JSON Pointer 写入模型:/content/canvas/elements/N/left这样的叶子路径就是唯一的对齐手段。

文字按表定尺寸,不凭肉眼

10px 内边距与文字高度表

文本元素四边各有 10px 内边距,因此可用区域为(width - 20) × (height - 20)。文本框的高度只能从一个固定表格取值(行高 1.5,已含内边距):

字号1 行2 行3 行4 行5 行
14px436485106127
16px467094118142
18px4976103130157
20px5282112142172
24px5894130166202
28px64106148190232
32px70118166214262
36px76130184238292

替换文字后的高度重推导

替换元素的文字时,重新推导高度而不是沿用旧值:

  1. characters_per_line = (width - 20) / font_size。让最长行保持在它的≤ 75%以内;超过 100% 文字就会换行,多占一行你没有预算的行。
  2. 数出新内容需要的行数——每个<p>算一行,每个超过characters_per_line的段落再加一行换行——然后加约0.8 行的余量并向上取整。
  3. 对照内容中存在的最大字号(不是平均字号)查表。

高度是容器,不是钳子:溢出的文字会溢出盒子而不是收缩,页面会如实显示溢出。修复顺序是先缩短文字,再升一档表格行,最后加宽盒子——按此顺序,因为需要更大盒子的幻灯片通常只需要更少的文字。

字号阶梯(Type Scale)

内容字号
主标题 Main title32-36px
副标题 Subtitle24-28px
要点 Key points18-20px
正文 Body16-18px
说明 Caption14-16px

各层级之间保持 2-4px 的差距,同一层级的所有内容使用同一个字号。当你触碰一个元素时,从该页面上扮演相同角色的兄弟元素那里取字号,而不是从这张表里现取——页面自身的阶梯优先,这张表是你识别元素属于哪个层级的工具。

字号存在于内容 HTML 中,以内联font-size写在<p>上——没有可供写入的 font-size 字段。因此改变字号意味着写回整个内容字符串,这意味着你必须了解你要替换的标记结构。

渲染器对你的 HTML 究竟做了什么

文本元素的content是一个 HTML 字符串,而该页面的 CSS reset 抹掉了大多数标签语义。以下四个后果决定你如何书写富文本:

  • <ul>/<ol>不渲染项目符号。样式表的 reset 剥离了list-style和缩进,而把它放回来的规则只作用于浏览器编辑器——不作用于课堂播放。以<ul><li>…</li></ul>发送的列表最终会呈现为裸的、无缩进的行。要像课件本身那样写项目符号:每项一个<p>,符号写在文本里,例如<p style="font-size:18px;">• 第一点</p>
  • <h1><h6>是无效的。reset 对它们设置了font-size: inheritfont-weight: inherit,所以标题标签只是多几个字符的<p>。字号和字重来自内联的font-size<strong>,它们才真正生效。
  • 堆叠的<p>标签之间没有间隙——只有 line-height 分隔它们。如果两行之间需要空气,就提高元素的lineHeight或把它们拆成两个元素;不要指望空<p>(它的高度仍然要占一个表格行)。
  • 纯文本中的换行不是换行。纯文本会被包进单个<p>,换行折叠成空格。多行内容必须以真正的<p>标签到达,每行一个。

任何看起来像标签的内容都会被当作标记透传而不是转义,所以包含<后跟字母的文本(如if x<y> then)会被当作 HTML 读取并损坏——请以转义实体发送。

受支持的内联样式font-sizecolortext-alignline-heightfont-weightfont-family受支持的标签<p><span><strong>/<b><em>/<i><u>。除此之外都不是契约。

在源码层面,这一行为与结构校验器的边界完全对应:正如 slide-dsl 所述,写入路径只检查 DSL结构schema(字段名、类型、必填字段、封闭对象),不检查标签、CSS、颜色格式、长度或几何边界——"guard rail catches shape, not meaning",本技能就是意义的来源。

对比度是一对,而不是一种颜色

命名这对组合

在改任何颜色之前,先说出将要叠放在一起的两样东西。文字是否可读是相对于它的直接背景而言的:位于形状上时是形状的fill;文本元素自身有fill时是它自己的fill;否则是页面背景。

哪个字段承载哪种颜色

墨色字段
文本元素字形defaultColor,或内容中的内联color
文本元素背景fill(未设置 = 页面透出)
形状标签字形text.defaultColor
形状主体fill
公式latex 元素上的color
线条 / 箭头line 元素上的color

一次颜色修改就是对渲染器实际读取的那个字段的一次写入——文本用defaultColor或内容里的内联color,形状标签用text.defaultColor,latex 或 line 元素用color。先读源 JSON 并保留其内联 span。文本元素上的opacity会同时淡化字形填充,因为它作用于整个盒子——它不是给活文字后面柔化背景的方式。

对比度目标与校准点

正文文字目标是≥ 4.5:1,24px 及以上的标题目标是≥ 3:1。本课件调色板有两个校准点:白色上的#333333约为 12:1,任何地方都安全;白色上的强调色#5b9bd5约为 3:1,能通过 32px 标题但通不过 16px 正文。这里始终有效的模式是浅色调填充配深色同色调文字——如#1e40af#dbeafe#166534#dcfce7#92400e#fef3c7,每组约为 6-7:1。只改这样一对中的一半会破坏它;要么都改,要么都不改。

形状上的文字是一个对象

卡片内的标签不是独立元素——它的盒子是从形状派生出来的:

text.width = shape.width - 40 (每边 20px 内边距) text.height = 一个表格值 ≤ shape.height - 40 text.left = shape.left + (shape.width - text.width) / 2 text.top = shape.top + (shape.height - text.height) / 2

中心点应在2px 内一致。所以移动形状总是两次编辑——先移动形状,再重新推导标签——而升到表格下一行的文字高度可能迫使卡片随之增高。经典的错误修复是给标签赋予形状自己的left/top,这会把它钉在左上角而不是居中。在底层,形状标签由ShapeText结构承载(contentdefaultFontNamedefaultColoralign均必填,见 element-schema.ts),水平对齐来自 HTML 内的text-align,垂直锚点才是align——这正是上面派生公式要解决的问题。

节奏,用精确数字

并行的事物用完全相同的值,而不是接近的值:一行三张卡片共享一个width、一个height、一个top和一个间距。人眼能分辨 5px 的差异,所以近似是可见的。当你删除一行中的一张卡片或向它复制一张时,要按这一行自身的算术重新分布所有卡片,而不是把新来者放到邻居旁边。

页面构建所依据的间距标准:

  • 标题 → 副标题 30-40px;标题 → 正文 35-50px;段落块之间 20-30px;文字 ↔ 图片垂直 25-35px、水平 30-40px。
  • 多列间距 40-60px。任何被连接箭头穿过的间距需要60-80px,否则箭头会落进相邻的盒子。
  • 任何东西都不低于画布边缘 50px。

从清单诊断密度

盒子会告诉你真相,无需渲染:把内容元素按top排序,读间距。拥挤的页面表现为间距低于约 20px、底边缘接近 512;空旷的页面表现为一个簇和它下方 150px 的死空间。修复拥挤靠删词和合并元素,而不是把字号降到阶梯以下——正文降到 12px 的页面就是内容太多的页面。修复空旷靠把类型升一级并垂直重新居中这个块,而不是加填充物。

一种内容,一种元素

页面上有十种元素类型,它们不可互换。搞错这一点是导致幻灯片上渲染出字面源码的失败。

  • 任何数学都是 latex 元素。文本元素或表格单元格里的 LaTeX 语法会渲染为原始字符串——学习者会看到\frac{a}{b}。小的也一样(x^2a/b)。
  • latex 元素的渲染形式被缓存。把新源码写入该元素的latex,服务器会重新渲染渲染器实际绘制的缓存html。用预览验证结果。这一机制在仓库中有明确的实现证据:apply.ts 会在 patch 改变某元素latex后调用renderLatexElementHtml(element.latex)重新生成html(渲染失败则删除html),除此之外文档中没有任何内容被触碰——这正是 slide-dsl 所称"整个写入路径中唯一的自动重写"。
  • 表格单元格是纯文本。没有公式,没有标记。
  • 代码元素接受纯文本行,按换行拆分,渲染为固定的浅色卡片,带自己的边框和标题栏——它不能被主题化成深色页面。默认字号 14px,高度必须覆盖 32px 的头部加每一行。
  • line 元素的width是描边粗细,不是长度。长度来自start/end。保持描边在 2-4(绝不超过 6):箭头是width × 3宽,所以width: 60会画出 180px 的箭头。
  • 图片保持宽高比。同时改变widthheight;写新src不会触碰盒子,所以不同形状的图片需要重新推导盒子。

派生元素跟随其锚点

下划线、分隔线和高亮条都是形状,其几何从它们装饰的文字计算而来。移动或缩放文字,它们不会跟随——要重新计算:

  • 标题下划线left = text.left + 10width = text.width - 20top = text.top + text.height + 8..12height = 2..4
  • 章节分隔线width700-900,height1-2,上下留 25-35px 的净空。
  • 高亮条left = text.left - 15top = text.top + 0.1 × text.heightheight = 0.8 × text.heightwidth3-6。

一条孤零零漂在被移动文字旁边的线,是粗心修补最显眼的标志之一。

层级就是数组顺序

元素按数组顺序绘制,靠后的在上。背景形状必须排在承载它的文字之前。当某物被另一物遮住时,修复方式是按你想要的顺序重写元素数组——绝不移动盒子来逃避重叠,也绝不删除背景层。在 JSON Pointer 写入模型中,这是唯一没有叶子可寻址的变更:你需要整体写入/content/canvas/elements,把所有元素原样带回并重新排序,id 集合和每个 id→类型配对必须原样返回(见 slide-dsl 的 restacking 规则)。

修补之后:检查清单

只检查你动过的元素,检查这些项:

  1. 在边距内——left/top≥ 50,右边缘和底边缘 ≤ 950 / 512.5。
  2. 高度是内容中最大字号对应的表格值,且最长行低于characters_per_line的 75%。
  3. 每个你改过的颜色仍与它背后的东西构成可读的一对
  4. 形状上的文字对仍在 2px 内居中;并行元素仍共享精确值。
  5. 任何锚定在你移动过的内容上的装饰形状已随之移动
  6. 文本或表格内容中没有 LaTeX,也没有原始标记
  7. 文字读起来仍像幻灯片——关键词和短语,每行约 20 个词或 30 个汉字以内,没有口语化的完整句子,也没有以教师名字或角色署名的文字。想被朗读的散文属于该页的旁白(narration),不属于页面本身。

在可用的地方,把预览花在列表无法定夺的变更上:公式、密度判断、或你怀疑溢出的文字。

本技能在整个技能栈中的位置

本技能明确声明自己不是一个独立流程,而是page-clonepro-editing的评判基准:

  • slide-dsl是位于本技能之下的字段参考——每种元素类型的字段、哪个承载文字、什么值合法、渲染器对每个字段真正做什么。它说你可以写什么;本技能说什么值得写。需要字段名或合法值时加载它。
  • page-clone是基于现有页面构建新页面的流程。它决定哪些元素是内容、哪些是骨架;本技能决定你放进内容的文字是否做得好。
  • pro-editing是修订已存在页面的流程——该用哪个操作、多小的粒度、如何验证。本技能就是那个操作落地之后"做得好"的定义。
  • stage-design仍然掌管整个课堂(stage)的构建。

硬性规则(Hard Rules)

  • 任何东西永远不进入距边缘 50px 以内——重新计算数字,不要微调。
  • 高度来自表格,每次文字变更后重新计算。
  • 颜色是一对。绝不要单独改文字/背景对的一侧;修补上面列出的渲染器持有的颜色字段。
  • 真实结构用真实 HTML——每行一个<p>、用符号字符而不是<ul>、用内联font-size而不是标题标签。
  • 公式是 latex 元素,且其渲染形态不跟随字符串修补——替换,而不是修补。
  • 并行元素共享精确数字——从清单里复制它们。
  • 先删词,再撑盒子。只能以 12px 容纳的页面就是内容太多的页面。

相关阅读

  • 深入阅读字段手册 slide-dsl,掌握十种元素类型逐字段的合法值、优先级规则与 PPTX 导出的读写差异。
  • 查看克隆页面的完整操作序列 page-clone 与修订页面的最小编辑纪律 pro-editing。
  • 在源码中验证结构 schema:element-schema.ts(画布viewportSize/viewportRatioShapeTextdefaultColor/lineHeight/paragraphSpace等字段约束);验证 latex 重渲染机制:apply.ts。
  • 如需了解页面如何在播放器与预览两种渲染器中呈现,参考 slide-dsl 的"Two renderers paint your page"章节——本技能的许多规则(如列表无符号、paragraphSpace在播放中失效)正是这两种渲染器差异的直接推论。

【免费下载链接】OpenMAICOpen Multi-Agent Interactive Classroom — Get an immersive, multi-agent learning experience in just one click项目地址: https://gitcode.com/GitHub_Trending/op/OpenMAIC

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 6:16:58

FPGA实现100G UDP协议栈移植、上板测试与调优实战

最近在做高速数据采集的项目&#xff0c;数据量上来之后10G网口成了瓶颈&#xff0c;于是开始折腾100G UDP传输方案。正好发现GitHub上有开源的100G UDP协议栈&#xff0c;就拿来移植到自己的FPGA板卡上做了一轮完整的上板测试。整个过程中踩了不少坑&#xff0c;也梳理清楚了很…

作者头像 李华
网站建设 2026/9/10 6:13:15

Python第五次作业实战:学生信息管理系统开发详解

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/10 6:11:50

四款爆火开发者工具实测:AI图像生成、架构治理与终端AI编程

这周的GitHub趋势榜很有意思&#xff0c;四个方向几乎代表了当下开发者工具圈的四大热点&#xff1a;AI图像生成资源库登顶热度第一、架构可视化工具开始卷"可验证"、OpenAI的Codex走向终端本地化、Anthropic的Claude Code成了编程辅助的当红炸子鸡。如果你最近也在追…

作者头像 李华
网站建设 2026/9/10 6:10:29

用npx装一个AI技能包:ponytail让Agent秒变专业造型师

在AI Agent满天飞的当下&#xff0c;真正能落地解决日常问题的技能包却不多见。直到我尝试了 npx skill add dietrichgebert/ponytail 这条命令&#xff0c;才发现原来“造型设计”这种看似凭感觉的领域&#xff0c;也能被拆解成一套严谨的AI技能流程。这篇文章就围绕ponytai…

作者头像 李华