refactor(editor): wrap multi-board templates onto rows
Every multi-board template laid its boards out in one long horizontal strip, so opening a seven-board carousel dropped the user onto a canvas they had to pan sideways to survey. Three per row matches the deck kit, and the extra row gap is deliberate: the canvas draws frame names at a fixed screen-space offset, so at fit-to-screen zoom a plain column gap lets the second row's labels sit on top of the boards above them. knowledge-carousel additionally takes hard line breaks in two body paragraphs. Greedy wrapping put a comma at the start of a line and left a lone full stop on the last one, which are both CJK line-break faults; authored breaks remove the engine's freedom to reintroduce them. Claude-Session: https://claude.ai/code/session_01FqKQqNj8exYwopGDpYUU7x
|
|
@ -3011,8 +3011,8 @@
|
|||
]
|
||||
}
|
||||
],
|
||||
"x": 3600,
|
||||
"y": 0
|
||||
"x": 0,
|
||||
"y": 1800
|
||||
},
|
||||
{
|
||||
"type": "frame",
|
||||
|
|
@ -3265,8 +3265,8 @@
|
|||
]
|
||||
}
|
||||
],
|
||||
"x": 4800,
|
||||
"y": 0
|
||||
"x": 1200,
|
||||
"y": 1800
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1987,8 +1987,8 @@
|
|||
]
|
||||
}
|
||||
],
|
||||
"x": 3600,
|
||||
"y": 0
|
||||
"x": 0,
|
||||
"y": 1800
|
||||
},
|
||||
{
|
||||
"type": "frame",
|
||||
|
|
@ -2269,8 +2269,8 @@
|
|||
]
|
||||
}
|
||||
],
|
||||
"x": 4800,
|
||||
"y": 0
|
||||
"x": 1200,
|
||||
"y": 1800
|
||||
},
|
||||
{
|
||||
"type": "frame",
|
||||
|
|
@ -2792,8 +2792,8 @@
|
|||
]
|
||||
}
|
||||
],
|
||||
"x": 6000,
|
||||
"y": 0
|
||||
"x": 2400,
|
||||
"y": 1800
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -720,7 +720,7 @@
|
|||
"type": "text",
|
||||
"id": "t37",
|
||||
"name": "论点阐述",
|
||||
"content": "轮播的优势是节奏,不是容量。一页塞两个论点,读者一个都记不住;拆成两页,两个都记得住。多拆一页的成本几乎为零,真正贵的是读者的耐心。",
|
||||
"content": "轮播的优势是节奏,不是容量。一页塞两个论点,\n读者一个都记不住;拆成两页,两个都记得住。\n多拆一页的成本几乎为零,真正贵的是读者的耐心。",
|
||||
"fontFamily": "Noto Sans SC",
|
||||
"fontSize": 34,
|
||||
"fontWeight": 400,
|
||||
|
|
@ -935,7 +935,7 @@
|
|||
"type": "text",
|
||||
"id": "t48",
|
||||
"name": "论点阐述",
|
||||
"content": "想让一句话被看见,办法不是把它放大,而是把它周围清空。留白足够时,30px 的字也比挤成一堆的 60px 更醒目。",
|
||||
"content": "想让一句话被看见,办法不是把它放大,\n而是把它周围清空。留白足够时,\n30px 的字也比挤成一堆的 60px 更醒目。",
|
||||
"fontFamily": "Noto Sans SC",
|
||||
"fontSize": 34,
|
||||
"fontWeight": 400,
|
||||
|
|
@ -1058,8 +1058,8 @@
|
|||
]
|
||||
}
|
||||
],
|
||||
"x": 3600,
|
||||
"y": 0
|
||||
"x": 0,
|
||||
"y": 1800
|
||||
},
|
||||
{
|
||||
"type": "frame",
|
||||
|
|
@ -1633,8 +1633,8 @@
|
|||
]
|
||||
}
|
||||
],
|
||||
"x": 4800,
|
||||
"y": 0
|
||||
"x": 1200,
|
||||
"y": 1800
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1894,8 +1894,8 @@
|
|||
]
|
||||
}
|
||||
],
|
||||
"x": 3600,
|
||||
"y": 0
|
||||
"x": 0,
|
||||
"y": 1800
|
||||
},
|
||||
{
|
||||
"type": "frame",
|
||||
|
|
@ -2183,8 +2183,8 @@
|
|||
]
|
||||
}
|
||||
],
|
||||
"x": 4800,
|
||||
"y": 0
|
||||
"x": 1200,
|
||||
"y": 1800
|
||||
},
|
||||
{
|
||||
"type": "frame",
|
||||
|
|
@ -2485,8 +2485,8 @@
|
|||
]
|
||||
}
|
||||
],
|
||||
"x": 6000,
|
||||
"y": 0
|
||||
"x": 2400,
|
||||
"y": 1800
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1975,8 +1975,8 @@
|
|||
]
|
||||
}
|
||||
],
|
||||
"x": 3600,
|
||||
"y": 0
|
||||
"x": 0,
|
||||
"y": 1800
|
||||
},
|
||||
{
|
||||
"type": "frame",
|
||||
|
|
@ -2551,8 +2551,8 @@
|
|||
]
|
||||
}
|
||||
],
|
||||
"x": 4800,
|
||||
"y": 0
|
||||
"x": 1200,
|
||||
"y": 1800
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1844,8 +1844,8 @@
|
|||
]
|
||||
}
|
||||
],
|
||||
"x": 3600,
|
||||
"y": 0
|
||||
"x": 0,
|
||||
"y": 1800
|
||||
},
|
||||
{
|
||||
"type": "frame",
|
||||
|
|
@ -2289,8 +2289,8 @@
|
|||
]
|
||||
}
|
||||
],
|
||||
"x": 4800,
|
||||
"y": 0
|
||||
"x": 1200,
|
||||
"y": 1800
|
||||
},
|
||||
{
|
||||
"type": "frame",
|
||||
|
|
@ -2561,8 +2561,8 @@
|
|||
]
|
||||
}
|
||||
],
|
||||
"x": 6000,
|
||||
"y": 0
|
||||
"x": 2400,
|
||||
"y": 1800
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2249,8 +2249,8 @@
|
|||
]
|
||||
}
|
||||
],
|
||||
"x": 3600,
|
||||
"y": 0
|
||||
"x": 0,
|
||||
"y": 1710
|
||||
},
|
||||
{
|
||||
"type": "frame",
|
||||
|
|
@ -2785,8 +2785,8 @@
|
|||
]
|
||||
}
|
||||
],
|
||||
"x": 4800,
|
||||
"y": 0
|
||||
"x": 1200,
|
||||
"y": 1710
|
||||
},
|
||||
{
|
||||
"type": "frame",
|
||||
|
|
@ -3233,8 +3233,8 @@
|
|||
]
|
||||
}
|
||||
],
|
||||
"x": 6000,
|
||||
"y": 0
|
||||
"x": 2400,
|
||||
"y": 1710
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2021,8 +2021,8 @@
|
|||
]
|
||||
}
|
||||
],
|
||||
"x": 3600,
|
||||
"y": 0
|
||||
"x": 0,
|
||||
"y": 1800
|
||||
},
|
||||
{
|
||||
"type": "frame",
|
||||
|
|
@ -2455,8 +2455,8 @@
|
|||
]
|
||||
}
|
||||
],
|
||||
"x": 4800,
|
||||
"y": 0
|
||||
"x": 1200,
|
||||
"y": 1800
|
||||
},
|
||||
{
|
||||
"type": "frame",
|
||||
|
|
@ -2905,8 +2905,8 @@
|
|||
]
|
||||
}
|
||||
],
|
||||
"x": 6000,
|
||||
"y": 0
|
||||
"x": 2400,
|
||||
"y": 1800
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1562,8 +1562,8 @@
|
|||
]
|
||||
}
|
||||
],
|
||||
"x": 3600,
|
||||
"y": 0
|
||||
"x": 0,
|
||||
"y": 1800
|
||||
},
|
||||
{
|
||||
"type": "frame",
|
||||
|
|
@ -2245,8 +2245,8 @@
|
|||
]
|
||||
}
|
||||
],
|
||||
"x": 4800,
|
||||
"y": 0
|
||||
"x": 1200,
|
||||
"y": 1800
|
||||
},
|
||||
{
|
||||
"type": "frame",
|
||||
|
|
@ -2519,8 +2519,8 @@
|
|||
]
|
||||
}
|
||||
],
|
||||
"x": 6000,
|
||||
"y": 0
|
||||
"x": 2400,
|
||||
"y": 1800
|
||||
},
|
||||
{
|
||||
"type": "frame",
|
||||
|
|
@ -2807,8 +2807,8 @@
|
|||
]
|
||||
}
|
||||
],
|
||||
"x": 7200,
|
||||
"y": 0
|
||||
"x": 0,
|
||||
"y": 3600
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3657,8 +3657,8 @@
|
|||
]
|
||||
}
|
||||
],
|
||||
"x": 3600,
|
||||
"y": 0
|
||||
"x": 0,
|
||||
"y": 1800
|
||||
},
|
||||
{
|
||||
"type": "frame",
|
||||
|
|
@ -4363,8 +4363,8 @@
|
|||
]
|
||||
}
|
||||
],
|
||||
"x": 4800,
|
||||
"y": 0
|
||||
"x": 1200,
|
||||
"y": 1800
|
||||
},
|
||||
{
|
||||
"type": "frame",
|
||||
|
|
@ -5328,8 +5328,8 @@
|
|||
]
|
||||
}
|
||||
],
|
||||
"x": 6000,
|
||||
"y": 0
|
||||
"x": 2400,
|
||||
"y": 1800
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1950,8 +1950,8 @@
|
|||
]
|
||||
}
|
||||
],
|
||||
"x": 3600,
|
||||
"y": 0
|
||||
"x": 0,
|
||||
"y": 1800
|
||||
},
|
||||
{
|
||||
"type": "frame",
|
||||
|
|
@ -2772,8 +2772,8 @@
|
|||
]
|
||||
}
|
||||
],
|
||||
"x": 4800,
|
||||
"y": 0
|
||||
"x": 1200,
|
||||
"y": 1800
|
||||
},
|
||||
{
|
||||
"type": "frame",
|
||||
|
|
@ -3423,8 +3423,8 @@
|
|||
]
|
||||
}
|
||||
],
|
||||
"x": 6000,
|
||||
"y": 0
|
||||
"x": 2400,
|
||||
"y": 1800
|
||||
},
|
||||
{
|
||||
"type": "frame",
|
||||
|
|
@ -3745,8 +3745,8 @@
|
|||
]
|
||||
}
|
||||
],
|
||||
"x": 7200,
|
||||
"y": 0
|
||||
"x": 0,
|
||||
"y": 3600
|
||||
},
|
||||
{
|
||||
"type": "frame",
|
||||
|
|
@ -4360,8 +4360,8 @@
|
|||
]
|
||||
}
|
||||
],
|
||||
"x": 8400,
|
||||
"y": 0
|
||||
"x": 1200,
|
||||
"y": 3600
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 30 KiB |
|
|
@ -8,6 +8,13 @@ from oplib import (Ids, frame, rect, text, solid, stroke, write_doc,
|
|||
PLACEHOLDER_TITLE, PLACEHOLDER_SPEC)
|
||||
|
||||
W, H, GAP = 1080, 1440, 120
|
||||
|
||||
# 3 板一行 —— 与 deck 体系(deckkit.BOARDS_PER_ROW)同一约定:多板模板在画布上
|
||||
# 分行铺开,而不是拖成一长排。行间距比列间距多 240 不是手滑:画布在帧上方以
|
||||
# **屏幕空间**固定偏移画帧名,缩到能整屏看时 120 文档像素只剩十几个屏幕像素,
|
||||
# 第二行的帧名会压到上一行的板上。
|
||||
BOARDS_PER_ROW = 3
|
||||
ROW_GAP = GAP + 240
|
||||
PAD_X, PAD_Y = 72, 88
|
||||
|
||||
VARS = color_vars({
|
||||
|
|
@ -236,8 +243,8 @@ def build():
|
|||
"不要把字塞满整张图。",),
|
||||
cta_page()]
|
||||
for i, p in enumerate(pages):
|
||||
p["x"] = i * (W + GAP)
|
||||
p["y"] = 0
|
||||
p["x"] = (i % BOARDS_PER_ROW) * (W + GAP)
|
||||
p["y"] = (i // BOARDS_PER_ROW) * (H + ROW_GAP)
|
||||
dst = sys.argv[1]
|
||||
write_doc(dst, VARS, pages, "截图教程卡 · 小红书 3:4 模板")
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,13 @@ sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
|||
from oplib import Ids, frame, rect, path, text, solid, stroke, write_doc, color_vars
|
||||
|
||||
W, H, GAP = 1080, 1440, 120
|
||||
|
||||
# 3 板一行 —— 与 deck 体系(deckkit.BOARDS_PER_ROW)同一约定:多板模板在画布上
|
||||
# 分行铺开,而不是拖成一长排。行间距比列间距多 240 不是手滑:画布在帧上方以
|
||||
# **屏幕空间**固定偏移画帧名,缩到能整屏看时 120 文档像素只剩十几个屏幕像素,
|
||||
# 第二行的帧名会压到上一行的板上。
|
||||
BOARDS_PER_ROW = 3
|
||||
ROW_GAP = GAP + 240
|
||||
PAD_X, PAD_Y = 72, 88
|
||||
|
||||
VARS = color_vars({
|
||||
|
|
@ -19,18 +26,32 @@ VARS = color_vars({
|
|||
|
||||
ids = Ids()
|
||||
|
||||
# 论点阐述的正文在 936px 宽、34px 字号下每行放得下 27 个汉字(936/34)。交给
|
||||
# 引擎贪心折行时,第 2、3 条的断点正好落在标点前,折出「,真正贵的是…」这种
|
||||
# 行首标点、和「。」独占末行的孤字——中文行首禁则的两类事故。
|
||||
#
|
||||
# 断点写死在标点**之后**,每段 ≤27 字:这样每一行都是作者断的硬行,引擎不再
|
||||
# 有折行的余地,两类事故按构造消失(检测器的孤字/行首禁则只对引擎折出的软行
|
||||
# 成立)。分段按**渲染宽度**挑而不是字数——第 3 条里的 30px/60px 是半角,24 字
|
||||
# 那行实际只有 18.5em,所以 18/15/24 字的分法反而是三行最齐的。
|
||||
#
|
||||
# 第 1 条没有写死断点:它引擎折出来本就干净,而它唯一可行的三段分法首行要占
|
||||
# 满 27.0em / 27.53em 的行宽,把这条冻成硬行等于交出引擎在字体度量有出入时重
|
||||
# 折的余地,不值得。
|
||||
POINTS = [
|
||||
("先有结论,再有论据",
|
||||
"读者划到你这一页,只会给你一眼的时间。把结论放进标题,把论据留给正文,"
|
||||
"不要让人读完三行才知道你想说什么。你以为在铺垫,读者以为你没重点。",
|
||||
"标题写结论,正文写理由。"),
|
||||
("一页只讲一个论点",
|
||||
"轮播的优势是节奏,不是容量。一页塞两个论点,读者一个都记不住;"
|
||||
"拆成两页,两个都记得住。多拆一页的成本几乎为零,真正贵的是读者的耐心。",
|
||||
"轮播的优势是节奏,不是容量。一页塞两个论点,\n"
|
||||
"读者一个都记不住;拆成两页,两个都记得住。\n"
|
||||
"多拆一页的成本几乎为零,真正贵的是读者的耐心。",
|
||||
"讲不完,就拆下一页。"),
|
||||
("留白比字号更重要",
|
||||
"想让一句话被看见,办法不是把它放大,而是把它周围清空。"
|
||||
"留白足够时,30px 的字也比挤成一堆的 60px 更醒目。",
|
||||
"想让一句话被看见,办法不是把它放大,\n"
|
||||
"而是把它周围清空。留白足够时,\n"
|
||||
"30px 的字也比挤成一堆的 60px 更醒目。",
|
||||
"想突出,先清空周围。"),
|
||||
]
|
||||
|
||||
|
|
@ -194,8 +215,8 @@ def build():
|
|||
pages = [cover(), point_page(1), point_page(2), point_page(3),
|
||||
summary_page()]
|
||||
for i, p in enumerate(pages):
|
||||
p["x"] = i * (W + GAP)
|
||||
p["y"] = 0
|
||||
p["x"] = (i % BOARDS_PER_ROW) * (W + GAP)
|
||||
p["y"] = (i // BOARDS_PER_ROW) * (H + ROW_GAP)
|
||||
write_doc(sys.argv[1], VARS, pages, "知识轮播 · 小红书 3:4 模板")
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -102,6 +102,13 @@ CJK = "Noto Sans SC"
|
|||
NUM = "Inter"
|
||||
|
||||
W, H, GAP = 1080, 1440, 120
|
||||
|
||||
# 3 板一行 —— 与 deck 体系(deckkit.BOARDS_PER_ROW)同一约定:多板模板在画布上
|
||||
# 分行铺开,而不是拖成一长排。行间距比列间距多 240 不是手滑:画布在帧上方以
|
||||
# **屏幕空间**固定偏移画帧名,缩到能整屏看时 120 文档像素只剩十几个屏幕像素,
|
||||
# 第二行的帧名会压到上一行的板上。
|
||||
BOARDS_PER_ROW = 3
|
||||
ROW_GAP = GAP + 240
|
||||
EDGE = 80
|
||||
TOP, BOT = 96, 300 # 下边距被山形吃掉,见母版规则 2
|
||||
INNER = W - EDGE * 2
|
||||
|
|
@ -235,8 +242,8 @@ def board(page, name, main, extra_decor=None):
|
|||
fill=solid("$c-bg"), clipContent=True)
|
||||
# 装饰层是最后一个孩子 —— jian 里 index 0 最上,写反了山会盖住正文。
|
||||
shell["children"] = [content, decor]
|
||||
shell["x"] = (page - 1) * (W + GAP)
|
||||
shell["y"] = 0
|
||||
shell["x"] = ((page - 1) % BOARDS_PER_ROW) * (W + GAP)
|
||||
shell["y"] = ((page - 1) // BOARDS_PER_ROW) * (H + ROW_GAP)
|
||||
return shell
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -106,6 +106,13 @@ CJK = "Noto Sans SC"
|
|||
NUM = "DM Mono"
|
||||
|
||||
W, H, GAP = 1080, 1440, 120
|
||||
|
||||
# 3 板一行 —— 与 deck 体系(deckkit.BOARDS_PER_ROW)同一约定:多板模板在画布上
|
||||
# 分行铺开,而不是拖成一长排。行间距比列间距多 240 不是手滑:画布在帧上方以
|
||||
# **屏幕空间**固定偏移画帧名,缩到能整屏看时 120 文档像素只剩十几个屏幕像素,
|
||||
# 第二行的帧名会压到上一行的板上。
|
||||
BOARDS_PER_ROW = 3
|
||||
ROW_GAP = GAP + 240
|
||||
EDGE = 80
|
||||
TOP, BOT = 96, 128
|
||||
INNER = W - EDGE * 2
|
||||
|
|
@ -201,8 +208,8 @@ def board(page, name, label, main, source):
|
|||
shell = frame(ids, f"{page:02d} {name}", width=W, height=H,
|
||||
layout="vertical", fill=solid("$c-bg"), clipContent=True)
|
||||
shell["children"] = [content]
|
||||
shell["x"] = (page - 1) * (W + GAP)
|
||||
shell["y"] = 0
|
||||
shell["x"] = ((page - 1) % BOARDS_PER_ROW) * (W + GAP)
|
||||
shell["y"] = ((page - 1) // BOARDS_PER_ROW) * (H + ROW_GAP)
|
||||
return shell
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -104,6 +104,13 @@ CJK = "Noto Sans SC"
|
|||
NUM = "Inter"
|
||||
|
||||
W, H, GAP = 1080, 1440, 120
|
||||
|
||||
# 3 板一行 —— 与 deck 体系(deckkit.BOARDS_PER_ROW)同一约定:多板模板在画布上
|
||||
# 分行铺开,而不是拖成一长排。行间距比列间距多 240 不是手滑:画布在帧上方以
|
||||
# **屏幕空间**固定偏移画帧名,缩到能整屏看时 120 文档像素只剩十几个屏幕像素,
|
||||
# 第二行的帧名会压到上一行的板上。
|
||||
BOARDS_PER_ROW = 3
|
||||
ROW_GAP = GAP + 240
|
||||
EDGE = 80
|
||||
TOP, BOT = 96, 128
|
||||
INNER = W - EDGE * 2 # 920,12 列 × 62 + 11 沟槽 × 16
|
||||
|
|
@ -209,8 +216,8 @@ def board(page, name, main, note, decor=None):
|
|||
content["children"] = [header(page), main, footer(note)]
|
||||
shell = stack(ids, f"{page:02d} {name}", content, decor or [],
|
||||
width=W, height=H, fill=solid("$c-bg"))
|
||||
shell["x"] = (page - 1) * (W + GAP)
|
||||
shell["y"] = 0
|
||||
shell["x"] = ((page - 1) % BOARDS_PER_ROW) * (W + GAP)
|
||||
shell["y"] = ((page - 1) // BOARDS_PER_ROW) * (H + ROW_GAP)
|
||||
return shell
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -105,6 +105,13 @@ CJK = "Noto Sans SC"
|
|||
NUM = "Inter"
|
||||
|
||||
W, H, GAP = 1080, 1440, 120
|
||||
|
||||
# 3 板一行 —— 与 deck 体系(deckkit.BOARDS_PER_ROW)同一约定:多板模板在画布上
|
||||
# 分行铺开,而不是拖成一长排。行间距比列间距多 240 不是手滑:画布在帧上方以
|
||||
# **屏幕空间**固定偏移画帧名,缩到能整屏看时 120 文档像素只剩十几个屏幕像素,
|
||||
# 第二行的帧名会压到上一行的板上。
|
||||
BOARDS_PER_ROW = 3
|
||||
ROW_GAP = GAP + 240
|
||||
EDGE = 80
|
||||
TOP, BOT = 96, 128
|
||||
INNER = W - EDGE * 2
|
||||
|
|
@ -252,8 +259,8 @@ def board(page, name, main, smudge_at, tag=None):
|
|||
fill=solid("$c-bg"), clipContent=True)
|
||||
# 装饰层最后 —— jian 里 index 0 最上,写反了擦痕会糊住板书。
|
||||
shell["children"] = [content, decor]
|
||||
shell["x"] = (page - 1) * (W + GAP)
|
||||
shell["y"] = 0
|
||||
shell["x"] = ((page - 1) % BOARDS_PER_ROW) * (W + GAP)
|
||||
shell["y"] = ((page - 1) // BOARDS_PER_ROW) * (H + ROW_GAP)
|
||||
return shell
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -107,6 +107,13 @@ CJK = "Noto Sans SC"
|
|||
NUM = "Inter"
|
||||
|
||||
W, H, GAP = 1080, 1440, 120
|
||||
|
||||
# 3 板一行 —— 与 deck 体系(deckkit.BOARDS_PER_ROW)同一约定:多板模板在画布上
|
||||
# 分行铺开,而不是拖成一长排。行间距比列间距多 240 不是手滑:画布在帧上方以
|
||||
# **屏幕空间**固定偏移画帧名,缩到能整屏看时 120 文档像素只剩十几个屏幕像素,
|
||||
# 第二行的帧名会压到上一行的板上。
|
||||
BOARDS_PER_ROW = 3
|
||||
ROW_GAP = GAP + 240
|
||||
EDGE = 80
|
||||
TOP, BOT = 96, 128
|
||||
INNER = W - EDGE * 2
|
||||
|
|
@ -214,8 +221,8 @@ def board(page, name, main, stage, decor=None):
|
|||
shell = stack(ids, f"{page:02d} {name}", content,
|
||||
[rain_reflection()] + (decor or []),
|
||||
width=W, height=H, fill=solid("$c-bg"))
|
||||
shell["x"] = (page - 1) * (W + GAP)
|
||||
shell["y"] = 0
|
||||
shell["x"] = ((page - 1) % BOARDS_PER_ROW) * (W + GAP)
|
||||
shell["y"] = ((page - 1) // BOARDS_PER_ROW) * (H + ROW_GAP)
|
||||
return shell
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -107,6 +107,13 @@ CJK = "Noto Sans SC"
|
|||
NUM = "Inter"
|
||||
|
||||
W, H, GAP = 1080, 1440, 120
|
||||
|
||||
# 3 板一行 —— 与 deck 体系(deckkit.BOARDS_PER_ROW)同一约定:多板模板在画布上
|
||||
# 分行铺开,而不是拖成一长排。行间距比列间距多 240 不是手滑:画布在帧上方以
|
||||
# **屏幕空间**固定偏移画帧名,缩到能整屏看时 120 文档像素只剩十几个屏幕像素,
|
||||
# 第二行的帧名会压到上一行的板上。
|
||||
BOARDS_PER_ROW = 3
|
||||
ROW_GAP = GAP + 240
|
||||
EDGE = 80
|
||||
MARGIN_X = 112 # 页边红线的位置 = 1 个列宽
|
||||
TEXT_EDGE = 152 # 正文左界,留出红线的呼吸
|
||||
|
|
@ -232,8 +239,8 @@ def board(page, name, main, note):
|
|||
shell = frame(ids, f"{page:02d} {name}", width=W, height=H, layout="none",
|
||||
fill=solid("$c-bg"), clipContent=True)
|
||||
shell["children"] = [content, paper]
|
||||
shell["x"] = (page - 1) * (W + GAP)
|
||||
shell["y"] = 0
|
||||
shell["x"] = ((page - 1) % BOARDS_PER_ROW) * (W + GAP)
|
||||
shell["y"] = ((page - 1) // BOARDS_PER_ROW) * (H + ROW_GAP)
|
||||
return shell
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -80,6 +80,13 @@ CJK = "Noto Sans SC"
|
|||
NUM = "Inter"
|
||||
|
||||
W, H, GAP = 1080, 1440, 120
|
||||
|
||||
# 3 板一行 —— 与 deck 体系(deckkit.BOARDS_PER_ROW)同一约定:多板模板在画布上
|
||||
# 分行铺开,而不是拖成一长排。行间距比列间距多 240 不是手滑:画布在帧上方以
|
||||
# **屏幕空间**固定偏移画帧名,缩到能整屏看时 120 文档像素只剩十几个屏幕像素,
|
||||
# 第二行的帧名会压到上一行的板上。
|
||||
BOARDS_PER_ROW = 3
|
||||
ROW_GAP = GAP + 240
|
||||
EDGE = 72
|
||||
|
||||
LH_DISPLAY, LH_HEAD, LH_BODY = 1.2, 1.35, 1.7
|
||||
|
|
@ -135,7 +142,8 @@ def page(name, children, *, index, fill="$c-bg", pad_top=80):
|
|||
padding=[pad_top, EDGE, 72, EDGE], gap=PAGE_GAP,
|
||||
fill=solid(fill), clipContent=True)
|
||||
node["children"] = children
|
||||
node["x"], node["y"] = index * (W + GAP), 0
|
||||
node["x"] = (index % BOARDS_PER_ROW) * (W + GAP)
|
||||
node["y"] = (index // BOARDS_PER_ROW) * (H + ROW_GAP)
|
||||
return node
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -67,6 +67,13 @@ CJK = "Noto Sans SC"
|
|||
NUM = "Inter"
|
||||
|
||||
W, H, GAP = 1080, 1350, 120
|
||||
|
||||
# 3 板一行 —— 与 deck 体系(deckkit.BOARDS_PER_ROW)同一约定:多板模板在画布上
|
||||
# 分行铺开,而不是拖成一长排。行间距比列间距多 240 不是手滑:画布在帧上方以
|
||||
# **屏幕空间**固定偏移画帧名,缩到能整屏看时 120 文档像素只剩十几个屏幕像素,
|
||||
# 第二行的帧名会压到上一行的板上。
|
||||
BOARDS_PER_ROW = 3
|
||||
ROW_GAP = GAP + 240
|
||||
EDGE = 72
|
||||
PAGE_GAP = 46
|
||||
|
||||
|
|
@ -124,7 +131,8 @@ def page(name, children, *, index, fill="$c-bg"):
|
|||
padding=[72, EDGE], gap=PAGE_GAP, fill=solid(fill),
|
||||
clipContent=True)
|
||||
node["children"] = children
|
||||
node["x"], node["y"] = index * (W + GAP), 0
|
||||
node["x"] = (index % BOARDS_PER_ROW) * (W + GAP)
|
||||
node["y"] = (index // BOARDS_PER_ROW) * (H + ROW_GAP)
|
||||
return node
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -71,6 +71,13 @@ CJK = "Noto Sans SC"
|
|||
NUM = "Inter"
|
||||
|
||||
W, H, GAP = 1080, 1440, 120
|
||||
|
||||
# 3 板一行 —— 与 deck 体系(deckkit.BOARDS_PER_ROW)同一约定:多板模板在画布上
|
||||
# 分行铺开,而不是拖成一长排。行间距比列间距多 240 不是手滑:画布在帧上方以
|
||||
# **屏幕空间**固定偏移画帧名,缩到能整屏看时 120 文档像素只剩十几个屏幕像素,
|
||||
# 第二行的帧名会压到上一行的板上。
|
||||
BOARDS_PER_ROW = 3
|
||||
ROW_GAP = GAP + 240
|
||||
EDGE = 72
|
||||
PAGE_GAP = 34
|
||||
|
||||
|
|
@ -131,7 +138,8 @@ def page(name, children, *, index):
|
|||
padding=[76, EDGE, 68, EDGE], gap=PAGE_GAP,
|
||||
fill=solid("$c-bg"), clipContent=True)
|
||||
node["children"] = children
|
||||
node["x"], node["y"] = index * (W + GAP), 0
|
||||
node["x"] = (index % BOARDS_PER_ROW) * (W + GAP)
|
||||
node["y"] = (index // BOARDS_PER_ROW) * (H + ROW_GAP)
|
||||
return node
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -112,6 +112,13 @@ CJK = "Noto Sans SC"
|
|||
NUM = "Inter"
|
||||
|
||||
W, H, GAP = 1080, 1440, 120
|
||||
|
||||
# 3 板一行 —— 与 deck 体系(deckkit.BOARDS_PER_ROW)同一约定:多板模板在画布上
|
||||
# 分行铺开,而不是拖成一长排。行间距比列间距多 240 不是手滑:画布在帧上方以
|
||||
# **屏幕空间**固定偏移画帧名,缩到能整屏看时 120 文档像素只剩十几个屏幕像素,
|
||||
# 第二行的帧名会压到上一行的板上。
|
||||
BOARDS_PER_ROW = 3
|
||||
ROW_GAP = GAP + 240
|
||||
EDGE = 80
|
||||
TOP, BOT = 96, 128
|
||||
INNER = W - EDGE * 2
|
||||
|
|
@ -317,8 +324,8 @@ def board(page, name, main, note, extra_decor=None):
|
|||
fill=solid("$c-bg"), clipContent=True)
|
||||
# 装饰层最后 —— jian 里 index 0 最上,写反了剥落会盖住正文。
|
||||
shell["children"] = [content, decor]
|
||||
shell["x"] = (page - 1) * (W + GAP)
|
||||
shell["y"] = 0
|
||||
shell["x"] = ((page - 1) % BOARDS_PER_ROW) * (W + GAP)
|
||||
shell["y"] = ((page - 1) // BOARDS_PER_ROW) * (H + ROW_GAP)
|
||||
return shell
|
||||
|
||||
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 177 KiB After Width: | Height: | Size: 180 KiB |
|
Before Width: | Height: | Size: 156 KiB After Width: | Height: | Size: 162 KiB |
|
Before Width: | Height: | Size: 411 KiB After Width: | Height: | Size: 443 KiB |
|
Before Width: | Height: | Size: 347 KiB After Width: | Height: | Size: 383 KiB |