skill-forge-hub 0.4.0 → 0.5.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/CHANGELOG.md +52 -0
- package/README.md +77 -22
- package/annual-report/SKILL.md +10 -3
- package/annual-report/resources/disk-and-html.md +7 -7
- package/annual-report/resources/reference.html +135 -41
- package/annual-report/user-config.md +3 -2
- package/article-to-html/SKILL.md +23 -0
- package/article-to-html/design-system.md +86 -21
- package/article-to-html/user-config.md +18 -0
- package/cli.js +71 -23
- package/daily-report/SKILL.md +10 -3
- package/daily-report/resources/disk-and-html.md +2 -2
- package/daily-report/resources/reference.html +163 -65
- package/daily-report/user-config.md +3 -2
- package/deck-stage/SKILL.md +80 -0
- package/deck-stage/package-lock.json +172 -0
- package/deck-stage/package.json +15 -0
- package/deck-stage/resources/cover-template.html +139 -0
- package/deck-stage/resources/data-schema.md +111 -0
- package/deck-stage/resources/pptx-builder.js +394 -0
- package/deck-stage/resources/usage-guide.md +20 -0
- package/deck-stage/user-config.md +26 -0
- package/magic-deck/SKILL.md +20 -11
- package/magic-deck/resources/deck-spec.md +380 -30
- package/magic-deck/resources/reference.html +1803 -82
- package/magic-deck/resources/usage-guide.md +42 -0
- package/magic-deck/user-config.md +10 -7
- package/meta-forge/SKILL.md +2 -0
- package/meta-forge/resources/forge-rules.md +1 -0
- package/package.json +16 -4
- package/prompt-pouch/SKILL.md +77 -0
- package/prompt-pouch/resources/data-format.md +67 -0
- package/prompt-pouch/resources/reference.html +2038 -0
- package/prompt-pouch/resources/usage-guide.md +32 -0
- package/prompt-pouch/user-config.md +22 -0
- package/weekly-report/SKILL.md +10 -3
- package/weekly-report/resources/disk-and-html.md +2 -2
- package/weekly-report/resources/reference.html +184 -95
- package/weekly-report/user-config.md +3 -2
|
@@ -10,34 +10,134 @@
|
|
|
10
10
|
html,body{ width:100%; height:100%; overflow:hidden;
|
|
11
11
|
font-family:ui-monospace,'SF Mono',SFMono-Regular,Menlo,Consolas,'Microsoft YaHei',monospace; }
|
|
12
12
|
button,select,input{ font-family:inherit; }
|
|
13
|
-
/* ══════════ 1.
|
|
13
|
+
/* ══════════ 1. 十六主题 CSS 变量(12 令牌 × 16 主题,默认 tech) ══════════ */
|
|
14
14
|
:root, [data-theme="tech"]{
|
|
15
|
-
--bg:#0a1929; --bg2:#071525; --panel:rgba(11,30,55,.
|
|
15
|
+
--bg:#0a1929; --bg2:#071525; --panel:rgba(11,30,55,.9); --panel-solid:#0b1e37;
|
|
16
16
|
--text:#bae6fd; --muted:#5b7fa5; --accent:#0ea5e9; --accent2:#14b8a6;
|
|
17
17
|
--border:rgba(14,165,233,.18); --glow:rgba(14,165,233,.35);
|
|
18
18
|
--title-grad:linear-gradient(90deg,#7dd3fc,#0ea5e9 45%,#818cf8);
|
|
19
19
|
--tag-bg:rgba(14,165,233,.12);
|
|
20
|
+
--card-shadow:0 1px 0 rgba(255,255,255,.05) inset,0 12px 32px rgba(1,6,16,.5),0 0 24px rgba(14,165,233,.15);
|
|
20
21
|
}
|
|
21
22
|
[data-theme="biz"]{
|
|
22
|
-
--bg:#
|
|
23
|
+
--bg:#e8ecf5; --bg2:#dde3ef; --panel:rgba(255,255,255,.97); --panel-solid:#ffffff;
|
|
23
24
|
--text:#1e293b; --muted:#64748b; --accent:#2563eb; --accent2:#0891b2;
|
|
24
25
|
--border:rgba(37,99,235,.14); --glow:rgba(37,99,235,.18);
|
|
25
26
|
--title-grad:linear-gradient(90deg,#1e40af,#2563eb 55%,#0891b2);
|
|
26
27
|
--tag-bg:rgba(37,99,235,.08);
|
|
28
|
+
--card-shadow:0 1px 2px rgba(15,23,42,.05),0 10px 28px rgba(15,23,42,.12);
|
|
27
29
|
}
|
|
28
30
|
[data-theme="mono"]{
|
|
29
|
-
--bg:#
|
|
31
|
+
--bg:#f2f2f4; --bg2:#e4e4e8; --panel:rgba(255,255,255,.98); --panel-solid:#ffffff;
|
|
30
32
|
--text:#16181d; --muted:#6b7280; --accent:#111111; --accent2:#4b5563;
|
|
31
33
|
--border:rgba(17,17,17,.14); --glow:rgba(17,17,17,.08);
|
|
32
34
|
--title-grad:linear-gradient(90deg,#111,#333 60%,#666);
|
|
33
35
|
--tag-bg:rgba(17,17,17,.06);
|
|
36
|
+
--card-shadow:0 1px 2px rgba(0,0,0,.06),0 10px 28px rgba(0,0,0,.1);
|
|
34
37
|
}
|
|
35
38
|
[data-theme="warm"]{
|
|
36
|
-
--bg:#
|
|
39
|
+
--bg:#f7ebd9; --bg2:#efe0c8; --panel:rgba(255,250,243,.97); --panel-solid:#fffaf3;
|
|
37
40
|
--text:#43301f; --muted:#8a7565; --accent:#d97706; --accent2:#ea580c;
|
|
38
41
|
--border:rgba(217,119,6,.18); --glow:rgba(217,119,6,.22);
|
|
39
42
|
--title-grad:linear-gradient(90deg,#b45309,#d97706 50%,#ea580c);
|
|
40
43
|
--tag-bg:rgba(217,119,6,.1);
|
|
44
|
+
--card-shadow:0 1px 2px rgba(120,72,24,.07),0 10px 28px rgba(120,72,24,.13);
|
|
45
|
+
}
|
|
46
|
+
[data-theme="aurora"]{ /* 极光紫(Linear 风) */
|
|
47
|
+
--bg:#0b0b10; --bg2:#08080d; --panel:rgba(30,30,46,.9); --panel-solid:#1e1e2e;
|
|
48
|
+
--text:#e8e8f0; --muted:#8a8aa3; --accent:#5e6ad2; --accent2:#9d8df2;
|
|
49
|
+
--border:rgba(94,106,210,.28); --glow:rgba(94,106,210,.4);
|
|
50
|
+
--title-grad:linear-gradient(90deg,#a8b3ff,#5e6ad2 45%,#9d8df2);
|
|
51
|
+
--tag-bg:rgba(94,106,210,.16);
|
|
52
|
+
--card-shadow:0 1px 0 rgba(255,255,255,.04) inset,0 10px 28px rgba(0,0,10,.45),0 0 20px rgba(94,106,210,.18);
|
|
53
|
+
}
|
|
54
|
+
[data-theme="dracula"]{ /* 德古拉紫(Dracula 配色) */
|
|
55
|
+
--bg:#282a36; --bg2:#21222c; --panel:rgba(48,50,64,.9); --panel-solid:#303240;
|
|
56
|
+
--text:#f8f8f2; --muted:#6272a4; --accent:#bd93f9; --accent2:#ff79c6;
|
|
57
|
+
--border:rgba(189,147,249,.28); --glow:rgba(189,147,249,.35);
|
|
58
|
+
--title-grad:linear-gradient(90deg,#ff79c6,#bd93f9 50%,#8be9fd);
|
|
59
|
+
--tag-bg:rgba(189,147,249,.15);
|
|
60
|
+
--card-shadow:0 1px 0 rgba(255,255,255,.04) inset,0 10px 28px rgba(0,0,0,.4),0 0 18px rgba(189,147,249,.15);
|
|
61
|
+
}
|
|
62
|
+
[data-theme="nord"]{ /* 北欧冰蓝(Nord 配色) */
|
|
63
|
+
--bg:#2e3440; --bg2:#272c36; --panel:rgba(59,66,82,.9); --panel-solid:#3b4252;
|
|
64
|
+
--text:#eceff4; --muted:#7e8aa0; --accent:#88c0d0; --accent2:#81a1c1;
|
|
65
|
+
--border:rgba(136,192,208,.25); --glow:rgba(136,192,208,.3);
|
|
66
|
+
--title-grad:linear-gradient(90deg,#8fbcbb,#88c0d0 45%,#81a1c1);
|
|
67
|
+
--tag-bg:rgba(136,192,208,.14);
|
|
68
|
+
--card-shadow:0 1px 0 rgba(255,255,255,.04) inset,0 10px 28px rgba(0,0,0,.4),0 0 18px rgba(136,192,208,.15);
|
|
69
|
+
}
|
|
70
|
+
[data-theme="midnight"]{ /* 东京夜色(Tokyo Night) */
|
|
71
|
+
--bg:#1a1b26; --bg2:#16161e; --panel:rgba(31,33,48,.9); --panel-solid:#1f2130;
|
|
72
|
+
--text:#c0caf5; --muted:#565f89; --accent:#7aa2f7; --accent2:#bb9af7;
|
|
73
|
+
--border:rgba(122,162,247,.25); --glow:rgba(122,162,247,.32);
|
|
74
|
+
--title-grad:linear-gradient(90deg,#7dcfff,#7aa2f7 45%,#bb9af7);
|
|
75
|
+
--tag-bg:rgba(122,162,247,.14);
|
|
76
|
+
--card-shadow:0 1px 0 rgba(255,255,255,.04) inset,0 10px 28px rgba(0,0,0,.42),0 0 18px rgba(122,162,247,.16);
|
|
77
|
+
}
|
|
78
|
+
[data-theme="matrix"]{ /* 终端荧光绿(Matrix) */
|
|
79
|
+
--bg:#0a0f0a; --bg2:#050a05; --panel:rgba(16,26,16,.9); --panel-solid:#101a10;
|
|
80
|
+
--text:#c8ffd8; --muted:#4f8a62; --accent:#00ff9c; --accent2:#3ddc84;
|
|
81
|
+
--border:rgba(0,255,156,.22); --glow:rgba(0,255,156,.32);
|
|
82
|
+
--title-grad:linear-gradient(90deg,#7dffc9,#00ff9c 50%,#3ddc84);
|
|
83
|
+
--tag-bg:rgba(0,255,156,.1);
|
|
84
|
+
--card-shadow:0 1px 0 rgba(255,255,255,.04) inset,0 10px 28px rgba(0,0,0,.45),0 0 20px rgba(0,255,156,.14);
|
|
85
|
+
}
|
|
86
|
+
[data-theme="cyber"]{ /* 赛博霓虹(Cyberpunk) */
|
|
87
|
+
--bg:#0b0518; --bg2:#070210; --panel:rgba(24,12,44,.9); --panel-solid:#180c2c;
|
|
88
|
+
--text:#e8e6ff; --muted:#6f6a9e; --accent:#ff2d78; --accent2:#00e5ff;
|
|
89
|
+
--border:rgba(255,45,120,.3); --glow:rgba(255,45,120,.4);
|
|
90
|
+
--title-grad:linear-gradient(90deg,#ff2d78,#ff7ab8 40%,#00e5ff);
|
|
91
|
+
--tag-bg:rgba(255,45,120,.14);
|
|
92
|
+
--card-shadow:0 1px 0 rgba(255,255,255,.05) inset,0 10px 28px rgba(0,0,10,.5),0 0 20px rgba(255,45,120,.18);
|
|
93
|
+
}
|
|
94
|
+
[data-theme="apple"]{ /* 苹果极简(Apple 官网) */
|
|
95
|
+
--bg:#eceef2; --bg2:#dde0e7; --panel:rgba(255,255,255,.97); --panel-solid:#ffffff;
|
|
96
|
+
--text:#1d1d1f; --muted:#6e6e73; --accent:#0071e3; --accent2:#42a5ff;
|
|
97
|
+
--border:rgba(0,113,227,.15); --glow:rgba(0,113,227,.2);
|
|
98
|
+
--title-grad:linear-gradient(90deg,#1d1d1f,#0071e3 55%,#42a5ff);
|
|
99
|
+
--tag-bg:rgba(0,113,227,.08);
|
|
100
|
+
--card-shadow:0 1px 2px rgba(0,0,0,.05),0 10px 28px rgba(0,0,0,.1);
|
|
101
|
+
}
|
|
102
|
+
[data-theme="stripe"]{ /* 条纹紫蓝(Stripe) */
|
|
103
|
+
--bg:#eef1f8; --bg2:#e2e6ee; --panel:rgba(255,255,255,.97); --panel-solid:#ffffff;
|
|
104
|
+
--text:#32325d; --muted:#6b7c93; --accent:#635bff; --accent2:#00d4ff;
|
|
105
|
+
--border:rgba(99,91,255,.2); --glow:rgba(99,91,255,.22);
|
|
106
|
+
--title-grad:linear-gradient(90deg,#635bff,#7a73ff 45%,#00d4ff);
|
|
107
|
+
--tag-bg:rgba(99,91,255,.08);
|
|
108
|
+
--card-shadow:0 1px 2px rgba(50,50,93,.06),0 10px 28px rgba(50,50,93,.12);
|
|
109
|
+
}
|
|
110
|
+
[data-theme="notion"]{ /* 纸感暖白(Notion) */
|
|
111
|
+
--bg:#faf9f6; --bg2:#e9e7e1; --panel:rgba(251,251,250,.98); --panel-solid:#fbfbfa;
|
|
112
|
+
--text:#37352f; --muted:#787774; --accent:#2383e2; --accent2:#0f9d8f;
|
|
113
|
+
--border:rgba(55,53,47,.14); --glow:rgba(35,131,226,.15);
|
|
114
|
+
--title-grad:linear-gradient(90deg,#37352f,#2383e2 55%,#0f9d8f);
|
|
115
|
+
--tag-bg:rgba(55,53,47,.06);
|
|
116
|
+
--card-shadow:0 1px 2px rgba(55,53,47,.07),0 10px 28px rgba(55,53,47,.11);
|
|
117
|
+
}
|
|
118
|
+
[data-theme="gruvbox"]{ /* 复古暖橙(Gruvbox) */
|
|
119
|
+
--bg:#282828; --bg2:#1d2021; --panel:rgba(50,48,47,.9); --panel-solid:#32302f;
|
|
120
|
+
--text:#ebdbb2; --muted:#a89984; --accent:#fe8019; --accent2:#b8bb26;
|
|
121
|
+
--border:rgba(254,128,25,.3); --glow:rgba(254,128,25,.32);
|
|
122
|
+
--title-grad:linear-gradient(90deg,#fabd2f,#fe8019 50%,#b8bb26);
|
|
123
|
+
--tag-bg:rgba(254,128,25,.12);
|
|
124
|
+
--card-shadow:0 1px 0 rgba(255,255,255,.04) inset,0 10px 28px rgba(0,0,0,.4),0 0 18px rgba(254,128,25,.14);
|
|
125
|
+
}
|
|
126
|
+
[data-theme="gold"]{ /* 黑金奢华(发布会) */
|
|
127
|
+
--bg:#0d0b08; --bg2:#080604; --panel:rgba(30,24,14,.9); --panel-solid:#1e180e;
|
|
128
|
+
--text:#f3e9c8; --muted:#9c8a5c; --accent:#d4af37; --accent2:#f5d76e;
|
|
129
|
+
--border:rgba(212,175,55,.28); --glow:rgba(212,175,55,.35);
|
|
130
|
+
--title-grad:linear-gradient(90deg,#f9e08a,#d4af37 45%,#f5d76e);
|
|
131
|
+
--tag-bg:rgba(212,175,55,.12);
|
|
132
|
+
--card-shadow:0 1px 0 rgba(255,255,255,.05) inset,0 12px 32px rgba(0,0,0,.5),0 0 22px rgba(212,175,55,.16);
|
|
133
|
+
}
|
|
134
|
+
[data-theme="ocean"]{ /* 深洋蓝(深海) */
|
|
135
|
+
--bg:#04121f; --bg2:#020a13; --panel:rgba(10,32,52,.9); --panel-solid:#0a2034;
|
|
136
|
+
--text:#d6e9ff; --muted:#5b8aad; --accent:#38bdf8; --accent2:#60a5fa;
|
|
137
|
+
--border:rgba(56,189,248,.25); --glow:rgba(56,189,248,.35);
|
|
138
|
+
--title-grad:linear-gradient(90deg,#7dd3fc,#38bdf8 45%,#60a5fa);
|
|
139
|
+
--tag-bg:rgba(56,189,248,.12);
|
|
140
|
+
--card-shadow:0 1px 0 rgba(255,255,255,.04) inset,0 10px 28px rgba(0,0,0,.45),0 0 18px rgba(56,189,248,.16);
|
|
41
141
|
}
|
|
42
142
|
/* ══════════ 2. 背景装饰(舞台外围氛围层) ══════════ */
|
|
43
143
|
.bg-glow{ position:fixed; inset:0; z-index:0;
|
|
@@ -69,24 +169,30 @@ button,select,input{ font-family:inherit; }
|
|
|
69
169
|
.tag{ flex:0 0 auto; margin-left:auto; font-size:13px; padding:5px 14px; border-radius:999px;
|
|
70
170
|
color:var(--accent); background:var(--tag-bg); border:1px solid var(--border); }
|
|
71
171
|
.panel{ background:var(--panel); border:1px solid var(--border); border-radius:14px;
|
|
72
|
-
padding:22px 26px; backdrop-filter:blur(6px); }
|
|
172
|
+
padding:22px 26px; backdrop-filter:blur(6px); box-shadow:var(--card-shadow); }
|
|
73
173
|
.grid2{ display:grid; grid-template-columns:1fr 1fr; gap:22px; }
|
|
74
174
|
.grid3{ display:grid; grid-template-columns:1fr 1fr 1fr; gap:22px; }
|
|
75
175
|
.grid4{ display:grid; grid-template-columns:repeat(4,1fr); gap:18px; }
|
|
176
|
+
.prof-grid{ display:grid; grid-template-columns:repeat(7,1fr); gap:8px; }
|
|
177
|
+
.prof-demo{ padding:9px 4px; text-align:center; cursor:pointer; transition:border-color .15s ease, transform .15s ease; }
|
|
178
|
+
.prof-demo:hover{ border-color:var(--accent); transform:translateY(-2px); }
|
|
179
|
+
.prof-demo h4{ font-size:12.5px; margin:0; }
|
|
180
|
+
.prof-demo .en{ display:block; font-size:10px; margin-top:2px; }
|
|
181
|
+
.demo-tip{ margin-top:16px; font-size:12px; color:var(--muted); text-align:center; }
|
|
76
182
|
.card{ background:var(--panel); border:1px solid var(--border); border-radius:12px; padding:20px 22px;
|
|
77
|
-
transition:transform .2s ease, box-shadow .2s ease; }
|
|
78
|
-
.card:hover{ transform:translateY(-4px); box-shadow:0 8px 24px var(--glow); }
|
|
183
|
+
box-shadow:var(--card-shadow); transition:transform .2s ease, box-shadow .2s ease; }
|
|
184
|
+
.card:hover{ transform:translateY(-4px); box-shadow:var(--card-shadow),0 8px 24px var(--glow); }
|
|
79
185
|
.card h4{ font-size:18px; font-weight:700; color:var(--text); margin-bottom:8px; }
|
|
80
186
|
.card h4 .en{ font-size:12px; color:var(--muted); margin-left:8px; font-weight:400; }
|
|
81
187
|
.card p{ font-size:14px; color:var(--muted); line-height:1.7; }
|
|
82
|
-
.bignum{ background:var(--panel); border:1px solid var(--border); border-radius:12px; padding:18px 20px; text-align:center; }
|
|
188
|
+
.bignum{ background:var(--panel); border:1px solid var(--border); border-radius:12px; padding:18px 20px; text-align:center; box-shadow:var(--card-shadow); }
|
|
83
189
|
.bignum b{ display:block; font-size:52px; font-weight:900; background:var(--title-grad);
|
|
84
190
|
-webkit-background-clip:text; background-clip:text; color:transparent; }
|
|
85
191
|
.bignum span{ font-size:13px; color:var(--muted); }
|
|
86
192
|
.toc{ display:flex; flex-direction:column; gap:14px; }
|
|
87
193
|
.toc-item{ display:flex; align-items:center; gap:16px; padding:16px 22px; border-radius:12px;
|
|
88
194
|
background:var(--panel); border:1px solid var(--border); cursor:pointer;
|
|
89
|
-
transition:transform .2s ease; }
|
|
195
|
+
box-shadow:var(--card-shadow); transition:transform .2s ease; }
|
|
90
196
|
.toc-item:hover{ transform:translateX(8px); }
|
|
91
197
|
.toc-item .no{ width:34px; height:34px; border-radius:8px; display:flex; align-items:center; justify-content:center;
|
|
92
198
|
font-weight:800; color:var(--accent); background:var(--tag-bg); }
|
|
@@ -177,9 +283,125 @@ button,select,input{ font-family:inherit; }
|
|
|
177
283
|
.tl-time{ font-size:24px; font-weight:800; color:var(--accent); }
|
|
178
284
|
.tl-item h4{ font-size:18px; font-weight:700; color:var(--text); margin:6px 0; }
|
|
179
285
|
.tl-item p{ font-size:14px; color:var(--muted); line-height:1.7; }
|
|
286
|
+
|
|
287
|
+
/* T6 steps 流程步骤:卡片重排为箭头连接的步骤条(包装器生成 .st-wrap) */
|
|
288
|
+
[data-template="steps"] .s-head h2{ font-size:34px; }
|
|
289
|
+
.st-wrap{ display:flex; align-items:stretch; flex:1; margin-top:6px; }
|
|
290
|
+
.st-step{ flex:1; position:relative; padding:24px 20px; background:var(--panel); border:1px solid var(--border); border-radius:14px; }
|
|
291
|
+
.st-step + .st-step{ margin-left:34px; }
|
|
292
|
+
.st-step::after{ content:'\2192'; position:absolute; right:-34px; top:50%; transform:translateY(-50%);
|
|
293
|
+
width:34px; text-align:center; font-size:22px; font-weight:700; color:var(--accent); }
|
|
294
|
+
.st-step:last-child::after{ display:none; }
|
|
295
|
+
.st-no{ display:flex; align-items:center; justify-content:center; width:42px; height:42px; border-radius:50%;
|
|
296
|
+
font-size:18px; font-weight:800; color:#fff; background:linear-gradient(135deg,var(--accent),var(--accent2));
|
|
297
|
+
box-shadow:0 0 14px var(--glow); }
|
|
298
|
+
.st-step h4{ font-size:16px; font-weight:700; color:var(--text); margin:12px 0 6px; }
|
|
299
|
+
.st-step p{ font-size:13px; color:var(--muted); line-height:1.7; }
|
|
300
|
+
/* T7 poster 海报宣传:海报大标题 + clip-path 斜切色带(包装器生成 .pt-band) */
|
|
301
|
+
[data-template="poster"] .s-title{ font-size:66px; letter-spacing:2px; line-height:1.2; }
|
|
302
|
+
[data-template="poster"] .cover .s-title{ font-size:84px; }
|
|
303
|
+
[data-template="poster"] .s-head h2{ font-size:40px; }
|
|
304
|
+
.pt-band{ position:relative; margin:16px 0; padding:14px 30px; color:#fff; font-size:19px; font-weight:700;
|
|
305
|
+
background:linear-gradient(90deg,var(--accent),var(--accent2));
|
|
306
|
+
clip-path:polygon(0 0, 95% 0, 100% 50%, 95% 100%, 0 100%); }
|
|
307
|
+
.pt-band:nth-child(odd){ clip-path:polygon(5% 0, 100% 0, 100% 100%, 5% 100%, 0 50%); text-align:right; }
|
|
308
|
+
.pt-band span{ font-size:12px; font-weight:400; opacity:.85; margin-left:10px; }
|
|
309
|
+
[data-template="poster"] .card{ background:transparent; border:none; padding:10px 6px; }
|
|
310
|
+
[data-template="poster"] .card p{ font-size:15px; }
|
|
311
|
+
[data-template="poster"] .card:hover{ transform:none; box-shadow:none; }
|
|
312
|
+
/* T8 vintage 复古报纸:衬线字 + 双栏排印 + 虚线分隔 */
|
|
313
|
+
[data-template="vintage"] .s-head h2,
|
|
314
|
+
[data-template="vintage"] .s-title,
|
|
315
|
+
[data-template="vintage"] .card h4{ font-family:Georgia,'Times New Roman','Songti SC','SimSun',serif; }
|
|
316
|
+
[data-template="vintage"] .s-head h2{ font-size:38px; letter-spacing:1px; }
|
|
317
|
+
[data-template="vintage"] .s-head{ border-bottom:3px double var(--text); padding-bottom:16px; margin-bottom:26px; }
|
|
318
|
+
[data-template="vintage"] .s-head::before{ display:none; }
|
|
319
|
+
.v-col{ column-count:2; column-gap:44px; column-rule:1px solid var(--border); flex:1; }
|
|
320
|
+
.v-col .card{ break-inside:avoid; }
|
|
321
|
+
[data-template="vintage"] .card{ background:transparent; border:none; border-bottom:1px dashed var(--border); border-radius:0; padding:12px 4px 16px; }
|
|
322
|
+
[data-template="vintage"] .card:hover{ transform:none; box-shadow:none; }
|
|
323
|
+
[data-template="vintage"] .card p{ font-size:13px; }
|
|
324
|
+
[data-template="vintage"] .tag{ font-family:Georgia,'Times New Roman',serif; letter-spacing:3px; }
|
|
325
|
+
[data-template="vintage"] .s-title{ font-size:52px; }
|
|
326
|
+
/* T9 finance 金融报表:仪表环 + 竖线分隔的 KPI 大数字 */
|
|
327
|
+
[data-template="finance"] .s-head{ border-bottom:2px solid var(--accent); padding-bottom:14px; }
|
|
328
|
+
[data-template="finance"] .s-head h2{ font-size:30px; }
|
|
329
|
+
[data-template="finance"] .bignum{ background:transparent; border:none; border-left:3px solid var(--accent); border-radius:0; text-align:left; padding:6px 18px; }
|
|
330
|
+
[data-template="finance"] .bignum b{ font-size:42px; }
|
|
331
|
+
[data-template="finance"] .bignum span{ letter-spacing:1px; }
|
|
332
|
+
.fn-ring{ position:relative; width:150px; height:150px; border-radius:50%; margin:0 auto 12px;
|
|
333
|
+
background:conic-gradient(var(--accent) 0 var(--pn,64%), var(--border) var(--pn,64%) 100%);
|
|
334
|
+
display:flex; align-items:center; justify-content:center; }
|
|
335
|
+
.fn-ring::before{ content:''; position:absolute; inset:16px; border-radius:50%; background:var(--bg); }
|
|
336
|
+
.fn-ring b{ position:relative; font-size:30px; font-weight:900; background:var(--title-grad);
|
|
337
|
+
-webkit-background-clip:text; background-clip:text; color:transparent; }
|
|
338
|
+
.fn-caption{ margin-top:10px; font-size:12px; color:var(--muted); text-align:center; letter-spacing:1px; }
|
|
339
|
+
/* T10 blueprint 蓝图工程:制图网格卡片 + 坐标刻度标注 */
|
|
340
|
+
[data-template="blueprint"] .slide{ background-image:linear-gradient(var(--border) 1px,transparent 1px),linear-gradient(90deg,var(--border) 1px,transparent 1px);
|
|
341
|
+
background-size:36px 36px; }
|
|
342
|
+
[data-template="blueprint"] .card{ border-radius:0; border:1px solid var(--accent); position:relative; }
|
|
343
|
+
[data-template="blueprint"] .card::before{ content:''; position:absolute; top:-7px; left:16px; width:52px; height:7px;
|
|
344
|
+
background:var(--panel); border:1px solid var(--accent); border-bottom:none; }
|
|
345
|
+
[data-template="blueprint"] .card::after{ content:''; position:absolute; right:-7px; bottom:16px; width:7px; height:52px;
|
|
346
|
+
background:var(--panel); border:1px solid var(--accent); border-left:none; }
|
|
347
|
+
[data-template="blueprint"] .card h4{ font-size:15px; text-transform:uppercase; letter-spacing:1px; }
|
|
348
|
+
[data-template="blueprint"] .card p{ font-size:13px; }
|
|
349
|
+
[data-template="blueprint"] .s-head::before{ border-radius:0; }
|
|
350
|
+
[data-template="blueprint"] .tag{ border-radius:0; letter-spacing:2px; }
|
|
351
|
+
[data-template="blueprint"] .bignum{ border-radius:0; }
|
|
352
|
+
/* T11 education 教学板书:手写感下划线 + 强调要点 */
|
|
353
|
+
[data-template="education"] .s-head::before{ display:none; }
|
|
354
|
+
[data-template="education"] .s-head h2{ font-size:38px; padding-bottom:10px; border-bottom:4px solid var(--accent); }
|
|
355
|
+
[data-template="education"] .s-head .tag{ border-radius:8px; }
|
|
356
|
+
[data-template="education"] .card{ background:transparent; border:none; border-left:4px solid var(--accent2); border-radius:0; padding:8px 18px; }
|
|
357
|
+
[data-template="education"] .card:hover{ transform:none; box-shadow:none; }
|
|
358
|
+
[data-template="education"] .card h4{ font-size:20px; }
|
|
359
|
+
/* T12 executive 高管简报:细线分隔 + 克制排版 */
|
|
360
|
+
[data-template="executive"] .s-head{ border-bottom:1px solid var(--border); padding-bottom:18px; }
|
|
361
|
+
[data-template="executive"] .s-head::before{ width:8px; height:44px; border-radius:2px; }
|
|
362
|
+
[data-template="executive"] .card{ border:none; border-left:3px solid var(--accent); border-radius:2px; }
|
|
363
|
+
[data-template="executive"] .card h4{ font-size:17px; }
|
|
364
|
+
[data-template="executive"] .grid3, [data-template="executive"] .grid2{ gap:16px; }
|
|
365
|
+
[data-template="executive"] .card p{ font-size:13px; }
|
|
366
|
+
/* T13 metro 扁平磁贴:nth 多彩色块卡 */
|
|
367
|
+
[data-template="metro"] .grid3, [data-template="metro"] .grid2{ gap:16px; }
|
|
368
|
+
[data-template="metro"] .card{ border:none; border-radius:8px; padding:22px; }
|
|
369
|
+
[data-template="metro"] .card:nth-child(4n+1){ background:var(--accent); }
|
|
370
|
+
[data-template="metro"] .card:nth-child(4n+2){ background:var(--accent2); }
|
|
371
|
+
[data-template="metro"] .card:nth-child(4n+3){ background:var(--muted); }
|
|
372
|
+
[data-template="metro"] .card:nth-child(4n+4){ background:var(--accent); filter:brightness(.82); }
|
|
373
|
+
[data-template="metro"] .card h4{ color:#fff; font-size:19px; }
|
|
374
|
+
[data-template="metro"] .card h4 .en{ color:rgba(255,255,255,.72); }
|
|
375
|
+
[data-template="metro"] .card p{ color:rgba(255,255,255,.88); }
|
|
376
|
+
[data-template="metro"] .card:hover{ transform:none; box-shadow:none; }
|
|
377
|
+
[data-template="metro"] .bignum{ border:none; border-radius:8px; }
|
|
378
|
+
/* T14 bento 模块网格:首卡大格拼贴 */
|
|
379
|
+
[data-template="bento"] .grid3{ grid-template-columns:1.5fr 1fr 1fr; grid-auto-rows:1fr; }
|
|
380
|
+
[data-template="bento"] .grid2{ grid-template-columns:1.5fr 1fr; grid-auto-rows:1fr; }
|
|
381
|
+
[data-template="bento"] .card:first-child{ grid-row:span 2; display:flex; flex-direction:column; justify-content:center; }
|
|
382
|
+
[data-template="bento"] .card:first-child h4{ font-size:24px; }
|
|
383
|
+
[data-template="bento"] .card:first-child p{ font-size:15px; }
|
|
384
|
+
[data-template="bento"] .card{ border-radius:18px; }
|
|
385
|
+
[data-template="bento"] .card h4 .en{ display:block; margin:4px 0 0; }
|
|
386
|
+
/* T15 dark 暗夜深色:页面级反色变量(浅色主题下同样全黑) */
|
|
387
|
+
[data-template="dark"]{ --bg:#0d1117; --bg2:#0a0c10; --panel:rgba(22,27,34,.88); --panel-solid:#161b22;
|
|
388
|
+
--text:#e6edf3; --muted:#8b949e; --accent:#58a6ff; --accent2:#7ee787;
|
|
389
|
+
--border:rgba(139,148,158,.22); --glow:rgba(88,166,255,.28);
|
|
390
|
+
--title-grad:linear-gradient(90deg,#a5d6ff,#58a6ff 50%,#7ee787);
|
|
391
|
+
--tag-bg:rgba(88,166,255,.12); }
|
|
392
|
+
/* T16 nature 自然清新:有机圆润形状语言 */
|
|
393
|
+
[data-template="nature"] .card{ border-radius:24px 8px 24px 8px; border-width:2px; }
|
|
394
|
+
[data-template="nature"] .card:nth-child(even){ border-radius:8px 24px 8px 24px; }
|
|
395
|
+
[data-template="nature"] .s-head::before{ width:16px; height:16px; border-radius:50% 50% 50% 0; transform:rotate(45deg); }
|
|
396
|
+
[data-template="nature"] .tag{ border-radius:16px 4px 16px 4px; }
|
|
397
|
+
[data-template="nature"] .bignum{ border-radius:50% 50% 8px 8px; }
|
|
398
|
+
[data-template="nature"] .toc-item{ border-radius:18px 6px 18px 6px; }
|
|
399
|
+
[data-template="nature"] .card:hover{ transform:translateY(-4px) rotate(-.6deg); }
|
|
400
|
+
|
|
180
401
|
/* ══════════ 6. 操作元素(固定样式) ══════════ */
|
|
181
402
|
.toolbar{ position:fixed; right:18px; top:14px; z-index:10;
|
|
182
|
-
display:flex; align-items:center; gap:10px;
|
|
403
|
+
display:flex; align-items:center; gap:10px;
|
|
404
|
+
flex-wrap:wrap; justify-content:flex-end; max-width:calc(100vw - 36px); }
|
|
183
405
|
.group{ display:flex; align-items:center; gap:8px; padding:4px 6px; border-radius:999px;
|
|
184
406
|
background:var(--panel-solid); border:1px solid var(--border); box-shadow:0 4px 16px rgba(0,0,0,.18); }
|
|
185
407
|
.tbtn{ display:inline-flex; align-items:center; justify-content:center; gap:6px;
|
|
@@ -188,12 +410,16 @@ button,select,input{ font-family:inherit; }
|
|
|
188
410
|
white-space:nowrap; transition:all .15s ease; }
|
|
189
411
|
.tbtn:hover{ border-color:var(--border); background:var(--tag-bg); }
|
|
190
412
|
.tbtn.on{ color:#fff; background:var(--accent); border-color:var(--accent); }
|
|
191
|
-
|
|
192
|
-
.
|
|
193
|
-
|
|
194
|
-
.
|
|
195
|
-
.
|
|
196
|
-
.
|
|
413
|
+
/* ═══ 主题切换面板(16 色点网格 + 全部/仅本页,即点即换) ═══ */
|
|
414
|
+
.theme-panel{ width:560px; max-width:94vw; max-height:82vh; display:flex; flex-direction:column; padding:24px 26px;
|
|
415
|
+
border-radius:16px; background:var(--panel-solid); border:1px solid var(--border); color:var(--text); }
|
|
416
|
+
.theme-panel h3{ font-size:18px; margin:0; }
|
|
417
|
+
.theme-grid{ display:grid; grid-template-columns:repeat(4,1fr); gap:8px; margin:14px 0 6px; overflow-y:auto; padding:2px; }
|
|
418
|
+
.th-item{ display:flex; align-items:center; gap:8px; padding:8px 10px; border-radius:10px;
|
|
419
|
+
background:var(--panel); border:1px solid var(--border); cursor:pointer; font-size:12px; transition:all .15s ease; }
|
|
420
|
+
.th-item:hover{ border-color:var(--accent); }
|
|
421
|
+
.th-item.on{ border-color:var(--accent); box-shadow:0 0 0 2px var(--tag-bg), 0 0 12px var(--glow); }
|
|
422
|
+
.th-dot{ width:14px; height:14px; border-radius:50%; flex:0 0 auto; border:2px solid rgba(255,255,255,.35); }
|
|
197
423
|
select.tbtn{ appearance:auto; padding:7px 10px; }
|
|
198
424
|
label.tbtn{ cursor:pointer; }
|
|
199
425
|
label.tbtn input[type=checkbox]{ width:14px; height:14px; margin:0; flex:0 0 auto; accent-color:var(--accent); }
|
|
@@ -212,7 +438,7 @@ body:hover .nav{ opacity:1; }
|
|
|
212
438
|
.help-mask{ position:fixed; inset:0; z-index:20; display:none; align-items:center; justify-content:center;
|
|
213
439
|
background:rgba(0,0,0,.55); backdrop-filter:blur(4px); }
|
|
214
440
|
.help-mask.open{ display:flex; }
|
|
215
|
-
.help-panel{ width:
|
|
441
|
+
.help-panel{ width:640px; max-width:94vw; max-height:70vh; overflow:auto; padding:30px 34px; border-radius:16px;
|
|
216
442
|
background:var(--panel-solid); border:1px solid var(--border); color:var(--text); }
|
|
217
443
|
.help-panel h3{ font-size:20px; margin-bottom:16px; }
|
|
218
444
|
.help-panel table{ width:100%; border-collapse:collapse; font-size:13px; }
|
|
@@ -221,7 +447,7 @@ body:hover .nav{ opacity:1; }
|
|
|
221
447
|
border:1px solid var(--border); font-family:inherit; }
|
|
222
448
|
.help-note{ margin-top:14px; font-size:12px; color:var(--muted); line-height:1.8; }
|
|
223
449
|
/* ═══ 选页复制面板 ═══ */
|
|
224
|
-
.copy-panel{ width:
|
|
450
|
+
.copy-panel{ width:500px; max-width:94vw; max-height:72vh; display:flex; flex-direction:column; padding:24px 26px;
|
|
225
451
|
border-radius:16px; background:var(--panel-solid); border:1px solid var(--border); color:var(--text); }
|
|
226
452
|
.copy-panel h3{ font-size:18px; margin:0; }
|
|
227
453
|
.cp-head{ display:flex; align-items:center; justify-content:space-between; margin-bottom:14px; }
|
|
@@ -238,12 +464,19 @@ body:hover .nav{ opacity:1; }
|
|
|
238
464
|
.cp-foot .tbtn{ border:1px solid var(--border); background:var(--tag-bg); cursor:pointer; }
|
|
239
465
|
.cp-foot .tbtn.primary{ background:var(--accent); color:var(--bg); border-color:transparent; }
|
|
240
466
|
/* ═══ 模板应用面板 ═══ */
|
|
241
|
-
.tpl-panel{ width:
|
|
467
|
+
.tpl-panel{ width:760px; max-width:94vw; max-height:82vh; display:flex; flex-direction:column; padding:24px 26px;
|
|
242
468
|
border-radius:16px; background:var(--panel-solid); border:1px solid var(--border); color:var(--text); }
|
|
243
469
|
.tpl-panel h3{ font-size:18px; margin:0; }
|
|
470
|
+
.tpl-tabs{ display:flex; gap:8px; }
|
|
471
|
+
.tpl-tab{ border:1px solid var(--border); background:var(--bg2); color:var(--muted);
|
|
472
|
+
border-radius:999px; padding:5px 14px; font-size:12px; letter-spacing:1px;
|
|
473
|
+
cursor:pointer; font-family:inherit; }
|
|
474
|
+
.tpl-tab.on{ background:var(--accent); color:var(--bg); border-color:var(--accent); font-weight:700; }
|
|
475
|
+
.tpl-cat{ grid-column:1/-1; font-size:11px; color:var(--muted); letter-spacing:2px; margin:6px 0 -4px; }
|
|
476
|
+
.tpl-card .nm .pg{ font-style:normal; font-size:10px; font-weight:400; color:var(--muted); margin-left:6px; letter-spacing:.5px; }
|
|
244
477
|
.tpl-head-note{ font-size:12px; color:var(--muted); }
|
|
245
|
-
.tpl-cards{ display:grid; grid-template-columns:repeat(
|
|
246
|
-
.tpl-card{ display:flex; align-items:
|
|
478
|
+
.tpl-cards{ display:grid; grid-template-columns:repeat(3,1fr); gap:10px; margin:14px 0 12px; overflow-y:auto; max-height:46vh; padding:2px; }
|
|
479
|
+
.tpl-card{ display:flex; flex-direction:column; align-items:stretch; gap:7px; padding:9px; border-radius:12px;
|
|
247
480
|
background:var(--panel); border:1px solid var(--border); cursor:pointer; transition:all .15s ease; text-align:left; }
|
|
248
481
|
.tpl-card:hover{ border-color:var(--accent); }
|
|
249
482
|
.tpl-card.on{ border-color:var(--accent); box-shadow:0 0 0 2px var(--tag-bg), 0 0 16px var(--glow); }
|
|
@@ -251,6 +484,8 @@ body:hover .nav{ opacity:1; }
|
|
|
251
484
|
justify-content:center; font-size:16px; color:#fff; background:linear-gradient(135deg,var(--accent),var(--accent2)); }
|
|
252
485
|
.tpl-card .nm{ display:block; font-size:14px; font-weight:700; }
|
|
253
486
|
.tpl-card .ds{ display:block; font-size:11px; color:var(--muted); margin-top:2px; line-height:1.5; }
|
|
487
|
+
.tpl-mini{ position:relative; height:46px; border-radius:7px; background:var(--bg2); border:1px solid var(--border); overflow:hidden; flex:0 0 auto; }
|
|
488
|
+
.tpl-mini i{ position:absolute; display:block; font-style:normal; }
|
|
254
489
|
.tpl-scope{ display:flex; gap:8px; margin:2px 0 12px; flex-wrap:wrap; }
|
|
255
490
|
.tpl-scope label{ display:inline-flex; align-items:center; gap:6px; font-size:13px; cursor:pointer; padding:6px 12px;
|
|
256
491
|
border-radius:999px; border:1px solid var(--border); color:var(--muted); }
|
|
@@ -258,6 +493,96 @@ body:hover .nav{ opacity:1; }
|
|
|
258
493
|
.tpl-scope label.sel{ color:var(--accent); border-color:var(--accent); background:var(--tag-bg); }
|
|
259
494
|
#tplList{ display:none; }
|
|
260
495
|
#tplList.show{ display:block; }
|
|
496
|
+
|
|
497
|
+
/* ═══ 页导航边栏(右侧缩略图,像专业 PPT 软件) ═══ */
|
|
498
|
+
.sidepanel{ position:fixed; right:0; top:0; bottom:0; width:264px; z-index:11; /* 高于工具栏(10):边栏打开时头部操作不被右上工具栏遮挡 */
|
|
499
|
+
display:flex; flex-direction:column; background:var(--panel-solid); border-left:1px solid var(--border);
|
|
500
|
+
transform:translateX(100%); transition:transform .25s ease; }
|
|
501
|
+
.sidepanel.open{ transform:translateX(0); }
|
|
502
|
+
.sp-head{ display:flex; align-items:center; justify-content:space-between; padding:10px 12px;
|
|
503
|
+
font-size:13px; font-weight:700; color:var(--text); border-bottom:1px solid var(--border); flex:0 0 auto; }
|
|
504
|
+
.sp-head-ops{ display:flex; align-items:center; gap:8px; }
|
|
505
|
+
.sp-add{ font-size:12px; padding:4px 10px; border-radius:999px; border:1px solid var(--border);
|
|
506
|
+
background:var(--tag-bg); color:var(--accent); cursor:pointer; }
|
|
507
|
+
.sp-add:hover{ border-color:var(--accent); }
|
|
508
|
+
.sp-close{ border:none; background:none; color:var(--muted); font-size:16px; cursor:pointer; padding:2px 6px; }
|
|
509
|
+
.sp-close:hover{ color:var(--accent); }
|
|
510
|
+
.sp-list{ flex:1; overflow-y:auto; padding:10px; display:flex; flex-direction:column; gap:10px; }
|
|
511
|
+
.thumb{ position:relative; flex:0 0 auto; border:2px solid var(--border); border-radius:8px; cursor:pointer;
|
|
512
|
+
overflow:hidden; background:var(--bg); transition:border-color .15s ease, box-shadow .15s ease; }
|
|
513
|
+
.thumb:hover{ border-color:var(--accent); }
|
|
514
|
+
.thumb.cur{ border-color:var(--accent); box-shadow:0 0 12px var(--glow); }
|
|
515
|
+
.thumb-no{ position:absolute; left:5px; top:5px; z-index:2; font-size:10px; font-weight:700; padding:1px 7px;
|
|
516
|
+
border-radius:999px; color:var(--accent); background:var(--panel-solid); border:1px solid var(--border); }
|
|
517
|
+
.thumb-t{ position:absolute; left:5px; bottom:5px; z-index:2; max-width:calc(100% - 96px);
|
|
518
|
+
font-size:10px; color:var(--text); background:rgba(0,0,0,.55); padding:1px 7px; border-radius:999px;
|
|
519
|
+
overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
|
|
520
|
+
.thumb-ops{ position:absolute; right:4px; bottom:4px; z-index:3; display:none; gap:3px; }
|
|
521
|
+
.thumb:hover .thumb-ops{ display:flex; }
|
|
522
|
+
.thumb-ops button{ width:20px; height:20px; border-radius:5px; border:1px solid var(--border);
|
|
523
|
+
background:var(--panel-solid); color:var(--text); cursor:pointer; font-size:11px; line-height:1;
|
|
524
|
+
display:inline-flex; align-items:center; justify-content:center; padding:0; }
|
|
525
|
+
.thumb-ops button:hover{ background:var(--accent); color:#fff; border-color:var(--accent); }
|
|
526
|
+
.thumb-ops .op-del{ background:rgba(220,38,38,.88); color:#fff; border-color:transparent; }
|
|
527
|
+
.thumb-ops .op-del:hover{ background:#dc2626; border-color:#dc2626; }
|
|
528
|
+
.thumb-ops button:disabled{ opacity:.3; cursor:default; }
|
|
529
|
+
.thumb-ops button:disabled:hover{ background:var(--panel-solid); color:var(--text); border-color:var(--border); }
|
|
530
|
+
.thumb-ops .op-del:disabled:hover{ background:rgba(220,38,38,.88); }
|
|
531
|
+
.thumb-wrap{ width:100%; aspect-ratio:16/9; position:relative; overflow:hidden; }
|
|
532
|
+
.thumb-slide{ position:absolute !important; top:0 !important; left:0 !important; width:1280px !important; height:720px !important; transform-origin:0 0 !important;
|
|
533
|
+
padding:64px 80px !important; display:flex !important; flex-direction:column !important;
|
|
534
|
+
background:var(--bg) !important; overflow:hidden !important;
|
|
535
|
+
opacity:1 !important; visibility:visible !important; transition:none !important; pointer-events:none !important; }
|
|
536
|
+
/* ═══ 侧边栏双 Tab(▤ 页面 / ⚙ 工具)与工具区 ═══ */
|
|
537
|
+
.sp-tabs{ display:flex; align-items:center; gap:6px; padding:8px 10px; border-bottom:1px solid var(--border); flex:0 0 auto; }
|
|
538
|
+
.sp-tab{ flex:1; padding:7px 0; border-radius:8px; border:1px solid transparent; background:none; color:var(--muted);
|
|
539
|
+
font-size:13px; font-weight:700; cursor:pointer; transition:all .15s ease; }
|
|
540
|
+
.sp-tab:hover{ color:var(--text); background:var(--tag-bg); }
|
|
541
|
+
.sp-tab.on{ color:var(--accent); background:var(--tag-bg); border-color:var(--border); }
|
|
542
|
+
.sp-pane{ display:none; flex:1; flex-direction:column; min-height:0; }
|
|
543
|
+
.sp-pane.on{ display:flex; }
|
|
544
|
+
#paneTools{ overflow-y:auto; }
|
|
545
|
+
.ts-sec{ padding:12px 12px 2px; border-bottom:1px solid var(--border); }
|
|
546
|
+
.ts-sec:last-child{ border-bottom:none; }
|
|
547
|
+
.ts-title{ display:flex; align-items:center; justify-content:space-between; font-size:12px; font-weight:700; color:var(--text); margin-bottom:8px; }
|
|
548
|
+
.ts-check{ display:inline-flex; align-items:center; gap:5px; font-weight:400; font-size:12px; color:var(--muted); cursor:pointer; }
|
|
549
|
+
.ts-check input{ margin:0; accent-color:var(--accent); }
|
|
550
|
+
.ts-sub{ font-size:11px; color:var(--muted); margin:10px 0 6px; }
|
|
551
|
+
.scope-seg{ display:flex; align-items:center; gap:6px; }
|
|
552
|
+
.ts-lbl{ font-size:11px; color:var(--muted); }
|
|
553
|
+
.seg-btn{ display:inline-flex; align-items:center; gap:4px; font-size:11px; padding:5px 9px; border-radius:999px;
|
|
554
|
+
border:1px solid var(--border); color:var(--muted); cursor:pointer; }
|
|
555
|
+
.seg-btn input{ margin:0; accent-color:var(--accent); }
|
|
556
|
+
.seg-btn.sel{ color:var(--accent); border-color:var(--accent); background:var(--tag-bg); }
|
|
557
|
+
.tg-grid{ display:grid; grid-template-columns:repeat(2,1fr); gap:6px; }
|
|
558
|
+
.tg-grid.col4{ grid-template-columns:repeat(4,1fr); }
|
|
559
|
+
.tg-grid button{ padding:7px 4px; border-radius:8px; border:1px solid var(--border); background:var(--panel);
|
|
560
|
+
color:var(--text); font-size:12px; cursor:pointer; transition:all .15s ease; }
|
|
561
|
+
.tg-grid button:hover{ border-color:var(--accent); color:var(--accent); }
|
|
562
|
+
.tg-grid button.on{ border-color:var(--accent); color:var(--accent); background:var(--tag-bg); box-shadow:0 0 10px var(--glow); }
|
|
563
|
+
.an-grid{ display:grid; grid-template-columns:repeat(3,1fr); gap:5px; }
|
|
564
|
+
.an-grid button{ padding:6px 2px; border-radius:7px; border:1px solid var(--border); background:var(--panel);
|
|
565
|
+
color:var(--muted); font-size:11px; cursor:pointer; transition:all .15s ease; }
|
|
566
|
+
.an-grid button:hover{ border-color:var(--accent); color:var(--accent); }
|
|
567
|
+
.an-grid button.on{ border-color:var(--accent); color:var(--accent); background:var(--tag-bg); box-shadow:0 0 8px var(--glow); }
|
|
568
|
+
.tools-ops{ display:grid; grid-template-columns:repeat(2,1fr); gap:6px; }
|
|
569
|
+
.tools-ops button{ padding:8px 4px; border-radius:8px; border:1px solid var(--border); background:var(--panel);
|
|
570
|
+
color:var(--text); font-size:12px; cursor:pointer; transition:all .15s ease; }
|
|
571
|
+
.tools-ops button:hover{ border-color:var(--accent); color:var(--accent); }
|
|
572
|
+
.ts-note{ padding:10px 12px 14px; font-size:11px; color:var(--muted); line-height:1.65; }
|
|
573
|
+
/* ═══ 新增页面板(选版式加页) ═══ */
|
|
574
|
+
.add-panel{ width:600px; max-width:94vw; max-height:82vh; display:flex; flex-direction:column; padding:24px 26px;
|
|
575
|
+
border-radius:16px; background:var(--panel-solid); border:1px solid var(--border); color:var(--text); }
|
|
576
|
+
.add-panel h3{ font-size:18px; margin:0; }
|
|
577
|
+
.add-head-note{ font-size:12px; color:var(--muted); }
|
|
578
|
+
.add-cards{ display:grid; grid-template-columns:repeat(4,1fr); gap:10px; margin:16px 0 6px; overflow-y:auto; max-height:52vh; padding:2px; }
|
|
579
|
+
.add-card{ padding:8px; border-radius:12px; background:var(--panel); border:1px solid var(--border); cursor:pointer; }
|
|
580
|
+
.add-card:hover{ border-color:var(--accent); box-shadow:0 0 10px var(--glow); }
|
|
581
|
+
.add-card .nm{ display:block; margin-top:6px; font-size:12px; font-weight:700; text-align:center; }
|
|
582
|
+
/* ═══ 按钮禁用态(undo/redo 不可用时) ═══ */
|
|
583
|
+
.tbtn[disabled]{ opacity:.35; cursor:default; }
|
|
584
|
+
.tbtn[disabled]:hover{ border-color:transparent; background:transparent; }
|
|
585
|
+
|
|
261
586
|
/* ══════════ 7. 全屏放映纯净模式(PPT 放映规范:黑底 + 幻灯充满画面) ══════════ */
|
|
262
587
|
:root:fullscreen{ background:#000; } /* 放映黑底:与 PPT 软件放映一致,比例不匹配处补黑边,不带主题氛围边框 */
|
|
263
588
|
:root:fullscreen .bg-glow,
|
|
@@ -266,7 +591,180 @@ body:hover .nav{ opacity:1; }
|
|
|
266
591
|
:root:fullscreen .pageno,
|
|
267
592
|
:root:fullscreen .hint,
|
|
268
593
|
:root:fullscreen .nav,
|
|
594
|
+
:root:fullscreen .sidepanel,
|
|
269
595
|
:root:fullscreen .help-mask{ display:none !important; }
|
|
596
|
+
|
|
597
|
+
/* ═══ 动画库:翻页八套(deck[data-transition])+ 入场十二式(data-anim)+ 离场十二式(data-anim-leave)+ 强调八式(data-anim-emphasis)═══ */
|
|
598
|
+
|
|
599
|
+
/* ── L1 翻页动画风格(slide-lr 为基础默认;以下七套覆盖)── */
|
|
600
|
+
.deck[data-transition="fade"] .slide{ transform:none; }
|
|
601
|
+
.deck[data-transition="fade"] .slide.active{ transform:none; }
|
|
602
|
+
.deck[data-transition="fade"] .slide.dim{ transform:none; }
|
|
603
|
+
.deck[data-transition="slide-ud"] .slide{ transform:translateY(44px); }
|
|
604
|
+
.deck[data-transition="slide-ud"] .slide.active{ transform:translateY(0); }
|
|
605
|
+
.deck[data-transition="slide-ud"] .slide.dim{ transform:translateY(-44px); }
|
|
606
|
+
.deck[data-transition="zoom"] .slide{ transform:scale(1.07); }
|
|
607
|
+
.deck[data-transition="zoom"] .slide.active{ transform:scale(1); }
|
|
608
|
+
.deck[data-transition="zoom"] .slide.dim{ transform:scale(.93); }
|
|
609
|
+
.deck[data-transition="flip"]{ perspective:1800px; }
|
|
610
|
+
.deck[data-transition="flip"] .slide{ transform-origin:center center; backface-visibility:hidden; transition:opacity .5s ease, transform .6s cubic-bezier(.4,0,.2,1), visibility 0s linear .6s; }
|
|
611
|
+
.deck[data-transition="flip"] .slide.active{ transform:rotateY(0deg); }
|
|
612
|
+
.deck[data-transition="flip"] .slide.dim{ opacity:0; transform:rotateY(-90deg); }
|
|
613
|
+
.deck[data-transition="cube"]{ perspective:1800px; }
|
|
614
|
+
.deck[data-transition="cube"] .slide{ transform-origin:center center; backface-visibility:hidden; transition:opacity .5s ease, transform .7s cubic-bezier(.4,0,.2,1), visibility 0s linear .7s; }
|
|
615
|
+
.deck[data-transition="cube"] .slide.active{ transform:rotateY(0deg); }
|
|
616
|
+
.deck[data-transition="cube"] .slide.dim{ opacity:0; transform:rotateY(90deg); }
|
|
617
|
+
.deck[data-transition="wipe"] .slide{ transform:translateX(100%); transition:opacity .45s ease, transform .55s cubic-bezier(.4,0,.2,1), visibility 0s linear .55s; }
|
|
618
|
+
.deck[data-transition="wipe"] .slide.active{ transform:translateX(0); }
|
|
619
|
+
.deck[data-transition="wipe"] .slide.dim{ transform:translateX(-100%); }
|
|
620
|
+
.deck[data-transition="dissolve"] .slide{ transform:none; transition:opacity .5s ease, filter .5s ease, visibility 0s linear .5s; }
|
|
621
|
+
.deck[data-transition="dissolve"] .slide.active{ filter:none; }
|
|
622
|
+
.deck[data-transition="dissolve"] .slide.dim{ opacity:0; filter:blur(8px); }
|
|
623
|
+
|
|
624
|
+
/* ── L2 元素入场动画(翻到该页自动播放;data-anim-delay 错落入场)── */
|
|
625
|
+
.slide [data-anim]{ opacity:0; animation-fill-mode:both; }
|
|
626
|
+
.slide [data-anim="none"]{ opacity:1 !important; animation:none !important; }
|
|
627
|
+
.slide.active [data-anim="fade-up"]{ animation-name:md-fade-up; animation-duration:.6s; animation-timing-function:cubic-bezier(.22,.61,.36,1); }
|
|
628
|
+
.slide.active [data-anim="fade-in"]{ animation-name:md-fade-in; animation-duration:.5s; animation-timing-function:ease; }
|
|
629
|
+
.slide.active [data-anim="fade-down"]{ animation-name:md-fade-down; animation-duration:.6s; animation-timing-function:cubic-bezier(.22,.61,.36,1); }
|
|
630
|
+
.slide.active [data-anim="zoom-in"]{ animation-name:md-zoom-in; animation-duration:.55s; animation-timing-function:cubic-bezier(.22,.61,.36,1); }
|
|
631
|
+
.slide.active [data-anim="slide-left"]{ animation-name:md-slide-left; animation-duration:.6s; animation-timing-function:cubic-bezier(.22,.61,.36,1); }
|
|
632
|
+
.slide.active [data-anim="slide-right"]{ animation-name:md-slide-right; animation-duration:.6s; animation-timing-function:cubic-bezier(.22,.61,.36,1); }
|
|
633
|
+
.slide.active [data-anim="slide-up"]{ animation-name:md-slide-up; animation-duration:.6s; animation-timing-function:cubic-bezier(.22,.61,.36,1); }
|
|
634
|
+
.slide.active [data-anim="slide-down"]{ animation-name:md-slide-down; animation-duration:.6s; animation-timing-function:cubic-bezier(.22,.61,.36,1); }
|
|
635
|
+
.slide.active [data-anim="pop"]{ animation-name:md-pop; animation-duration:.5s; animation-timing-function:cubic-bezier(.34,1.56,.64,1); }
|
|
636
|
+
.slide.active [data-anim="bounce-in"]{ animation-name:md-bounce-in; animation-duration:.7s; animation-timing-function:cubic-bezier(.34,1.56,.64,1); }
|
|
637
|
+
.slide.active [data-anim="flip-in"]{ animation-name:md-flip-in; animation-duration:.65s; animation-timing-function:cubic-bezier(.22,.61,.36,1); }
|
|
638
|
+
.slide.active [data-anim="blur"]{ animation-name:md-blur; animation-duration:.6s; animation-timing-function:ease; }
|
|
639
|
+
.slide.active [data-anim-delay="60"]{ animation-delay:60ms; }
|
|
640
|
+
.slide.active [data-anim-delay="120"]{ animation-delay:120ms; }
|
|
641
|
+
.slide.active [data-anim-delay="180"]{ animation-delay:180ms; }
|
|
642
|
+
.slide.active [data-anim-delay="240"]{ animation-delay:240ms; }
|
|
643
|
+
.slide.active [data-anim-delay="300"]{ animation-delay:300ms; }
|
|
644
|
+
.slide.active [data-anim-delay="400"]{ animation-delay:400ms; }
|
|
645
|
+
.slide.active [data-anim-delay="500"]{ animation-delay:500ms; }
|
|
646
|
+
.slide.active [data-anim-delay="600"]{ animation-delay:600ms; }
|
|
647
|
+
|
|
648
|
+
/* ── L3 元素离场动画(翻离该页前 0.48s 窗口播放;.slide.leaving 由 JS 触发)── */
|
|
649
|
+
.slide [data-anim-leave]{ animation-fill-mode:both; }
|
|
650
|
+
.slide.leaving [data-anim-leave="fade-out"]{ animation:md-fade-out .45s ease both; }
|
|
651
|
+
.slide.leaving [data-anim-leave="fade-up-out"]{ animation:md-fade-up-out .45s ease both; }
|
|
652
|
+
.slide.leaving [data-anim-leave="fade-down-out"]{ animation:md-fade-down-out .45s ease both; }
|
|
653
|
+
.slide.leaving [data-anim-leave="slide-left-out"]{ animation:md-slide-left-out .45s ease both; }
|
|
654
|
+
.slide.leaving [data-anim-leave="slide-right-out"]{ animation:md-slide-right-out .45s ease both; }
|
|
655
|
+
.slide.leaving [data-anim-leave="slide-up-out"]{ animation:md-slide-up-out .45s ease both; }
|
|
656
|
+
.slide.leaving [data-anim-leave="slide-down-out"]{ animation:md-slide-down-out .45s ease both; }
|
|
657
|
+
.slide.leaving [data-anim-leave="zoom-out"]{ animation:md-zoom-out .45s ease both; }
|
|
658
|
+
.slide.leaving [data-anim-leave="zoom-big-out"]{ animation:md-zoom-big-out .45s ease both; }
|
|
659
|
+
.slide.leaving [data-anim-leave="flip-out"]{ animation:md-flip-out .45s ease both; }
|
|
660
|
+
.slide.leaving [data-anim-leave="drop-out"]{ animation:md-drop-out .5s cubic-bezier(.55,0,.8,.4) both; }
|
|
661
|
+
.slide.leaving [data-anim-leave="blur-out"]{ animation:md-blur-out .45s ease both; }
|
|
662
|
+
|
|
663
|
+
/* ── L4 元素强调动画(页面激活期间循环播放;与入场互斥,强调优先)── */
|
|
664
|
+
.slide.active [data-anim-emphasis]{ opacity:1; }
|
|
665
|
+
.slide.active [data-anim-emphasis="pulse"]{ animation:md-pulse 1.6s ease-in-out infinite; }
|
|
666
|
+
.slide.active [data-anim-emphasis="swing"]{ animation:md-swing 1.8s ease-in-out infinite; transform-origin:top center; }
|
|
667
|
+
.slide.active [data-anim-emphasis="shake"]{ animation:md-shake 1.4s ease-in-out infinite; }
|
|
668
|
+
.slide.active [data-anim-emphasis="breathe"]{ animation:md-breathe 2.2s ease-in-out infinite; }
|
|
669
|
+
.slide.active [data-anim-emphasis="flash"]{ animation:md-flash 1.8s ease-in-out infinite; }
|
|
670
|
+
.slide.active [data-anim-emphasis="tada"]{ animation:md-tada 1.8s ease-in-out infinite; }
|
|
671
|
+
.slide.active [data-anim-emphasis="spin"]{ animation:md-spin 1.8s linear infinite; }
|
|
672
|
+
.slide.active [data-anim-emphasis="glow"]{ animation:md-glow 1.6s ease-in-out infinite; }
|
|
673
|
+
|
|
674
|
+
/* ── L5 标题文字动画(运行时拆分 h1/h2/h3/.s-title 为 span,复用入场机制)── */
|
|
675
|
+
.tchar, .tword{ display:inline-block; }
|
|
676
|
+
.tline{ display:block; }
|
|
677
|
+
|
|
678
|
+
/* ── 入场开关(deck[data-anim="off"] 全部停用)── */
|
|
679
|
+
.deck[data-anim="off"] .slide [data-anim]{ opacity:1 !important; animation:none !important; }
|
|
680
|
+
.deck[data-anim="off"] .slide [data-anim-emphasis]{ animation:none !important; }
|
|
681
|
+
|
|
682
|
+
@keyframes md-fade-up{ from{ opacity:0; transform:translateY(24px); } to{ opacity:1; transform:none; } }
|
|
683
|
+
@keyframes md-fade-in{ from{ opacity:0; } to{ opacity:1; } }
|
|
684
|
+
@keyframes md-fade-down{ from{ opacity:0; transform:translateY(-24px); } to{ opacity:1; transform:none; } }
|
|
685
|
+
@keyframes md-zoom-in{ from{ opacity:0; transform:scale(.9); } to{ opacity:1; transform:none; } }
|
|
686
|
+
@keyframes md-slide-left{ from{ opacity:0; transform:translateX(-32px); } to{ opacity:1; transform:none; } }
|
|
687
|
+
@keyframes md-slide-right{ from{ opacity:0; transform:translateX(32px); } to{ opacity:1; transform:none; } }
|
|
688
|
+
@keyframes md-slide-up{ from{ opacity:0; transform:translateY(32px); } to{ opacity:1; transform:none; } }
|
|
689
|
+
@keyframes md-slide-down{ from{ opacity:0; transform:translateY(-32px); } to{ opacity:1; transform:none; } }
|
|
690
|
+
@keyframes md-pop{ 0%{ opacity:0; transform:scale(.6); } 70%{ transform:scale(1.05); } 100%{ opacity:1; transform:none; } }
|
|
691
|
+
@keyframes md-bounce-in{ 0%{ opacity:0; transform:translateY(40px) scale(.9); } 55%{ opacity:1; transform:translateY(-12px) scale(1.03); } 78%{ transform:translateY(6px) scale(.99); } 100%{ opacity:1; transform:none; } }
|
|
692
|
+
@keyframes md-flip-in{ from{ opacity:0; transform:perspective(900px) rotateY(-75deg); } to{ opacity:1; transform:none; } }
|
|
693
|
+
@keyframes md-blur{ from{ opacity:0; filter:blur(10px); } to{ opacity:1; filter:none; } }
|
|
694
|
+
@keyframes md-fade-out{ from{ opacity:1; } to{ opacity:0; } }
|
|
695
|
+
@keyframes md-fade-up-out{ from{ opacity:1; transform:none; } to{ opacity:0; transform:translateY(-40px); } }
|
|
696
|
+
@keyframes md-fade-down-out{ from{ opacity:1; transform:none; } to{ opacity:0; transform:translateY(40px); } }
|
|
697
|
+
@keyframes md-slide-left-out{ from{ opacity:1; transform:none; } to{ opacity:0; transform:translateX(-64px); } }
|
|
698
|
+
@keyframes md-slide-right-out{ from{ opacity:1; transform:none; } to{ opacity:0; transform:translateX(64px); } }
|
|
699
|
+
@keyframes md-slide-up-out{ from{ opacity:1; transform:none; } to{ opacity:0; transform:translateY(-64px); } }
|
|
700
|
+
@keyframes md-slide-down-out{ from{ opacity:1; transform:none; } to{ opacity:0; transform:translateY(64px); } }
|
|
701
|
+
@keyframes md-zoom-out{ from{ opacity:1; transform:none; } to{ opacity:0; transform:scale(.82); } }
|
|
702
|
+
@keyframes md-zoom-big-out{ from{ opacity:1; transform:none; } to{ opacity:0; transform:scale(1.28); } }
|
|
703
|
+
@keyframes md-flip-out{ from{ opacity:1; transform:none; } to{ opacity:0; transform:perspective(900px) rotateY(70deg); } }
|
|
704
|
+
@keyframes md-drop-out{ 0%{ opacity:1; transform:none; } 55%{ opacity:1; transform:translateY(12px); } 100%{ opacity:0; transform:translateY(120px); } }
|
|
705
|
+
@keyframes md-blur-out{ from{ opacity:1; filter:none; } to{ opacity:0; filter:blur(10px); } }
|
|
706
|
+
@keyframes md-pulse{ 0%,100%{ transform:scale(1); } 50%{ transform:scale(1.06); } }
|
|
707
|
+
@keyframes md-swing{ 0%,100%{ transform:rotate(0deg); } 20%{ transform:rotate(6deg); } 40%{ transform:rotate(-5deg); } 60%{ transform:rotate(4deg); } 80%{ transform:rotate(-3deg); } }
|
|
708
|
+
@keyframes md-shake{ 0%,100%{ transform:translateX(0); } 12%{ transform:translateX(-6px); } 24%{ transform:translateX(6px); } 36%{ transform:translateX(-5px); } 48%{ transform:translateX(5px); } 60%{ transform:translateX(-3px); } 72%{ transform:translateX(3px); } 84%{ transform:translateX(-1px); } }
|
|
709
|
+
@keyframes md-breathe{ 0%,100%{ opacity:1; transform:scale(1); } 50%{ opacity:.82; transform:scale(1.045); } }
|
|
710
|
+
@keyframes md-flash{ 0%,100%{ opacity:1; } 50%{ opacity:.3; } }
|
|
711
|
+
@keyframes md-tada{ 0%{ transform:scale(1); } 25%{ transform:scale(1.16) rotate(-2.5deg); } 55%{ transform:scale(1.16) rotate(2.5deg); } 100%{ transform:scale(1); } }
|
|
712
|
+
@keyframes md-spin{ from{ transform:rotate(0deg); } to{ transform:rotate(360deg); } }
|
|
713
|
+
@keyframes md-glow{ 0%,100%{ box-shadow:0 0 6px var(--glow); } 50%{ box-shadow:0 0 26px var(--glow), 0 0 48px var(--glow); } }
|
|
714
|
+
/* ═══ L6 图表组件与动画(bars/line/pie/ring/count 五式:柱状生长/折线描画/饼图扇入/仪表扫弧/数字滚动,
|
|
715
|
+
挂 data-anim-chart 容器,翻到页自动播放、翻离再翻回重放,与模板/主题正交;全部主题变量驱动不写死颜色) ═══ */
|
|
716
|
+
.chart-card{ background:var(--panel); border:1px solid var(--border); border-radius:14px; padding:18px 20px 16px; }
|
|
717
|
+
.chart-card .cc-head{ display:flex; align-items:baseline; justify-content:space-between; gap:8px; margin-bottom:14px; }
|
|
718
|
+
.chart-card .cc-head h4{ font-size:16px; color:var(--text); }
|
|
719
|
+
.chart-card .cc-head .en{ font-size:11px; color:var(--muted); letter-spacing:.1em; }
|
|
720
|
+
/* 柱状生长:柱高由 --h 内联控制,逐柱 --bi×100ms 错峰 */
|
|
721
|
+
.chart-bars{ display:flex; align-items:flex-end; gap:14px; height:158px; }
|
|
722
|
+
.chart-bars .bar{ flex:1; display:flex; flex-direction:column; align-items:center; justify-content:flex-end; gap:7px; height:100%; }
|
|
723
|
+
.chart-bars .bar i{ display:block; width:100%; max-width:44px; border-radius:6px 6px 2px 2px;
|
|
724
|
+
background:linear-gradient(180deg,var(--accent),var(--accent2)); box-shadow:0 0 12px var(--glow);
|
|
725
|
+
height:var(--h,50%); transform:scaleY(0); transform-origin:bottom; }
|
|
726
|
+
.chart-bars .bar b{ font-size:12px; color:var(--accent); font-weight:800; }
|
|
727
|
+
.chart-bars .bar em{ font-style:normal; font-size:11px; color:var(--muted); }
|
|
728
|
+
.slide.active [data-anim-chart="bars"] .bar i{ animation:md-bar-grow .85s cubic-bezier(.3,.8,.4,1) both; animation-delay:calc(var(--bi,0)*100ms); }
|
|
729
|
+
@keyframes md-bar-grow{ from{ transform:scaleY(0); } to{ transform:scaleY(1); } }
|
|
730
|
+
/* 折线描画:走线 dashoffset 归零后圆点按序浮现 */
|
|
731
|
+
.chart-line svg{ width:100%; height:158px; display:block; }
|
|
732
|
+
.chart-line .ln{ stroke:var(--accent); stroke-width:3; fill:none; stroke-linecap:round;
|
|
733
|
+
stroke-dasharray:600; stroke-dashoffset:600; filter:drop-shadow(0 0 5px var(--glow)); }
|
|
734
|
+
.chart-line .pt{ fill:var(--accent2); opacity:0; }
|
|
735
|
+
.slide.active [data-anim-chart="line"] .ln{ animation:md-line-draw 1.15s cubic-bezier(.4,0,.2,1) .12s both; }
|
|
736
|
+
.slide.active [data-anim-chart="line"] .pt{ animation:md-pt-in .45s ease both; animation-delay:calc(.25s + var(--pi,0)*150ms); }
|
|
737
|
+
@keyframes md-line-draw{ to{ stroke-dashoffset:0; } }
|
|
738
|
+
@keyframes md-pt-in{ from{ opacity:0; } to{ opacity:1; } }
|
|
739
|
+
/* 饼图扇入:弧段 dashoffset 从整周长扫入,transform rotate 定段起点,逐段 --pi×140ms 错峰 */
|
|
740
|
+
.chart-pie{ display:flex; justify-content:center; align-items:center; }
|
|
741
|
+
.chart-pie svg{ width:158px; height:158px; }
|
|
742
|
+
.chart-pie .pc{ fill:none; stroke-width:24; transform-box:fill-box; transform-origin:center; }
|
|
743
|
+
.chart-pie .pc.s1{ stroke:var(--accent); }
|
|
744
|
+
.chart-pie .pc.s2{ stroke:var(--accent2); }
|
|
745
|
+
.chart-pie .pc.s3{ stroke:#34d399; }
|
|
746
|
+
.chart-pie .pc.s4{ stroke:#f59e0b; }
|
|
747
|
+
.slide.active [data-anim-chart="pie"] .pc{ animation:md-pie-sweep .9s cubic-bezier(.4,0,.2,1) both; animation-delay:calc(var(--pi,0)*140ms); }
|
|
748
|
+
@keyframes md-pie-sweep{ from{ stroke-dashoffset:var(--po,340); } to{ stroke-dashoffset:0; } }
|
|
749
|
+
/* 仪表扫弧:单弧扫入 + 中心数字 count-up(data-count 由 JS 滚动) */
|
|
750
|
+
.chart-ring{ position:relative; width:158px; height:158px; margin:0 auto; }
|
|
751
|
+
.chart-ring svg{ width:158px; height:158px; }
|
|
752
|
+
.chart-ring .rc-bg{ fill:none; stroke:var(--tag-bg); stroke-width:12; }
|
|
753
|
+
.chart-ring .rc{ fill:none; stroke:var(--accent); stroke-width:12; stroke-linecap:round;
|
|
754
|
+
transform-box:fill-box; transform-origin:center; transform:rotate(-90deg); filter:drop-shadow(0 0 6px var(--glow)); }
|
|
755
|
+
.chart-ring .rc-val{ position:absolute; inset:0; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:2px; }
|
|
756
|
+
.chart-ring .rc-val b{ font-size:32px; font-weight:900; color:var(--text); line-height:1; }
|
|
757
|
+
.chart-ring .rc-val span{ font-size:11px; color:var(--muted); }
|
|
758
|
+
.slide.active [data-anim-chart="ring"] .rc{ animation:md-pie-sweep 1.15s cubic-bezier(.4,0,.2,1) .2s both; }
|
|
759
|
+
@media (prefers-reduced-motion:reduce){
|
|
760
|
+
.slide, .slide.active, .slide.dim{ transition:none; }
|
|
761
|
+
.slide [data-anim], .slide.active [data-anim], .slide [data-anim-emphasis], .slide.leaving [data-anim-leave]{ opacity:1 !important; animation:none !important; }
|
|
762
|
+
.slide [data-anim-chart] .bar i{ transform:none !important; animation:none !important; }
|
|
763
|
+
.slide [data-anim-chart] .ln{ stroke-dashoffset:0 !important; }
|
|
764
|
+
.slide [data-anim-chart] .pc, .slide [data-anim-chart] .rc{ stroke-dashoffset:0 !important; }
|
|
765
|
+
.slide [data-anim-chart] .pt{ opacity:1 !important; }
|
|
766
|
+
}
|
|
767
|
+
|
|
270
768
|
</style>
|
|
271
769
|
</head>
|
|
272
770
|
<body>
|
|
@@ -277,14 +775,19 @@ body:hover .nav{ opacity:1; }
|
|
|
277
775
|
</div>
|
|
278
776
|
<div class="toolbar">
|
|
279
777
|
<div class="group">
|
|
280
|
-
<button class="tbtn" id="btnTemplate" title="
|
|
778
|
+
<button class="tbtn" id="btnTemplate" title="十六套版式模板:可应用到全部页面 / 仅本页 / 勾选页面,支持预览本页,标题自动映射">🎨 模板</button>
|
|
779
|
+
<button class="tbtn" id="btnTheme" title="十六套主题配色面板:色点即点即换,范围可选全部页面或仅本页">🎨 主题</button>
|
|
780
|
+
</div>
|
|
781
|
+
<div class="group" title="编辑:撤销 / 重做(支持模板应用、增删页、换主题等所有编辑操作)">
|
|
782
|
+
<button class="tbtn" id="btnUndo" title="撤销上一步(Ctrl+Z)" disabled>↶ 撤销</button>
|
|
783
|
+
<button class="tbtn" id="btnRedo" title="重做(Ctrl+Shift+Z / Ctrl+Y)" disabled>↷ 重做</button>
|
|
784
|
+
</div>
|
|
785
|
+
<div class="group" title="页面管理:右侧缩略图边栏(新页 / 复页 / 排序 / 删页 / 跳转)">
|
|
786
|
+
<button class="tbtn" id="btnPages" title="右侧边栏:▤ 页面管理 / ⚙ 动画与工具(G 开关)">▤ 页导航</button>
|
|
281
787
|
</div>
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
<button class="tbtn
|
|
285
|
-
<button class="tbtn theme" data-theme="mono" title="mono 极简黑白"></button>
|
|
286
|
-
<button class="tbtn theme" data-theme="warm" title="warm 温暖渐变"></button>
|
|
287
|
-
<button class="tbtn" id="btnScope" title="开启后主题只作用于当前页">⭮ 仅本页</button>
|
|
788
|
+
|
|
789
|
+
<div class="group" title="动画库与复制截图已收纳到右侧边栏 ⚙ 工具 Tab">
|
|
790
|
+
<button class="tbtn" id="btnTools" title="右侧边栏 ⚙ 工具 Tab:动画库(翻页八套 / 入场离场强调 / 标题文字动画)+ 复制与截图">⚙ 工具</button>
|
|
288
791
|
</div>
|
|
289
792
|
<div class="group">
|
|
290
793
|
<button class="tbtn" id="btnPlay">▶ 自动播放</button>
|
|
@@ -298,26 +801,121 @@ body:hover .nav{ opacity:1; }
|
|
|
298
801
|
<label class="tbtn"><input type="checkbox" id="chkFromStart" checked>从头</label>
|
|
299
802
|
</div>
|
|
300
803
|
<div class="group">
|
|
301
|
-
<button class="tbtn" id="btnCopy">⧉ 复制本页</button>
|
|
302
|
-
<button class="tbtn" id="btnCopyMulti">▦ 选页复制</button>
|
|
303
|
-
<button class="tbtn" id="btnShot">📷 截图本页</button>
|
|
304
|
-
<button class="tbtn" id="btnShotMulti">▦ 选页截图</button>
|
|
305
804
|
<button class="tbtn" id="btnFull">⛶ 全屏</button>
|
|
306
805
|
<button class="tbtn help" id="btnHelp">?</button>
|
|
307
806
|
</div>
|
|
308
807
|
</div>
|
|
309
808
|
<div class="pageno" id="pageNo"><b>1</b> / 9</div>
|
|
310
|
-
<div class="hint">← → 翻页 ·
|
|
809
|
+
<div class="hint">← → 翻页 · P 播放 · F 全屏 · G 页面/工具 · Ctrl+Z 撤销 · ? 操作说明</div>
|
|
311
810
|
<button class="nav prev" id="btnPrev">‹</button>
|
|
312
811
|
<button class="nav next" id="btnNext">›</button>
|
|
313
|
-
<
|
|
812
|
+
<aside class="sidepanel" id="sidePanel">
|
|
813
|
+
<div class="sp-tabs">
|
|
814
|
+
<button class="sp-tab on" data-tab="pages" title="页面管理:缩略图跳页、新页、复页、排序、删页">▤ 页面</button>
|
|
815
|
+
<button class="sp-tab" data-tab="tools" title="动画库与页面工具:翻页八套、入场/离场/强调、标题文字动画、复制与截图">⚙ 工具</button>
|
|
816
|
+
<button class="sp-close" id="spClose" title="收起(G)">✕</button>
|
|
817
|
+
</div>
|
|
818
|
+
<div class="sp-pane on" id="panePages">
|
|
819
|
+
<div class="sp-head"><span>页面导航</span>
|
|
820
|
+
<span class="sp-head-ops">
|
|
821
|
+
<button class="sp-add" id="spAdd" title="新增页面:16 版式任选,插在当前页之后">+ 新页</button>
|
|
822
|
+
</span>
|
|
823
|
+
</div>
|
|
824
|
+
<div class="sp-list" id="spList"></div>
|
|
825
|
+
</div>
|
|
826
|
+
<div class="sp-pane" id="paneTools">
|
|
827
|
+
<div class="ts-sec">
|
|
828
|
+
<div class="ts-title">翻页切换</div>
|
|
829
|
+
<div class="tg-grid col4" id="tgGrid">
|
|
830
|
+
<button data-tg="slide-lr">⇢ 滑移</button>
|
|
831
|
+
<button data-tg="fade">◌ 淡入</button>
|
|
832
|
+
<button data-tg="slide-ud">⇣ 上下</button>
|
|
833
|
+
<button data-tg="zoom">◉ 缩放</button>
|
|
834
|
+
<button data-tg="flip">◱ 3D 翻页</button>
|
|
835
|
+
<button data-tg="cube">▦ 立方</button>
|
|
836
|
+
<button data-tg="wipe">▬ 擦除</button>
|
|
837
|
+
<button data-tg="dissolve">✦ 溶解</button>
|
|
838
|
+
</div>
|
|
839
|
+
</div>
|
|
840
|
+
<div class="ts-sec">
|
|
841
|
+
<div class="ts-title">元素动画 <label class="ts-check"><input type="checkbox" id="chkAnim" checked>开启</label></div>
|
|
842
|
+
<div class="scope-seg">
|
|
843
|
+
<span class="ts-lbl">应用范围</span>
|
|
844
|
+
<label class="seg-btn sel"><input type="radio" name="animScope" value="all" checked>全部页面</label>
|
|
845
|
+
<label class="seg-btn"><input type="radio" name="animScope" value="current">仅本页</label>
|
|
846
|
+
</div>
|
|
847
|
+
<div class="ts-sub">入场 12 式 · 点选即用(作用于带入场标记的元素)</div>
|
|
848
|
+
<div class="an-grid" id="enterGrid">
|
|
849
|
+
<button data-a="none">无</button>
|
|
850
|
+
<button data-a="fade-in">淡入</button>
|
|
851
|
+
<button data-a="fade-up">上浮</button>
|
|
852
|
+
<button data-a="fade-down">下沉</button>
|
|
853
|
+
<button data-a="slide-left">左滑</button>
|
|
854
|
+
<button data-a="slide-right">右滑</button>
|
|
855
|
+
<button data-a="slide-up">上滑</button>
|
|
856
|
+
<button data-a="slide-down">下滑</button>
|
|
857
|
+
<button data-a="zoom-in">缩放</button>
|
|
858
|
+
<button data-a="pop">弹跳</button>
|
|
859
|
+
<button data-a="bounce-in">弹入</button>
|
|
860
|
+
<button data-a="flip-in">翻转</button>
|
|
861
|
+
<button data-a="blur">模糊</button>
|
|
862
|
+
</div>
|
|
863
|
+
<div class="ts-sub">离场 12 式 · 翻离该页前自动播放</div>
|
|
864
|
+
<div class="an-grid" id="leaveGrid">
|
|
865
|
+
<button data-l="none">无</button>
|
|
866
|
+
<button data-l="fade-out">淡出</button>
|
|
867
|
+
<button data-l="fade-up-out">上飘</button>
|
|
868
|
+
<button data-l="fade-down-out">坠下</button>
|
|
869
|
+
<button data-l="slide-left-out">左出</button>
|
|
870
|
+
<button data-l="slide-right-out">右出</button>
|
|
871
|
+
<button data-l="slide-up-out">上出</button>
|
|
872
|
+
<button data-l="slide-down-out">下出</button>
|
|
873
|
+
<button data-l="zoom-out">缩小</button>
|
|
874
|
+
<button data-l="zoom-big-out">放大</button>
|
|
875
|
+
<button data-l="flip-out">翻转</button>
|
|
876
|
+
<button data-l="drop-out">坠落</button>
|
|
877
|
+
<button data-l="blur-out">模糊</button>
|
|
878
|
+
</div>
|
|
879
|
+
<div class="ts-sub">强调 8 式 · 循环播放(与入场二选一)</div>
|
|
880
|
+
<div class="an-grid" id="emphGrid">
|
|
881
|
+
<button data-e="none">无</button>
|
|
882
|
+
<button data-e="pulse">脉冲</button>
|
|
883
|
+
<button data-e="swing">摇摆</button>
|
|
884
|
+
<button data-e="shake">抖动</button>
|
|
885
|
+
<button data-e="breathe">呼吸</button>
|
|
886
|
+
<button data-e="flash">闪烁</button>
|
|
887
|
+
<button data-e="tada">弹跳</button>
|
|
888
|
+
<button data-e="spin">旋转</button>
|
|
889
|
+
<button data-e="glow">辉光</button>
|
|
890
|
+
</div>
|
|
891
|
+
<div class="ts-sub">标题文字(默认无动画)</div>
|
|
892
|
+
<div class="tg-grid col4" id="textGrid">
|
|
893
|
+
<button data-ta="none">无动画</button>
|
|
894
|
+
<button data-ta="char">逐字</button>
|
|
895
|
+
<button data-ta="word">逐词</button>
|
|
896
|
+
<button data-ta="line">逐行</button>
|
|
897
|
+
</div>
|
|
898
|
+
</div>
|
|
899
|
+
<div class="ts-sec">
|
|
900
|
+
<div class="ts-title">页面操作</div>
|
|
901
|
+
<div class="tools-ops">
|
|
902
|
+
<button id="btnCopy" title="复制本页文字到剪贴板(C)">⧉ 复制本页</button>
|
|
903
|
+
<button id="btnCopyMulti" title="勾选多页批量复制文字">▦ 选页复制</button>
|
|
904
|
+
<button id="btnShot" title="截图本页为 PNG 2x(S)">📷 截图本页</button>
|
|
905
|
+
<button id="btnShotMulti" title="勾选多页逐张下载 PNG">▦ 选页截图</button>
|
|
906
|
+
</div>
|
|
907
|
+
</div>
|
|
908
|
+
<div class="ts-note">动画点选即应用(范围:全部页面 / 仅本页)并自动记忆;入场与强调作用于带入场标记的元素;标题文字动画将标题拆为字 / 词 / 行错落入场。离场动画在翻离该页前播放。</div>
|
|
909
|
+
</div>
|
|
910
|
+
</aside>
|
|
911
|
+
<main class="stage"><div class="deck" id="deck" data-transition="slide-lr" data-anim="on">
|
|
314
912
|
|
|
315
913
|
<!-- 页 1 封面(classic 模板) -->
|
|
316
914
|
<section class="slide cover active" data-title="封面">
|
|
317
|
-
<div class="logo"></div>
|
|
318
|
-
<div class="s-title">魔法幻灯<br>Magic Deck</div>
|
|
319
|
-
<div class="sub">HTML 形态 · PPT 体验 · 单文件离线放映</div>
|
|
320
|
-
<div class="sign">GENERATED BY SKILLFORGE</div>
|
|
915
|
+
<div class="logo" data-anim="pop"></div>
|
|
916
|
+
<div class="s-title" data-anim="fade-up">魔法幻灯<br>Magic Deck</div>
|
|
917
|
+
<div class="sub" data-anim="fade-up" data-anim-delay="120">HTML 形态 · PPT 体验 · 单文件离线放映</div>
|
|
918
|
+
<div class="sign" data-anim="fade-in" data-anim-delay="300">GENERATED BY SKILLFORGE</div>
|
|
321
919
|
</section>
|
|
322
920
|
|
|
323
921
|
<!-- 页 2 目录 -->
|
|
@@ -329,6 +927,9 @@ body:hover .nav{ opacity:1; }
|
|
|
329
927
|
<div class="toc-item" data-goto="4"><span class="no">03</span><span class="t">杂志画册版式</span><span class="pg">第 5 页</span></div>
|
|
330
928
|
<div class="toc-item" data-goto="5"><span class="no">04</span><span class="t">黑金发布版式</span><span class="pg">第 6 页</span></div>
|
|
331
929
|
<div class="toc-item" data-goto="6"><span class="no">05</span><span class="t">时间线叙事版式</span><span class="pg">第 7 页</span></div>
|
|
930
|
+
<div class="toc-item" data-goto="8"><span class="no">06</span><span class="t">更多版式演示</span><span class="pg">第 9-12 页</span></div>
|
|
931
|
+
<div class="toc-item" data-goto="12"><span class="no">07</span><span class="t">图表动画演示</span><span class="pg">第 13 页</span></div>
|
|
932
|
+
<div class="toc-item" data-goto="13"><span class="no">08</span><span class="t">领域模板库</span><span class="pg">第 14 页</span></div>
|
|
332
933
|
</div>
|
|
333
934
|
</section>
|
|
334
935
|
|
|
@@ -374,7 +975,7 @@ body:hover .nav{ opacity:1; }
|
|
|
374
975
|
<section class="slide" data-title="时间线叙事" data-template="timeline">
|
|
375
976
|
<div class="s-head"><h2>里程碑</h2><span class="tag">TIMELINE</span></div>
|
|
376
977
|
<div class="grid3">
|
|
377
|
-
<div class="card"><h4>立项与架构<span class="en">2026 Q1</span></h4><p
|
|
978
|
+
<div class="card"><h4>立项与架构<span class="en">2026 Q1</span></h4><p>完成技术选型与十六主题变量体系。</p></div>
|
|
378
979
|
<div class="card"><h4>模板库建设<span class="en">2026 Q2</span></h4><p>五套版式骨架与主题正交组合。</p></div>
|
|
379
980
|
<div class="card"><h4>单页换肤<span class="en">2026 Q3</span></h4><p>整份或单页自由切换主题。</p></div>
|
|
380
981
|
</div>
|
|
@@ -391,7 +992,126 @@ body:hover .nav{ opacity:1; }
|
|
|
391
992
|
</div>
|
|
392
993
|
</section>
|
|
393
994
|
|
|
394
|
-
<!-- 页 9
|
|
995
|
+
<!-- 页 9 steps 流程步骤(箭头步骤条由包装器生成) -->
|
|
996
|
+
<section class="slide" data-title="流程步骤" data-template="steps">
|
|
997
|
+
<div class="s-head"><h2>发布流程四步走</h2><span class="tag">STEPS</span></div>
|
|
998
|
+
<div class="grid4">
|
|
999
|
+
<div class="card"><h4>撰写内容<span class="en">Draft</span></h4><p>结构与文案一气呵成。</p></div>
|
|
1000
|
+
<div class="card"><h4>套用版式<span class="en">Layout</span></h4><p>十六套版式任意切换。</p></div>
|
|
1001
|
+
<div class="card"><h4>细节打磨<span class="en">Polish</span></h4><p>主题配色逐页微调。</p></div>
|
|
1002
|
+
<div class="card"><h4>发布放映<span class="en">Publish</span></h4><p>全屏放映或分享 HTML。</p></div>
|
|
1003
|
+
</div>
|
|
1004
|
+
</section>
|
|
1005
|
+
|
|
1006
|
+
<!-- 页 10 vintage 复古报纸(双栏报纸结构由包装器生成) -->
|
|
1007
|
+
<section class="slide" data-title="复古报纸" data-template="vintage">
|
|
1008
|
+
<div class="s-head"><h2>行业快讯</h2><span class="tag">VINTAGE</span></div>
|
|
1009
|
+
<div class="grid2">
|
|
1010
|
+
<div class="card"><h4>双栏排印<span class="en">Columns</span></h4><p>报纸式双栏,虚线分隔,衬线标题,刊头气质。</p></div>
|
|
1011
|
+
<div class="card"><h4>复古气质<span class="en">Retro</span></h4><p>适合文化、历史与人文主题的叙事表达。</p></div>
|
|
1012
|
+
</div>
|
|
1013
|
+
</section>
|
|
1014
|
+
|
|
1015
|
+
<!-- 页 11 poster 海报宣传(斜切色带由包装器生成) -->
|
|
1016
|
+
<section class="slide" data-title="海报宣传" data-template="poster">
|
|
1017
|
+
<div class="s-head"><h2>年度盛典</h2><span class="tag">POSTER</span></div>
|
|
1018
|
+
<ul class="points">
|
|
1019
|
+
<li>主会场 · 主题演讲</li>
|
|
1020
|
+
<li>分论坛 · 产品发布</li>
|
|
1021
|
+
<li>晚宴 · 颁奖典礼</li>
|
|
1022
|
+
</ul>
|
|
1023
|
+
</section>
|
|
1024
|
+
|
|
1025
|
+
<!-- 页 12 finance 金融报表(仪表环由包装器生成) -->
|
|
1026
|
+
<section class="slide" data-title="金融报表" data-template="finance">
|
|
1027
|
+
<div class="s-head"><h2>经营指标</h2><span class="tag">FINANCE</span></div>
|
|
1028
|
+
<div class="grid3">
|
|
1029
|
+
<div class="bignum"><b>86%</b><span>毛利率</span></div>
|
|
1030
|
+
<div class="bignum"><b>42%</b><span>增长率</span></div>
|
|
1031
|
+
<div class="bignum"><b>9.8</b><span>客户评分</span></div>
|
|
1032
|
+
</div>
|
|
1033
|
+
</section>
|
|
1034
|
+
|
|
1035
|
+
<!-- 页 14 图表动画(bars/line/pie/ring 四式,翻到本页自动播放,翻离再翻回重放) -->
|
|
1036
|
+
<section class="slide" data-title="图表动画">
|
|
1037
|
+
<div class="s-head"><h2>图表动画</h2><span class="tag">CHARTS</span></div>
|
|
1038
|
+
<div class="grid2">
|
|
1039
|
+
<div class="chart-card" data-anim-chart="bars">
|
|
1040
|
+
<div class="cc-head"><h4>季度销售额</h4><span class="en">BARS GROW</span></div>
|
|
1041
|
+
<div class="chart-bars">
|
|
1042
|
+
<div class="bar" style="--bi:0"><b>128</b><i style="--h:42%"></i><em>Q1</em></div>
|
|
1043
|
+
<div class="bar" style="--bi:1"><b>186</b><i style="--h:61%"></i><em>Q2</em></div>
|
|
1044
|
+
<div class="bar" style="--bi:2"><b>243</b><i style="--h:80%"></i><em>Q3</em></div>
|
|
1045
|
+
<div class="bar" style="--bi:3"><b>298</b><i style="--h:97%"></i><em>Q4</em></div>
|
|
1046
|
+
</div>
|
|
1047
|
+
</div>
|
|
1048
|
+
<div class="chart-card" data-anim-chart="line">
|
|
1049
|
+
<div class="cc-head"><h4>用户增长趋势</h4><span class="en">LINE DRAW</span></div>
|
|
1050
|
+
<div class="chart-line">
|
|
1051
|
+
<svg viewBox="0 0 300 158" preserveAspectRatio="none">
|
|
1052
|
+
<polyline class="ln" points="0,130 60,112 120,98 180,66 240,42 300,20"/>
|
|
1053
|
+
<circle class="pt" style="--pi:0" cx="0" cy="130" r="4"/>
|
|
1054
|
+
<circle class="pt" style="--pi:1" cx="60" cy="112" r="4"/>
|
|
1055
|
+
<circle class="pt" style="--pi:2" cx="120" cy="98" r="4"/>
|
|
1056
|
+
<circle class="pt" style="--pi:3" cx="180" cy="66" r="4"/>
|
|
1057
|
+
<circle class="pt" style="--pi:4" cx="240" cy="42" r="4"/>
|
|
1058
|
+
<circle class="pt" style="--pi:5" cx="300" cy="20" r="4"/>
|
|
1059
|
+
</svg>
|
|
1060
|
+
</div>
|
|
1061
|
+
</div>
|
|
1062
|
+
<div class="chart-card" data-anim-chart="pie">
|
|
1063
|
+
<div class="cc-head"><h4>渠道占比</h4><span class="en">PIE SWEEP</span></div>
|
|
1064
|
+
<div class="chart-pie">
|
|
1065
|
+
<svg viewBox="0 0 150 150">
|
|
1066
|
+
<circle class="pc s1" cx="75" cy="75" r="56" style="--po:351.86; --pi:0" stroke-dasharray="158.3 193.6" transform="rotate(0)"/>
|
|
1067
|
+
<circle class="pc s2" cx="75" cy="75" r="56" style="--po:351.86; --pi:1" stroke-dasharray="105.6 246.3" transform="rotate(162)"/>
|
|
1068
|
+
<circle class="pc s3" cx="75" cy="75" r="56" style="--po:351.86; --pi:2" stroke-dasharray="88 263.9" transform="rotate(270)"/>
|
|
1069
|
+
</svg>
|
|
1070
|
+
</div>
|
|
1071
|
+
</div>
|
|
1072
|
+
<div class="chart-card" data-anim-chart="ring">
|
|
1073
|
+
<div class="cc-head"><h4>年度达成率</h4><span class="en">RING SWEEP</span></div>
|
|
1074
|
+
<div class="chart-ring">
|
|
1075
|
+
<svg viewBox="0 0 150 150">
|
|
1076
|
+
<circle class="rc-bg" cx="75" cy="75" r="62"/>
|
|
1077
|
+
<circle class="rc" cx="75" cy="75" r="62" style="--po:389.56" stroke-dasharray="280.5 109.1"/>
|
|
1078
|
+
</svg>
|
|
1079
|
+
<div class="rc-val"><b data-count="72" data-count-dec="0">0</b><span>目标达成</span></div>
|
|
1080
|
+
</div>
|
|
1081
|
+
</div>
|
|
1082
|
+
</div>
|
|
1083
|
+
</section>
|
|
1084
|
+
|
|
1085
|
+
<!-- 页 15 领域模板库(二十一套领域 / 业务成套模板,点卡片直达面板生成整套页面) -->
|
|
1086
|
+
<section class="slide" data-title="领域模板">
|
|
1087
|
+
<div class="s-head"><h2>领域模板库 · 二十一套</h2><span class="tag">DOMAIN</span></div>
|
|
1088
|
+
<div class="prof-grid">
|
|
1089
|
+
<div class="card prof-demo" data-prof="thesis" data-anim="fade-up" data-anim-delay="40"><h4>毕业答辩<span class="en">Thesis</span></h4></div>
|
|
1090
|
+
<div class="card prof-demo" data-prof="proposal" data-anim="fade-up" data-anim-delay="65"><h4>开题报告<span class="en">Proposal</span></h4></div>
|
|
1091
|
+
<div class="card prof-demo" data-prof="teaching" data-anim="fade-up" data-anim-delay="90"><h4>教学课件<span class="en">Teaching</span></h4></div>
|
|
1092
|
+
<div class="card prof-demo" data-prof="report" data-anim="fade-up" data-anim-delay="115"><h4>年终汇报<span class="en">Report</span></h4></div>
|
|
1093
|
+
<div class="card prof-demo" data-prof="competition" data-anim="fade-up" data-anim-delay="140"><h4>竞聘述职<span class="en">Competition</span></h4></div>
|
|
1094
|
+
<div class="card prof-demo" data-prof="plan" data-anim="fade-up" data-anim-delay="165"><h4>商业计划书<span class="en">BizPlan</span></h4></div>
|
|
1095
|
+
<div class="card prof-demo" data-prof="hiring" data-anim="fade-up" data-anim-delay="190"><h4>求职简历<span class="en">Resume</span></h4></div>
|
|
1096
|
+
<div class="card prof-demo" data-prof="product" data-anim="fade-up" data-anim-delay="215"><h4>产品发布<span class="en">Product</span></h4></div>
|
|
1097
|
+
<div class="card prof-demo" data-prof="tech" data-anim="fade-up" data-anim-delay="240"><h4>科技发布<span class="en">Tech</span></h4></div>
|
|
1098
|
+
<div class="card prof-demo" data-prof="marketing" data-anim="fade-up" data-anim-delay="265"><h4>营销方案<span class="en">Marketing</span></h4></div>
|
|
1099
|
+
<div class="card prof-demo" data-prof="training" data-anim="fade-up" data-anim-delay="290"><h4>企业培训<span class="en">Training</span></h4></div>
|
|
1100
|
+
<div class="card prof-demo" data-prof="ceremony" data-anim="fade-up" data-anim-delay="315"><h4>年会盛典<span class="en">Ceremony</span></h4></div>
|
|
1101
|
+
<div class="card prof-demo" data-prof="finance" data-anim="fade-up" data-anim-delay="340"><h4>金融分析<span class="en">Finance</span></h4></div>
|
|
1102
|
+
<div class="card prof-demo" data-prof="medical" data-anim="fade-up" data-anim-delay="365"><h4>医疗科普<span class="en">Medical</span></h4></div>
|
|
1103
|
+
<div class="card prof-demo" data-prof="law" data-anim="fade-up" data-anim-delay="390"><h4>法律合规<span class="en">Legal</span></h4></div>
|
|
1104
|
+
<div class="card prof-demo" data-prof="gov" data-anim="fade-up" data-anim-delay="415"><h4>政务汇报<span class="en">Government</span></h4></div>
|
|
1105
|
+
<div class="card prof-demo" data-prof="party" data-anim="fade-up" data-anim-delay="440"><h4>党建汇报<span class="en">Party</span></h4></div>
|
|
1106
|
+
<div class="card prof-demo" data-prof="food" data-anim="fade-up" data-anim-delay="465"><h4>餐饮品牌<span class="en">Food</span></h4></div>
|
|
1107
|
+
<div class="card prof-demo" data-prof="travel" data-anim="fade-up" data-anim-delay="490"><h4>旅游攻略<span class="en">Travel</span></h4></div>
|
|
1108
|
+
<div class="card prof-demo" data-prof="festival" data-anim="fade-up" data-anim-delay="515"><h4>节日庆典<span class="en">Festival</span></h4></div>
|
|
1109
|
+
<div class="card prof-demo" data-prof="charity" data-anim="fade-up" data-anim-delay="540"><h4>公益慈善<span class="en">Charity</span></h4></div>
|
|
1110
|
+
</div>
|
|
1111
|
+
<div class="demo-tip">点任意卡片,直接打开模板面板并选中该套模板,一键「生成成套页面」——封面 · 目录 · 内容页 · 图表页整份生成,可撤销</div>
|
|
1112
|
+
</section>
|
|
1113
|
+
|
|
1114
|
+
<!-- 页 13 结束页 -->
|
|
395
1115
|
<section class="slide endpage" data-title="结束">
|
|
396
1116
|
<div class="s-title">谢谢观看</div>
|
|
397
1117
|
<p>按 F 全屏放映 · 按 ? 查看全部热键</p>
|
|
@@ -410,19 +1130,25 @@ body:hover .nav{ opacity:1; }
|
|
|
410
1130
|
<tr><td><kbd>F</kbd></td><td>全屏放映(操作元素自动退场)</td></tr>
|
|
411
1131
|
<tr><td><kbd>1</kbd>-<kbd>9</kbd></td><td>数字直达对应页</td></tr>
|
|
412
1132
|
<tr><td><kbd>Home</kbd> / <kbd>End</kbd></td><td>首页 / 末页</td></tr>
|
|
1133
|
+
<tr><td><kbd>G</kbd></td><td>右侧边栏:▤ 页面 / ⚙ 动画与工具</td></tr>
|
|
1134
|
+
<tr><td><kbd>Ctrl</kbd>+<kbd>Z</kbd> / <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>Z</kbd></td><td>撤销 / 重做</td></tr>
|
|
413
1135
|
<tr><td><kbd>Esc</kbd></td><td>关弹层 / 退全屏</td></tr>
|
|
414
1136
|
</table>
|
|
415
|
-
<div class="help-note"
|
|
1137
|
+
<div class="help-note">「🎨 主题」面板 16 套配色即点即换,范围可选全部页面或仅本页。「🎨 模板」=十六套版式模板应用到全部页/仅本页/勾选页,支持「预览本页」先看效果,标题自动映射,切回经典商务即恢复原排版。右侧边栏双 Tab:「▤ 页面」缩略图跳页、悬停操作条复页/上移/下移/删页,头部「+新页」选版式插页;「⚙ 工具」收纳动画库(翻页八套 + 入场十二式 + 离场十二式 + 强调八式 + 标题文字逐字/逐词/逐行,可设全部页面/仅本页范围)与复制截图(本页/选页批量,只含主体内容,截图逐张下载 PNG),点选即应用并自动记忆。「↶/↷」撤销重做(Ctrl+Z)。</div>
|
|
416
1138
|
</div>
|
|
417
1139
|
</div>
|
|
418
1140
|
<div class="help-mask" id="tplMask">
|
|
419
1141
|
<div class="tpl-panel">
|
|
420
1142
|
<div class="cp-head">
|
|
421
1143
|
<h3>应用模板</h3>
|
|
422
|
-
<
|
|
1144
|
+
<div class="tpl-tabs">
|
|
1145
|
+
<button type="button" class="tpl-tab on" id="tabLayout">🎨 版式</button>
|
|
1146
|
+
<button type="button" class="tpl-tab" id="tabProf">💼 领域</button>
|
|
1147
|
+
</div>
|
|
1148
|
+
<span class="tpl-head-note" id="tplHeadNote">模板只改版式,内容与配色不动;先「预览本页」看效果,满意再应用</span>
|
|
423
1149
|
</div>
|
|
424
1150
|
<div class="tpl-cards" id="tplCards"></div>
|
|
425
|
-
<div class="tpl-scope">
|
|
1151
|
+
<div class="tpl-scope" id="tplScopeRow">
|
|
426
1152
|
<label class="sel"><input type="radio" name="tplScope" value="all" checked>全部页面</label>
|
|
427
1153
|
<label><input type="radio" name="tplScope" value="current">仅本页</label>
|
|
428
1154
|
<label><input type="radio" name="tplScope" value="selected">选择页面</label>
|
|
@@ -430,11 +1156,29 @@ body:hover .nav{ opacity:1; }
|
|
|
430
1156
|
<div class="cp-list" id="tplList"></div>
|
|
431
1157
|
<div class="cp-foot">
|
|
432
1158
|
<button class="tbtn" id="tplCancel">取消</button>
|
|
1159
|
+
<button class="tbtn" id="tplPreview">👁 预览本页</button>
|
|
433
1160
|
<button class="tbtn primary" id="tplDo">应用模板</button>
|
|
434
1161
|
</div>
|
|
435
1162
|
<div class="help-note">标题自动映射到模板固定位置:timeline 取卡片标题做节点、keynote 取页标题做大观点、magazine 左文右图分栏,切回「经典商务」即恢复原始排版,内容一条不丢。模板与主题正交——换模板后配色保持不变。</div>
|
|
436
1163
|
</div>
|
|
437
1164
|
</div>
|
|
1165
|
+
<div class="help-mask" id="themeMask">
|
|
1166
|
+
<div class="theme-panel">
|
|
1167
|
+
<div class="cp-head">
|
|
1168
|
+
<h3>切换主题</h3>
|
|
1169
|
+
<span class="tpl-head-note">点色点立即生效,可连点对比效果;Esc 或 ✕ 关闭</span>
|
|
1170
|
+
</div>
|
|
1171
|
+
<div class="tpl-scope">
|
|
1172
|
+
<label class="sel"><input type="radio" name="thScope" value="all" checked>全部页面</label>
|
|
1173
|
+
<label><input type="radio" name="thScope" value="current">仅本页</label>
|
|
1174
|
+
</div>
|
|
1175
|
+
<div class="theme-grid" id="themeGrid"></div>
|
|
1176
|
+
<div class="cp-foot">
|
|
1177
|
+
<button class="tbtn" id="thClose">✕ 关闭</button>
|
|
1178
|
+
</div>
|
|
1179
|
+
<div class="help-note">主题与模板正交:换主题不动版式与内容。「仅本页」时色点只改当前页;整份切换会统一覆盖所有页面配色。</div>
|
|
1180
|
+
</div>
|
|
1181
|
+
</div>
|
|
438
1182
|
<div class="help-mask" id="copyMask">
|
|
439
1183
|
<div class="copy-panel">
|
|
440
1184
|
<div class="cp-head">
|
|
@@ -462,14 +1206,26 @@ body:hover .nav{ opacity:1; }
|
|
|
462
1206
|
<div class="help-note">逐张下载 PNG(2560×1440 两倍清晰度);浏览器首次会询问「下载多个文件」的许可,点允许即可。</div>
|
|
463
1207
|
</div>
|
|
464
1208
|
</div>
|
|
1209
|
+
<div class="help-mask" id="addMask">
|
|
1210
|
+
<div class="add-panel">
|
|
1211
|
+
<div class="cp-head">
|
|
1212
|
+
<h3>新增页面</h3>
|
|
1213
|
+
<span class="add-head-note">选择版式,插在当前页之后</span>
|
|
1214
|
+
</div>
|
|
1215
|
+
<div class="add-cards" id="addCards"></div>
|
|
1216
|
+
<div class="cp-foot">
|
|
1217
|
+
<button class="tbtn" id="addCancel">取消</button>
|
|
1218
|
+
</div>
|
|
1219
|
+
<div class="help-note">新页自带版式占位内容,落盘后直接改文字即可。所有编辑操作(套模板、增删页、换主题)都支持撤销 / 重做(Ctrl+Z / Ctrl+Shift+Z)。</div>
|
|
1220
|
+
</div>
|
|
1221
|
+
</div>
|
|
465
1222
|
<script>
|
|
466
|
-
var slides = Array.prototype.slice.call(document.querySelectorAll('.slide'));
|
|
1223
|
+
var slides = Array.prototype.slice.call(document.querySelectorAll('#deck .slide'));
|
|
467
1224
|
var N = slides.length;
|
|
468
1225
|
var cur = 0, timer = null, playing = false;
|
|
469
1226
|
var progFill = document.getElementById('progFill');
|
|
470
1227
|
var pageNo = document.getElementById('pageNo');
|
|
471
1228
|
var btnPlay = document.getElementById('btnPlay');
|
|
472
|
-
var btnScope = document.getElementById('btnScope');
|
|
473
1229
|
var selInterval = document.getElementById('selInterval');
|
|
474
1230
|
var chkLoop = document.getElementById('chkLoop');
|
|
475
1231
|
var chkFromStart = document.getElementById('chkFromStart');
|
|
@@ -482,10 +1238,30 @@ function go(i){
|
|
|
482
1238
|
});
|
|
483
1239
|
progFill.style.width = ((cur + 1) / N * 100) + '%';
|
|
484
1240
|
pageNo.innerHTML = '<b>' + (cur + 1) + '</b> / ' + N;
|
|
1241
|
+
thumbCur();
|
|
1242
|
+
/* 入场动画重播:翻到当前页时重置其 [data-anim] 元素,错落入场重新播放 */
|
|
1243
|
+
var curEl = slides[cur];
|
|
1244
|
+
if (curEl) curEl.querySelectorAll('[data-anim]').forEach(function(el){
|
|
1245
|
+
el.style.animation = 'none';
|
|
1246
|
+
void el.offsetWidth;
|
|
1247
|
+
el.style.animation = '';
|
|
1248
|
+
});
|
|
1249
|
+
/* 图表数字滚动:翻到页时数字从 0 滚到目标值(data-count),与图表动画同源重放 */
|
|
1250
|
+
if (curEl) curEl.querySelectorAll('[data-count]').forEach(function(el){
|
|
1251
|
+
var target = parseFloat(el.getAttribute('data-count'));
|
|
1252
|
+
var dec = parseInt(el.getAttribute('data-count-dec') || '0', 10);
|
|
1253
|
+
if (!isFinite(target)) return;
|
|
1254
|
+
var t0 = performance.now(), dur = 900;
|
|
1255
|
+
(function tick(t){
|
|
1256
|
+
var k = Math.min(1, (t - t0) / dur); k = 1 - Math.pow(1 - k, 3);
|
|
1257
|
+
el.textContent = (target * k).toFixed(dec);
|
|
1258
|
+
if (k < 1) requestAnimationFrame(tick);
|
|
1259
|
+
})(t0);
|
|
1260
|
+
});
|
|
485
1261
|
if (location.hash !== '#/' + (cur + 1)) history.replaceState(null, '', '#/' + (cur + 1));
|
|
486
1262
|
}
|
|
487
|
-
function next(){ if (cur < N - 1)
|
|
488
|
-
function prev(){ if (cur > 0)
|
|
1263
|
+
function next(){ if (cur < N - 1) leaveThenGo(cur + 1); else if (chkLoop.checked) leaveThenGo(0); }
|
|
1264
|
+
function prev(){ if (cur > 0) leaveThenGo(cur - 1); else if (chkLoop.checked) leaveThenGo(N - 1); }
|
|
489
1265
|
function stopPlay(){ if (timer){ clearInterval(timer); timer = null; } playing = false; btnPlay.classList.remove('on'); btnPlay.textContent = '▶ 自动播放'; }
|
|
490
1266
|
function startPlay(){
|
|
491
1267
|
var sec = parseInt(selInterval.value, 10); if (!isFinite(sec) || sec < 1) sec = 5;
|
|
@@ -493,12 +1269,18 @@ function startPlay(){
|
|
|
493
1269
|
stopPlay();
|
|
494
1270
|
playing = true; btnPlay.classList.add('on'); btnPlay.textContent = '⏸ 暂停';
|
|
495
1271
|
timer = setInterval(function(){
|
|
496
|
-
if (cur < N - 1)
|
|
1272
|
+
if (cur < N - 1) leaveThenGo(cur + 1); else if (chkLoop.checked) leaveThenGo(0); else stopPlay();
|
|
497
1273
|
}, sec * 1000);
|
|
498
1274
|
}
|
|
499
1275
|
btnPlay.addEventListener('click', function(){ playing ? stopPlay() : startPlay(); });
|
|
500
1276
|
|
|
501
|
-
/* ──
|
|
1277
|
+
/* ── 主题切换(🎨 主题面板:16 色点网格即点即换,范围全部 / 仅本页) ── */
|
|
1278
|
+
var THEMES = [
|
|
1279
|
+
['tech','深蓝科技','#0ea5e9'], ['biz','浅色商务','#2563eb'], ['mono','极简黑白','#111111'], ['warm','温暖渐变','#d97706'],
|
|
1280
|
+
['aurora','极光紫','#5e6ad2'], ['dracula','德古拉紫','#bd93f9'], ['nord','北欧冰蓝','#88c0d0'], ['midnight','东京夜色','#7aa2f7'],
|
|
1281
|
+
['matrix','终端荧光绿','#00ff9c'], ['cyber','赛博霓虹','#ff2d78'], ['apple','苹果极简','#0071e3'], ['stripe','条纹紫蓝','#635bff'],
|
|
1282
|
+
['notion','纸感暖白','#2383e2'], ['gruvbox','复古暖橙','#fe8019'], ['gold','黑金奢华','#d4af37'], ['ocean','深洋蓝','#38bdf8']
|
|
1283
|
+
];
|
|
502
1284
|
function setGlobalTheme(name){
|
|
503
1285
|
document.documentElement.setAttribute('data-theme', name);
|
|
504
1286
|
slides.forEach(function(s){ s.removeAttribute('data-theme'); });
|
|
@@ -506,27 +1288,378 @@ function setGlobalTheme(name){
|
|
|
506
1288
|
function setSlideTheme(name){
|
|
507
1289
|
slides[cur].setAttribute('data-theme', name);
|
|
508
1290
|
}
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
1291
|
+
var themeMask = document.getElementById('themeMask');
|
|
1292
|
+
var themeGrid = document.getElementById('themeGrid');
|
|
1293
|
+
function activeThemeName(){
|
|
1294
|
+
var sc = themeMask.querySelector('input[name="thScope"]:checked');
|
|
1295
|
+
if (sc && sc.value === 'current'){
|
|
1296
|
+
var st = slides[cur].getAttribute('data-theme');
|
|
1297
|
+
if (st) return st;
|
|
1298
|
+
}
|
|
1299
|
+
return document.documentElement.getAttribute('data-theme') || 'tech';
|
|
1300
|
+
}
|
|
1301
|
+
function renderThemeDots(){
|
|
1302
|
+
var active = activeThemeName();
|
|
1303
|
+
var html = '';
|
|
1304
|
+
THEMES.forEach(function(t){
|
|
1305
|
+
html += '<div class="th-item' + (t[0] === active ? ' on' : '') + '" data-theme="' + t[0] + '">'
|
|
1306
|
+
+ '<span class="th-dot" style="background:' + t[2] + '"></span><span>' + t[1] + '</span></div>';
|
|
514
1307
|
});
|
|
1308
|
+
themeGrid.innerHTML = html;
|
|
1309
|
+
}
|
|
1310
|
+
function openThemePanel(){
|
|
1311
|
+
renderThemeDots();
|
|
1312
|
+
closeCopyPanel(); closeShotPanel(); closeTplPanel(); addMask.classList.remove('open');
|
|
1313
|
+
themeMask.classList.add('open');
|
|
1314
|
+
}
|
|
1315
|
+
function closeThemePanel(){ themeMask.classList.remove('open'); }
|
|
1316
|
+
document.getElementById('btnTheme').addEventListener('click', openThemePanel);
|
|
1317
|
+
document.getElementById('thClose').addEventListener('click', closeThemePanel);
|
|
1318
|
+
themeMask.addEventListener('click', function(e){ if (e.target === themeMask) closeThemePanel(); });
|
|
1319
|
+
themeMask.addEventListener('change', function(e){
|
|
1320
|
+
if (e.target.name === 'thScope'){
|
|
1321
|
+
Array.prototype.forEach.call(themeMask.querySelectorAll('.tpl-scope label'), function(l){
|
|
1322
|
+
l.classList.toggle('sel', l.querySelector('input') === e.target);
|
|
1323
|
+
});
|
|
1324
|
+
renderThemeDots();
|
|
1325
|
+
}
|
|
515
1326
|
});
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
1327
|
+
themeGrid.addEventListener('click', function(e){
|
|
1328
|
+
var it = e.target.closest('.th-item');
|
|
1329
|
+
if (!it) return;
|
|
1330
|
+
pushUndo();
|
|
1331
|
+
var sc = themeMask.querySelector('input[name="thScope"]:checked');
|
|
1332
|
+
if (sc && sc.value === 'current') setSlideTheme(it.getAttribute('data-theme'));
|
|
1333
|
+
else setGlobalTheme(it.getAttribute('data-theme'));
|
|
1334
|
+
renderThemeDots();
|
|
1335
|
+
buildThumbs();
|
|
519
1336
|
});
|
|
520
1337
|
|
|
521
1338
|
|
|
522
1339
|
/* ── 模板应用(全部/本页/选页;标题自动映射到模板固定位置,内容不丢) ── */
|
|
523
1340
|
var TPLS = [
|
|
524
|
-
{ id:'classic', name:'经典商务', ic:'▦', ds:'左色条标题 + 卡片栅格,稳重大方'
|
|
525
|
-
|
|
526
|
-
{ id:'
|
|
527
|
-
|
|
528
|
-
{ id:'
|
|
1341
|
+
{ id:'classic', name:'经典商务', ic:'▦', ds:'左色条标题 + 卡片栅格,稳重大方',
|
|
1342
|
+
mini:'<i style="left:5%;top:18%;width:2.5%;height:64%;background:var(--accent)"></i><i style="left:11%;top:18%;width:34%;height:12%;background:var(--text);opacity:.8"></i><i style="left:11%;top:40%;right:6%;height:42%;border:1px solid var(--border);background:var(--panel)"></i><i style="left:14%;top:48%;width:22%;height:10%;background:var(--accent);opacity:.25"></i>' },
|
|
1343
|
+
{ id:'minimal', name:'极简留白', ic:'▫', ds:'居中大标题 + 无边框要点,安静克制',
|
|
1344
|
+
mini:'<i style="left:30%;top:20%;width:40%;height:8%;background:var(--text);opacity:.85"></i><i style="left:14%;top:40%;width:72%;height:5%;background:var(--border)"></i><i style="left:14%;top:56%;width:60%;height:5%;background:var(--border)"></i><i style="left:14%;top:72%;width:68%;height:5%;background:var(--border)"></i>' },
|
|
1345
|
+
{ id:'magazine', name:'杂志画册', ic:'▤', ds:'超大标题跨版 + 左文右图 + 大数字带',
|
|
1346
|
+
mini:'<i style="left:5%;top:14%;width:56%;height:18%;background:var(--text);opacity:.85"></i><i style="left:5%;top:40%;width:34%;height:8%;background:var(--muted);opacity:.6"></i><i style="left:5%;top:54%;width:42%;height:8%;background:var(--muted);opacity:.6"></i><i style="left:68%;top:14%;width:27%;height:48%;background:linear-gradient(135deg,var(--accent),var(--accent2));opacity:.75"></i>' },
|
|
1347
|
+
{ id:'keynote', name:'黑金发布', ic:'◉', ds:'每页一个核心观点,大字居中 + 环形进度',
|
|
1348
|
+
mini:'<i style="left:42%;top:10%;width:16%;height:34%;border-radius:50%;background:conic-gradient(var(--accent) 0 70%, var(--border) 70% 100%)"></i><i style="left:30%;top:52%;width:40%;height:10%;background:var(--text);opacity:.85"></i><i style="left:36%;top:72%;width:28%;height:6%;background:var(--border)"></i>' },
|
|
1349
|
+
{ id:'timeline', name:'时间线叙事', ic:'☰', ds:'竖线时间轴 + 节点卡片,适合历程回顾',
|
|
1350
|
+
mini:'<i style="left:16%;top:8%;width:1.5%;height:84%;background:var(--accent)"></i><i style="left:10%;top:10%;width:9%;height:20%;border-radius:50%;background:var(--accent)"></i><i style="left:24%;top:10%;width:70%;height:14%;background:var(--panel);border:1px solid var(--border)"></i><i style="left:10%;top:40%;width:9%;height:20%;border-radius:50%;background:var(--accent)"></i><i style="left:24%;top:40%;width:70%;height:14%;background:var(--panel);border:1px solid var(--border)"></i><i style="left:10%;top:70%;width:9%;height:20%;border-radius:50%;background:var(--accent)"></i><i style="left:24%;top:70%;width:70%;height:14%;background:var(--panel);border:1px solid var(--border)"></i>' },
|
|
1351
|
+
{ id:'steps', name:'流程步骤', ic:'⇢', ds:'箭头连接的步骤条,适合流程与方法论',
|
|
1352
|
+
mini:'<i style="left:5%;top:26%;width:24%;height:48%;border-radius:6px;background:var(--panel);border:1px solid var(--accent)"></i><i style="left:38%;top:26%;width:24%;height:48%;border-radius:6px;background:var(--panel);border:1px solid var(--accent)"></i><i style="left:71%;top:26%;width:24%;height:48%;border-radius:6px;background:var(--panel);border:1px solid var(--accent)"></i><i style="left:30%;top:42%;width:0;height:0;border-top:5px solid transparent;border-bottom:5px solid transparent;border-left:8px solid var(--accent)"></i><i style="left:63%;top:42%;width:0;height:0;border-top:5px solid transparent;border-bottom:5px solid transparent;border-left:8px solid var(--accent)"></i>' },
|
|
1353
|
+
{ id:'poster', name:'海报宣传', ic:'▰', ds:'海报大字 + 斜切色带,适合活动与品牌',
|
|
1354
|
+
mini:'<i style="left:5%;top:12%;width:70%;height:14%;background:linear-gradient(90deg,var(--accent),var(--accent2));clip-path:polygon(0 0,94% 0,100% 50%,94% 100%,0 100%)"></i><i style="left:25%;top:40%;width:70%;height:14%;background:linear-gradient(90deg,var(--accent2),var(--accent));clip-path:polygon(6% 0,100% 0,100% 100%,6% 100%,0 50%)"></i><i style="left:5%;top:70%;width:60%;height:14%;background:linear-gradient(90deg,var(--accent),var(--accent2));clip-path:polygon(0 0,94% 0,100% 50%,94% 100%,0 100%)"></i>' },
|
|
1355
|
+
{ id:'vintage', name:'复古报纸', ic:'❧', ds:'衬线刊头 + 双栏排印,文化人文气质',
|
|
1356
|
+
mini:'<i style="left:5%;top:10%;width:50%;height:10%;background:var(--text);opacity:.9"></i><i style="left:5%;top:26%;width:40%;height:4%;background:var(--muted);opacity:.7"></i><i style="left:5%;top:38%;width:44%;height:4%;background:var(--muted);opacity:.5"></i><i style="left:5%;top:50%;width:38%;height:4%;background:var(--muted);opacity:.5"></i><i style="left:58%;top:10%;width:1%;height:80%;background:var(--border)"></i><i style="left:66%;top:26%;width:30%;height:4%;background:var(--muted);opacity:.7"></i><i style="left:66%;top:38%;width:26%;height:4%;background:var(--muted);opacity:.5"></i><i style="left:66%;top:50%;width:30%;height:4%;background:var(--muted);opacity:.5"></i>' },
|
|
1357
|
+
{ id:'finance', name:'金融报表', ic:'◔', ds:'仪表环 + 竖线 KPI,数据一目了然',
|
|
1358
|
+
mini:'<i style="left:38%;top:6%;width:24%;height:52%;border-radius:50%;background:conic-gradient(var(--accent) 0 62%, var(--border) 62% 100%)"></i><i style="left:45%;top:20%;width:10%;height:24%;border-radius:50%;background:var(--bg2)"></i><i style="left:8%;top:72%;width:20%;height:8%;background:var(--accent)"></i><i style="left:38%;top:72%;width:20%;height:8%;background:var(--accent)"></i><i style="left:68%;top:72%;width:20%;height:8%;background:var(--accent)"></i>' },
|
|
1359
|
+
{ id:'blueprint', name:'蓝图工程', ic:'⌗', ds:'制图网格 + 坐标标注,工程严谨感',
|
|
1360
|
+
mini:'<i style="left:8%;top:14%;width:38%;height:58%;border:1px solid var(--accent);background:repeating-linear-gradient(0deg,transparent 0 3px,var(--border) 3px 4px),repeating-linear-gradient(90deg,transparent 0 3px,var(--border) 3px 4px)"></i><i style="left:54%;top:14%;width:38%;height:58%;border:1px solid var(--accent);background:repeating-linear-gradient(0deg,transparent 0 3px,var(--border) 3px 4px),repeating-linear-gradient(90deg,transparent 0 3px,var(--border) 3px 4px)"></i><i style="left:20%;top:26%;width:14%;height:6%;background:var(--accent);opacity:.7"></i><i style="left:66%;top:26%;width:14%;height:6%;background:var(--accent);opacity:.7"></i>' },
|
|
1361
|
+
{ id:'education', name:'教学板书', ic:'✎', ds:'粉笔下划线 + 要点条,讲解演示',
|
|
1362
|
+
mini:'<i style="left:14%;top:16%;width:32%;height:14%;background:var(--text);opacity:.85"></i><i style="left:14%;top:42%;width:24%;height:5%;background:var(--accent2)"></i><i style="left:14%;top:56%;width:28%;height:5%;background:var(--accent2)"></i><i style="left:60%;top:14%;width:3px;height:40%;background:var(--accent2)"></i>' },
|
|
1363
|
+
{ id:'executive', name:'高管简报', ic:'▐', ds:'粗色条 + 细分隔线,结论优先',
|
|
1364
|
+
mini:'<i style="left:5%;top:12%;width:4%;height:76%;background:var(--accent)"></i><i style="left:14%;top:12%;width:46%;height:12%;background:var(--text);opacity:.85"></i><i style="left:14%;top:32%;width:80%;height:3%;background:var(--border)"></i><i style="left:14%;top:44%;width:70%;height:3%;background:var(--border)"></i><i style="left:14%;top:56%;width:76%;height:3%;background:var(--border)"></i>' },
|
|
1365
|
+
{ id:'metro', name:'扁平磁贴', ic:'▣', ds:'多彩色块磁贴,界面风与应用展示',
|
|
1366
|
+
mini:'<i style="left:5%;top:10%;width:28%;height:38%;border-radius:4px;background:var(--accent)"></i><i style="left:37%;top:10%;width:28%;height:38%;border-radius:4px;background:var(--accent2)"></i><i style="left:69%;top:10%;width:26%;height:38%;border-radius:4px;background:var(--muted)"></i><i style="left:5%;top:52%;width:28%;height:38%;border-radius:4px;background:var(--accent2)"></i><i style="left:37%;top:52%;width:28%;height:38%;border-radius:4px;background:var(--muted)"></i><i style="left:69%;top:52%;width:26%;height:38%;border-radius:4px;background:var(--accent)"></i>' },
|
|
1367
|
+
{ id:'bento', name:'模块网格', ic:'▦', ds:'大小格拼贴,信息层级分明',
|
|
1368
|
+
mini:'<i style="left:5%;top:10%;width:36%;height:80%;border-radius:8px;background:var(--accent);opacity:.75"></i><i style="left:46%;top:10%;width:24%;height:36%;border-radius:8px;background:var(--panel);border:1px solid var(--border)"></i><i style="left:74%;top:10%;width:21%;height:36%;border-radius:8px;background:var(--panel);border:1px solid var(--border)"></i><i style="left:46%;top:52%;width:49%;height:38%;border-radius:8px;background:var(--panel);border:1px solid var(--border)"></i>' },
|
|
1369
|
+
{ id:'dark', name:'暗夜深色', ic:'◐', ds:'页面级反色,浅色主题下也全黑',
|
|
1370
|
+
mini:'<i style="left:0;top:0;width:100%;height:100%;background:#0d1117"></i><i style="left:8%;top:20%;width:40%;height:10%;background:#58a6ff;opacity:.85"></i><i style="left:8%;top:44%;width:60%;height:6%;background:#30363d"></i><i style="left:8%;top:60%;width:50%;height:6%;background:#30363d"></i><i style="left:74%;top:18%;width:16%;height:34%;border-radius:50%;background:conic-gradient(#58a6ff 0 60%,#30363d 60% 100%)"></i>' },
|
|
1371
|
+
{ id:'nature', name:'自然清新', ic:'❀', ds:'圆润有机形状,教育与生活主题',
|
|
1372
|
+
mini:'<i style="left:8%;top:16%;width:30%;height:64%;border-radius:40% 15% 40% 15%;border:2px solid var(--accent)"></i><i style="left:44%;top:16%;width:26%;height:40%;border-radius:15% 40% 15% 40%;border:2px solid var(--accent2)"></i><i style="left:76%;top:26%;width:10%;height:22%;border-radius:50%;background:var(--accent)"></i>' }
|
|
1373
|
+
];
|
|
1374
|
+
|
|
1375
|
+
/* ── 成套模板生成器:领域 / 业务 21 式(面板「💼 领域」Tab 一键生成整套页面) ── */
|
|
1376
|
+
var P = (function(){
|
|
1377
|
+
function pad2(n){ return ('0' + n).slice(-2); }
|
|
1378
|
+
function sec(title, tpl, inner){ return '<section class="slide" data-title="' + title + '"' + (tpl ? ' data-template="' + tpl + '"' : '') + '>' + inner + '</section>'; }
|
|
1379
|
+
function head(h2, tag){ return '<div class="s-head"><h2>' + h2 + '</h2><span class="tag">' + tag + '</span></div>'; }
|
|
1380
|
+
return {
|
|
1381
|
+
cover: function(title, sub){
|
|
1382
|
+
return '<section class="slide cover" data-title="封面"><div class="logo" data-anim="pop"></div><div class="s-title" data-anim="fade-up">' + title + '</div><div class="sub" data-anim="fade-up" data-anim-delay="120">' + sub + '</div><div class="sign" data-anim="fade-in" data-anim-delay="300">GENERATED BY SKILLFORGE</div></section>';
|
|
1383
|
+
},
|
|
1384
|
+
toc: function(title, items){
|
|
1385
|
+
var inner = head(title, 'CONTENTS') + '<div class="toc">';
|
|
1386
|
+
items.forEach(function(t, i){
|
|
1387
|
+
inner += '<div class="toc-item" data-goto="' + (2 + i) + '"><span class="no">' + pad2(i + 1) + '</span><span class="t">' + t + '</span><span class="pg">第 ' + (3 + i) + ' 页</span></div>';
|
|
1388
|
+
});
|
|
1389
|
+
inner += '</div>';
|
|
1390
|
+
return sec('目录', '', inner);
|
|
1391
|
+
},
|
|
1392
|
+
points: function(title, tag, tpl, pts){
|
|
1393
|
+
var inner = head(title, tag) + '<ul class="points">';
|
|
1394
|
+
pts.forEach(function(p){ inner += '<li>' + p + '</li>'; });
|
|
1395
|
+
inner += '</ul>';
|
|
1396
|
+
return sec(title, tpl, inner);
|
|
1397
|
+
},
|
|
1398
|
+
cards: function(title, tag, tpl, list){
|
|
1399
|
+
var g = list.length <= 2 ? 'grid2' : (list.length === 3 ? 'grid3' : 'grid4');
|
|
1400
|
+
var inner = head(title, tag) + '<div class="' + g + '">';
|
|
1401
|
+
list.forEach(function(c){ inner += '<div class="card"><h4>' + c.h + (c.en ? '<span class="en">' + c.en + '</span>' : '') + '</h4><p>' + c.p + '</p></div>'; });
|
|
1402
|
+
inner += '</div>';
|
|
1403
|
+
return sec(title, tpl, inner);
|
|
1404
|
+
},
|
|
1405
|
+
nums: function(title, tag, tpl, list){
|
|
1406
|
+
var inner = head(title, tag) + '<div class="grid4">';
|
|
1407
|
+
list.forEach(function(n){ inner += '<div class="bignum"><b>' + n.b + '</b><span>' + n.s + '</span></div>'; });
|
|
1408
|
+
inner += '</div>';
|
|
1409
|
+
return sec(title, tpl, inner);
|
|
1410
|
+
},
|
|
1411
|
+
chartHtml: function(kind, spec){
|
|
1412
|
+
var h = '';
|
|
1413
|
+
if (kind === 'bars'){
|
|
1414
|
+
var max = 1;
|
|
1415
|
+
spec.forEach(function(d){ if (d.v > max) max = d.v; });
|
|
1416
|
+
h = '<div class="chart-bars">';
|
|
1417
|
+
spec.forEach(function(d, i){
|
|
1418
|
+
h += '<div class="bar" style="--bi:' + i + '"><b>' + d.v + '</b><i style="--h:' + Math.round(d.v / max * 100) + '%"></i><em>' + d.n + '</em></div>';
|
|
1419
|
+
});
|
|
1420
|
+
h += '</div>';
|
|
1421
|
+
} else if (kind === 'line'){
|
|
1422
|
+
var n = spec.length, pts = '', xs = [], ys = [];
|
|
1423
|
+
spec.forEach(function(d, i){
|
|
1424
|
+
var x = n === 1 ? 150 : Math.round(i * 300 / (n - 1));
|
|
1425
|
+
var y = Math.round(150 - d.v / 100 * 130);
|
|
1426
|
+
xs.push(x); ys.push(y);
|
|
1427
|
+
pts += (pts ? ' ' : '') + x + ',' + y;
|
|
1428
|
+
});
|
|
1429
|
+
h = '<div class="chart-line"><svg viewBox="0 0 300 158" preserveAspectRatio="none"><polyline class="ln" points="' + pts + '"/>';
|
|
1430
|
+
xs.forEach(function(x, i){ h += '<circle class="pt" style="--pi:' + i + '" cx="' + x + '" cy="' + ys[i] + '" r="4"/>'; });
|
|
1431
|
+
h += '</svg></div>';
|
|
1432
|
+
} else if (kind === 'pie'){
|
|
1433
|
+
var C = 351.86, total = 0, acc = 0;
|
|
1434
|
+
spec.forEach(function(d){ total += d.v; });
|
|
1435
|
+
h = '<div class="chart-pie"><svg viewBox="0 0 150 150">';
|
|
1436
|
+
spec.forEach(function(d, i){
|
|
1437
|
+
var L = Math.round(C * d.v / total);
|
|
1438
|
+
var rot = Math.round(acc / total * 360);
|
|
1439
|
+
h += '<circle class="pc s' + (i + 1) + '" cx="75" cy="75" r="56" style="--po:351.86; --pi:' + i + '" stroke-dasharray="' + L + ' ' + Math.round(C - L) + '" transform="rotate(' + rot + ')"/>';
|
|
1440
|
+
acc += d.v;
|
|
1441
|
+
});
|
|
1442
|
+
h += '</svg></div>';
|
|
1443
|
+
} else if (kind === 'ring'){
|
|
1444
|
+
var CC = 389.56, L2 = Math.round(CC * spec[0].pct / 100);
|
|
1445
|
+
h = '<div class="chart-ring"><svg viewBox="0 0 150 150"><circle class="rc-bg" cx="75" cy="75" r="62"/><circle class="rc" cx="75" cy="75" r="62" style="--po:389.56" stroke-dasharray="' + L2 + ' ' + Math.round(CC - L2) + '"/></svg><div class="rc-val"><b data-count="' + spec[0].pct + '" data-count-dec="0">0</b><span>' + spec[0].s + '</span></div></div>';
|
|
1446
|
+
}
|
|
1447
|
+
return h;
|
|
1448
|
+
},
|
|
1449
|
+
chart: function(title, tag, tpl, kind, spec, noteH, notes){
|
|
1450
|
+
var inner = head(title, tag) + '<div class="grid2"><div class="chart-card" data-anim-chart="' + kind + '"><div class="cc-head"><h4>' + spec.t + '</h4><span class="en">' + spec.en + '</span></div>' + P.chartHtml(kind, spec.data) + '</div><div class="card"><h4>' + noteH + '</h4><ul class="points">';
|
|
1451
|
+
notes.forEach(function(n2){ inner += '<li>' + n2 + '</li>'; });
|
|
1452
|
+
inner += '</ul></div></div>';
|
|
1453
|
+
return sec(title, tpl, inner);
|
|
1454
|
+
},
|
|
1455
|
+
end: function(){
|
|
1456
|
+
return '<section class="slide endpage" data-title="结束"><div class="s-title">谢谢观看</div><p>按 F 全屏放映 · 按 ? 查看全部热键</p><p class="sign">GENERATED BY SKILLFORGE</p></section>';
|
|
1457
|
+
}
|
|
1458
|
+
};
|
|
1459
|
+
})();
|
|
1460
|
+
|
|
1461
|
+
/* 领域 / 业务分类 */
|
|
1462
|
+
var PROF_CATS = [
|
|
1463
|
+
{ id:'edu', name:'教育学术' },
|
|
1464
|
+
{ id:'biz', name:'职场商务' },
|
|
1465
|
+
{ id:'corp', name:'企业运营' },
|
|
1466
|
+
{ id:'pro', name:'专业领域' },
|
|
1467
|
+
{ id:'gov', name:'党政政务' },
|
|
1468
|
+
{ id:'life', name:'生活场景' }
|
|
529
1469
|
];
|
|
1470
|
+
|
|
1471
|
+
/* 二十一套成套模板:pages = 封面 + 目录 + 内容页 + 图表页 + 结束页,一键整份替换 */
|
|
1472
|
+
var PROF = [
|
|
1473
|
+
{ id:'thesis', cat:'edu', name:'毕业答辩', ds:'课题研究 · 方法创新 · 成果致谢', main:'minimal', pages:[
|
|
1474
|
+
P.cover('毕业答辩<br>基于深度学习的图像分割方法研究', '答辩人:张三 · 指导教师:李四教授 · 2026 年 6 月'),
|
|
1475
|
+
P.toc('目录', ['研究背景', '研究方法', '关键创新', '实验结果']),
|
|
1476
|
+
P.points('研究背景', 'RESEARCH', 'minimal', ['传统分割方法依赖人工设计特征,泛化能力有限', '医学影像标注成本高昂,可用样本稀缺', '实时分割场景对推理速度要求严苛']),
|
|
1477
|
+
P.points('研究方法', 'METHOD', 'minimal', ['提出多尺度特征融合的编码器-解码器结构', '引入注意力机制抑制背景噪声干扰', '采用混合损失函数缓解类别不平衡问题']),
|
|
1478
|
+
P.cards('关键创新', 'NOVELTY', 'minimal', [{h:'多尺度融合', en:'Fusion', p:'深浅层特征双向融合,兼顾细节与语义'}, {h:'注意力机制', en:'Attention', p:'通道-空间双重注意力,聚焦目标区域'}, {h:'轻量化设计', en:'Light', p:'模型压缩 4 倍,推理提速 60%'}]),
|
|
1479
|
+
P.chart('实验结果', 'RESULT', 'minimal', 'bars', {t:'不同方法 mIoU 对比', en:'BARS GROW', data:[{n:'FCN', v:62}, {n:'U-Net', v:71}, {n:'DeepLab', v:78}, {n:'本文方法', v:86}]}, '实验结论', ['在公开数据集上 mIoU 达 86%,优于主流方法', '单帧推理耗时 18ms,满足实时要求', '未来探索小样本与自监督学习方向']),
|
|
1480
|
+
P.end()
|
|
1481
|
+
]},
|
|
1482
|
+
{ id:'proposal', cat:'edu', name:'开题报告', ds:'选题背景 · 研究内容 · 进度安排', main:'executive', pages:[
|
|
1483
|
+
P.cover('开题报告<br>城市智慧停车调度系统设计与实现', '汇报人:王五 · 导师:赵六教授 · 2026 年 3 月'),
|
|
1484
|
+
P.toc('目录', ['选题背景', '研究内容', '技术路线', '进度安排']),
|
|
1485
|
+
P.points('选题背景', 'MOTIVE', 'executive', ['城市停车难问题突出,车位平均利用率不足 40%', '现有调度系统缺乏全局优化视角,找位耗时', '智慧城市政策推动,智慧停车被列为重点工程']),
|
|
1486
|
+
P.cards('研究内容', 'SCOPE', 'executive', [{h:'车位状态感知', en:'Sensing', p:'地磁 + 视频融合,车位占用实时检测'}, {h:'调度算法设计', en:'Algorithm', p:'基于强化学习的全局车位调度策略'}, {h:'平台系统实现', en:'Platform', p:'小程序 + 后台管理 + 数据大屏一体'}]),
|
|
1487
|
+
P.points('技术路线', 'ROUTE', 'executive', ['调研分析:实地考察 12 个停车场现状', '建模求解:构建停车需求预测模型', '算法验证:仿真环境对比 4 种调度策略', '系统落地:试点 3 个停车场评估效果']),
|
|
1488
|
+
P.chart('进度安排', 'PLAN', 'executive', 'ring', {t:'课题总体完成度', en:'RING SWEEP', data:[{pct:35, s:'总体进度'}]}, '里程碑', ['文献调研与技术选型已完成', '算法设计与仿真实验进行中', '预计 12 月完成系统开发与论文撰写']),
|
|
1489
|
+
P.end()
|
|
1490
|
+
]},
|
|
1491
|
+
{ id:'teaching', cat:'edu', name:'教学课件', ds:'学习目标 · 知识讲解 · 课堂练习', main:'education', pages:[
|
|
1492
|
+
P.cover('人教版 · 小学语文五年级<br>《草船借箭》', '授课教师:陈老师 · 第三单元 · 共 2 课时'),
|
|
1493
|
+
P.toc('目录', ['学习目标', '生字词', '课文精讲', '课堂练习']),
|
|
1494
|
+
P.points('学习目标', 'GOALS', 'education', ['认识 11 个生字,会写 8 个字', '理解诸葛亮神机妙算的深层原因', '感受古典名著的魅力,激发阅读兴趣']),
|
|
1495
|
+
P.cards('生字词', 'WORDS', 'education', [{h:'擂鼓', en:'léi gǔ', p:'击鼓助威,古代军中号令'}, {h:'都督', en:'dū du', p:'古代军事长官,课文指周瑜'}, {h:'妒忌', en:'dù jì', p:'因别人胜过自己而心怀怨恨'}]),
|
|
1496
|
+
P.points('课文精讲', 'TEXT', 'education', ['起因:周瑜妒忌,令诸葛亮十日造十万支箭', '经过:大雾漫天,草船逼近曹营水寨', '结果:借箭十万,周瑜自叹不如']),
|
|
1497
|
+
P.chart('课堂练习', 'QUIZ', 'education', 'bars', {t:'随堂检测正确率', en:'BARS GROW', data:[{n:'识字', v:92}, {n:'词语', v:88}, {n:'理解', v:85}, {n:'拓展', v:78}]}, '练习小结', ['生字听写全班平均正确率 92%', '人物性格分析环节讨论热烈', '课后推荐阅读《三国演义》原著节选']),
|
|
1498
|
+
P.end()
|
|
1499
|
+
]},
|
|
1500
|
+
{ id:'report', cat:'biz', name:'年终汇报', ds:'年度总览 · 重点项目 · 明年规划', main:'executive', pages:[
|
|
1501
|
+
P.cover('2026 年度工作汇报', '汇报人:产品总监 · 张三 · 2026 年 12 月'),
|
|
1502
|
+
P.toc('目录', ['年度总览', '重点项目', '关键数据', '团队建设', '明年规划']),
|
|
1503
|
+
P.nums('年度总览', 'OVERVIEW', 'executive', [{b:'12', s:'项重点项目'}, {b:'3.2亿', s:'全年 GMV'}, {b:'98%', s:'按期交付率'}, {b:'40', s:'人团队规模'}]),
|
|
1504
|
+
P.cards('重点项目', 'PROJECTS', 'executive', [{h:'智能推荐 2.0', en:'Recommend', p:'转化率提升 26%,GMV 贡献 1.2 亿'}, {h:'会员体系重构', en:'Membership', p:'付费会员破 80 万,续费率 72%'}, {h:'性能优化专项', en:'Performance', p:'首屏时间 1.8s → 0.9s,崩溃率降 60%'}]),
|
|
1505
|
+
P.chart('关键数据', 'DATA', 'executive', 'line', {t:'全年 GMV 走势(亿元)', en:'LINE DRAW', data:[{n:'Q1', v:38}, {n:'Q2', v:52}, {n:'Q3', v:66}, {n:'Q4', v:85}]}, '数据解读', ['Q4 同比增长 40%,创历史新高', '大促期间峰值日 GMV 突破 5000 万', '客单价同比提升 12%']),
|
|
1506
|
+
P.points('团队建设', 'TEAM', 'executive', ['校招补充 15 人,全员完成职级晋升答辩', '建立双周复盘机制,问题闭环率 95%', '组织内部技术分享 24 场']),
|
|
1507
|
+
P.cards('明年规划', 'PLAN', 'executive', [{h:'出海业务探索', en:'Global', p:'东南亚市场试点,组建本地化团队'}, {h:'数据中台建设', en:'Data', p:'统一指标口径,赋能精细化运营'}, {h:'组织效能提升', en:'Efficiency', p:'推进 OKR 落地,人均产出提升 20%'}]),
|
|
1508
|
+
P.end()
|
|
1509
|
+
]},
|
|
1510
|
+
{ id:'competition', cat:'biz', name:'竞聘述职', ds:'个人经历 · 核心业绩 · 任职规划', main:'timeline', pages:[
|
|
1511
|
+
P.cover('竞聘述职 · 产品总监', '竞聘人:李四 · 2026 年 11 月'),
|
|
1512
|
+
P.toc('目录', ['个人经历', '核心业绩', '能力模型', '任职规划']),
|
|
1513
|
+
P.cards('个人经历', 'CAREER', 'timeline', [{h:'产品专员', en:'2019', p:'从 0 到 1 搭建用户反馈体系'}, {h:'高级产品经理', en:'2022', p:'主导 3 条核心产品线迭代'}, {h:'产品组长', en:'2025', p:'带领 8 人团队,年度考核 S'}]),
|
|
1514
|
+
P.nums('核心业绩', 'RESULTS', 'timeline', [{b:'15', s:'条产品线'}, {b:'240%', s:'用户增长'}, {b:'9.2', s:'团队评分'}, {b:'6', s:'次年度优秀'}]),
|
|
1515
|
+
P.points('能力模型', 'SKILLS', 'timeline', ['战略规划:从业务目标倒推产品路线图', '团队管理:辅导 12 名成员晋升', '数据分析:以数据驱动关键决策']),
|
|
1516
|
+
P.chart('任职规划', 'PLAN', 'timeline', 'ring', {t:'年度目标达成承诺', en:'RING SWEEP', data:[{pct:96, s:'目标达成'}]}, '三步走', ['首季度完成组织梳理与流程优化', '半年内上线两条新业务线', '全年营收增长 50%,团队扩至 20 人']),
|
|
1517
|
+
P.end()
|
|
1518
|
+
]},
|
|
1519
|
+
{ id:'plan', cat:'biz', name:'商业计划书', ds:'市场分析 · 商业模式 · 财务预测', main:'finance', pages:[
|
|
1520
|
+
P.cover('商业计划书<br>智能养老服务平台', '星海科技 · 2026 年 10 月'),
|
|
1521
|
+
P.toc('目录', ['市场分析', '商业模式', '产品方案', '财务预测']),
|
|
1522
|
+
P.points('市场分析', 'MARKET', 'finance', ['银发经济规模将突破 30 万亿元', '居家养老需求占比超 90%,供给不足', '适老化产品渗透率不足 15%,空间巨大']),
|
|
1523
|
+
P.cards('商业模式', 'MODEL', 'finance', [{h:'平台服务费', en:'Service', p:'撮合服务订单,抽取 10%-15% 佣金'}, {h:'智能硬件销售', en:'Hardware', p:'智能手环 + 一键呼救设备'}, {h:'增值服务', en:'Plus', p:'健康管理、陪诊、适老化改造'}]),
|
|
1524
|
+
P.nums('产品方案', 'PRODUCT', 'finance', [{b:'4', s:'大产品模块'}, {b:'120', s:'项养老服务'}, {b:'500+', s:'合作机构'}, {b:'7×24', s:'全天响应'}]),
|
|
1525
|
+
P.chart('财务预测', 'FINANCE', 'finance', 'pie', {t:'收入结构占比', en:'PIE SWEEP', data:[{n:'平台服务', v:45}, {n:'硬件销售', v:30}, {n:'增值服务', v:25}]}, '盈利展望', ['首年营收目标 1200 万元', '第三年实现盈亏平衡', '本轮融资需求 800 万元']),
|
|
1526
|
+
P.end()
|
|
1527
|
+
]},
|
|
1528
|
+
{ id:'hiring', cat:'biz', name:'求职简历', ds:'教育经历 · 项目成果 · 技能特长', main:'timeline', pages:[
|
|
1529
|
+
P.cover('个人简历 · 全栈工程师', '张三 · 5 年经验 · 期望职位:高级工程师'),
|
|
1530
|
+
P.toc('目录', ['工作经历', '项目成果', '技能特长']),
|
|
1531
|
+
P.cards('工作经历', 'EXPERIENCE', 'timeline', [{h:'某科技公司 · 技术负责人', en:'2024-今', p:'带领 10 人团队,负责核心系统架构'}, {h:'某互联网公司 · 全栈工程师', en:'2021-2024', p:'从 0 到 1 搭建交易中台'}, {h:'某软件公司 · 前端工程师', en:'2019-2021', p:'负责企业级管理后台开发'}]),
|
|
1532
|
+
P.nums('项目成果', 'PROJECTS', 'timeline', [{b:'8', s:'个核心项目'}, {b:'99.99%', s:'系统可用性'}, {b:'40%', s:'性能提升'}, {b:'3', s:'项技术专利'}]),
|
|
1533
|
+
P.points('技能特长', 'SKILLS', 'timeline', ['精通 Vue / React / Node.js 全栈技术体系', '熟悉微服务架构与容器化部署', '具备 10 人团队管理与项目推进经验']),
|
|
1534
|
+
P.end()
|
|
1535
|
+
]},
|
|
1536
|
+
{ id:'product', cat:'corp', name:'产品发布', ds:'行业洞察 · 产品亮点 · 增长数据', main:'keynote', pages:[
|
|
1537
|
+
P.cover('新一代智能协作平台 3.0<br>发布会', '让协作回归简单 · 2026 秋季'),
|
|
1538
|
+
P.toc('目录', ['行业洞察', '产品亮点', '核心数据', '用户增长']),
|
|
1539
|
+
P.points('行业洞察', 'INSIGHT', 'keynote', ['远程办公常态化,协作工具市场年增 25%', '用户苦于工具割裂与信息过载', '团队需要「一个入口,完成所有协作」']),
|
|
1540
|
+
P.cards('产品亮点', 'HIGHLIGHTS', 'keynote', [{h:'AI 会议纪要', en:'AI Notes', p:'自动转写、摘要、待办一条龙'}, {h:'知识库联动', en:'Knowledge', p:'文档、聊天、任务打通互链'}, {h:'全端实时同步', en:'Sync', p:'多设备毫秒级状态同步'}]),
|
|
1541
|
+
P.nums('核心数据', 'DATA', 'keynote', [{b:'10ms', s:'平均响应'}, {b:'99.99%', s:'可用性'}, {b:'500万', s:'注册用户'}, {b:'200+', s:'生态应用'}]),
|
|
1542
|
+
P.chart('用户增长', 'GROWTH', 'keynote', 'line', {t:'内测至今用户数(万)', en:'LINE DRAW', data:[{n:'3月', v:12}, {n:'5月', v:35}, {n:'7月', v:70}, {n:'9月', v:150}, {n:'11月', v:300}]}, '增长密码', ['内测转正率 68%,远超行业平均', '次日留存 55%,周留存 38%', '公测预约已突破 50 万人']),
|
|
1543
|
+
P.end()
|
|
1544
|
+
]},
|
|
1545
|
+
{ id:'tech', cat:'corp', name:'科技发布会', ds:'技术架构 · 性能指标 · 生态布局', main:'blueprint', pages:[
|
|
1546
|
+
P.cover('苍穹 AI 大模型发布会', '多模态 · 千亿参数 · 开放平台'),
|
|
1547
|
+
P.toc('目录', ['技术架构', '核心能力', '性能指标', '评测对比']),
|
|
1548
|
+
P.points('技术架构', 'ARCH', 'blueprint', ['千亿参数 MoE 稀疏专家架构', '多模态统一编码,一图多文全覆盖', '训推一体,推理成本降低 60%']),
|
|
1549
|
+
P.cards('核心能力', 'CAPABILITY', 'blueprint', [{h:'多轮对话', en:'Chat', p:'长上下文记忆,连续 50 轮不掉线'}, {h:'图像理解', en:'Vision', p:'图表、文档、场景一图读懂'}, {h:'代码生成', en:'Code', p:'支持 60+ 语言,一键生成可运行代码'}]),
|
|
1550
|
+
P.nums('性能指标', 'BENCHMARK', 'blueprint', [{b:'85.6', s:'权威评测分'}, {b:'3.2s', s:'平均响应'}, {b:'60%', s:'成本降低'}, {b:'128K', s:'上下文窗口'}]),
|
|
1551
|
+
P.chart('评测对比', 'RESULT', 'blueprint', 'bars', {t:'主流基准测试得分', en:'BARS GROW', data:[{n:'模型 A', v:78}, {n:'模型 B', v:82}, {n:'苍穹', v:91}]}, '评测结论', ['中文理解能力业界领先', '复杂推理能力提升显著', '开放 API 即日起可申请试用']),
|
|
1552
|
+
P.end()
|
|
1553
|
+
]},
|
|
1554
|
+
{ id:'marketing', cat:'corp', name:'营销方案', ds:'市场洞察 · 策略路径 · 预算分配', main:'poster', pages:[
|
|
1555
|
+
P.cover('618 年中大促<br>整合营销方案', '全渠道 · 全场景 · 全人群'),
|
|
1556
|
+
P.toc('目录', ['市场洞察', '策略路径', '渠道排布', '预算分配']),
|
|
1557
|
+
P.points('市场洞察', 'INSIGHT', 'poster', ['目标人群 Z 世代占比 62%,偏好内容种草', '竞品大促集中在价格战,缺乏体验创新', '私域流量红利仍在,复购提升空间大']),
|
|
1558
|
+
P.cards('策略路径', 'STRATEGY', 'poster', [{h:'内容种草', en:'Content', p:'300+ KOL 矩阵,提前 30 天蓄水'}, {h:'直播引爆', en:'Live', p:'大促当日 42 场直播同时开播'}, {h:'私域沉淀', en:'Private', p:'社群 + 会员体系承接复购'}]),
|
|
1559
|
+
P.nums('渠道排布', 'CHANNELS', 'poster', [{b:'6', s:'大平台联动'}, {b:'42', s:'场直播'}, {b:'300+', s:'位 KOL'}, {b:'1000万', s:'目标曝光'}]),
|
|
1560
|
+
P.chart('预算分配', 'BUDGET', 'poster', 'pie', {t:'营销预算结构', en:'PIE SWEEP', data:[{n:'内容投放', v:40}, {n:'直播渠道', v:35}, {n:'活动让利', v:25}]}, '预算与目标', ['营销总预算 500 万元', '预期 ROI 达到 1:3.5', '大促 GMV 目标 2 亿元']),
|
|
1561
|
+
P.end()
|
|
1562
|
+
]},
|
|
1563
|
+
{ id:'training', cat:'corp', name:'企业培训', ds:'公司概况 · 制度规范 · 成长路径', main:'education', pages:[
|
|
1564
|
+
P.cover('新员工入职培训<br>走进星海科技', '人力资源部 · 2026 年第 3 期'),
|
|
1565
|
+
P.toc('目录', ['公司概况', '组织架构', '制度规范', '成长路径']),
|
|
1566
|
+
P.nums('公司概况', 'OVERVIEW', 'education', [{b:'2016', s:'年成立'}, {b:'800+', s:'员工'}, {b:'12', s:'个城市'}, {b:'3', s:'条业务线'}]),
|
|
1567
|
+
P.cards('组织架构', 'ORG', 'education', [{h:'产品研发中心', en:'R&D', p:'产品、设计、研发、测试四大团队'}, {h:'市场运营中心', en:'Market', p:'市场、销售、客户成功协同作战'}, {h:'职能支撑中心', en:'Support', p:'人力、财务、行政、法务保驾护航'}]),
|
|
1568
|
+
P.points('制度规范', 'RULES', 'education', ['考勤与假期:弹性工作制,年假 10 天起', '报销与采购:线上流程,48 小时内到账', '信息安全:数据分级管理,严禁外发']),
|
|
1569
|
+
P.chart('成长路径', 'GROWTH', 'education', 'ring', {t:'新员工培训完成度', en:'RING SWEEP', data:[{pct:100, s:'课程完成'}]}, '培养计划', ['导师一对一辅导 3 个月', '第 90 天进行转正答辩', '晋升通道每半年开放一次']),
|
|
1570
|
+
P.end()
|
|
1571
|
+
]},
|
|
1572
|
+
{ id:'ceremony', cat:'corp', name:'年会盛典', ds:'年度回顾 · 荣誉时刻 · 节目抽奖', main:'poster', pages:[
|
|
1573
|
+
P.cover('星海科技 2026 年度盛典', '拾光而行 · 感谢有你'),
|
|
1574
|
+
P.toc('目录', ['年度回顾', '荣誉时刻', '节目单', '幸运抽奖']),
|
|
1575
|
+
P.nums('年度回顾', 'REVIEW', 'poster', [{b:'3亿', s:'年度营收'}, {b:'500万', s:'用户规模'}, {b:'120', s:'项专利'}, {b:'40', s:'座行业奖项'}]),
|
|
1576
|
+
P.cards('荣誉时刻', 'HONOR', 'poster', [{h:'年度之星', en:'10 人', p:'在各自岗位做出突出贡献'}, {h:'五年陈', en:'25 人', p:'与公司共同成长的伙伴'}, {h:'最佳团队', en:'5 支', p:'协同作战、业绩斐然的团队'}]),
|
|
1577
|
+
P.points('节目单', 'SHOW', 'poster', ['开场歌舞《星河》——产品研发中心', '小品《加班那点事》——技术部', '大合唱《明天会更好》——全员']),
|
|
1578
|
+
P.chart('幸运抽奖', 'LUCKY', 'poster', 'pie', {t:'奖项设置', en:'PIE SWEEP', data:[{n:'特等奖', v:2}, {n:'一等奖', v:10}, {n:'二等奖', v:50}, {n:'三等奖', v:200}]}, '抽奖说明', ['阳光普照奖人手一份', '现场扫码参与抽奖', '祝大家好运连连']),
|
|
1579
|
+
P.end()
|
|
1580
|
+
]},
|
|
1581
|
+
{ id:'finance', cat:'pro', name:'金融分析', ds:'宏观环境 · 行业配置 · 组合策略', main:'finance', pages:[
|
|
1582
|
+
P.cover('2026 年第三季度<br>投资策略报告', '资产配置 · 行业轮动 · 风险控制'),
|
|
1583
|
+
P.toc('目录', ['宏观环境', '行业配置', '组合策略', '风险提示']),
|
|
1584
|
+
P.points('宏观环境', 'MACRO', 'finance', ['经济温和复苏,制造业景气度回升', '流动性合理充裕,利率中枢下移', '海外扰动边际减弱,风险偏好修复']),
|
|
1585
|
+
P.cards('行业配置', 'SECTOR', 'finance', [{h:'科技成长', en:'Tech', p:'AI 算力与半导体国产替代'}, {h:'高端制造', en:'Manufacture', p:'机器人与工业自动化'}, {h:'消费复苏', en:'Consume', p:'出行链与健康消费'}]),
|
|
1586
|
+
P.chart('组合策略', 'STRATEGY', 'finance', 'line', {t:'模拟组合净值走势', en:'LINE DRAW', data:[{n:'1月', v:100}, {n:'3月', v:112}, {n:'5月', v:128}, {n:'7月', v:135}, {n:'9月', v:152}]}, '组合表现', ['年化收益 21%,跑赢沪深 300 指数', '最大回撤控制在 6% 以内', '建议股债比例 6:4,攻守兼备']),
|
|
1587
|
+
P.points('风险提示', 'RISK', 'finance', ['地缘政治与海外政策存在不确定性', '行业监管政策可能发生变化', '市场波动可能超预期,注意仓位管理']),
|
|
1588
|
+
P.end()
|
|
1589
|
+
]},
|
|
1590
|
+
{ id:'medical', cat:'pro', name:'医疗科普', ds:'健康数据 · 预防建议 · 就医指引', main:'metro', pages:[
|
|
1591
|
+
P.cover('心血管健康科普<br>别让血管悄悄变老', '健康管理中心 · 公益科普讲座'),
|
|
1592
|
+
P.toc('目录', ['认识心血管', '危险因素', '预防指南', '就医指引']),
|
|
1593
|
+
P.nums('认识心血管', 'FACTS', 'metro', [{b:'3.3亿', s:'患者人数'}, {b:'45%', s:'致死原因占比'}, {b:'30岁', s:'年轻化趋势'}, {b:'80%', s:'可以预防'}]),
|
|
1594
|
+
P.cards('危险因素', 'RISKS', 'metro', [{h:'高血压', en:'BP', p:'血压 ≥140/90 需及时干预'}, {h:'高血脂', en:'Lipid', p:'LDL 超标加速动脉硬化'}, {h:'吸烟酗酒', en:'Tobacco', p:'血管内皮损伤的重要元凶'}, {h:'缺乏运动', en:'Sedentary', p:'久坐不动,代谢持续走低'}]),
|
|
1595
|
+
P.points('预防指南', 'PREVENT', 'metro', ['每周 150 分钟中等强度运动', '少盐少油,多吃蔬果与全谷物', '定期体检,监测血压血脂血糖']),
|
|
1596
|
+
P.chart('就医指引', 'FIRST-AID', 'metro', 'ring', {t:'4 分钟内心肺复苏存活率', en:'RING SWEEP', data:[{pct:70, s:'黄金救援'}]}, '急救要点', ['胸痛持续 15 分钟立即就医', '拨打 120 说明症状与准确地址', '学习心肺复苏,关键时刻能救命']),
|
|
1597
|
+
P.end()
|
|
1598
|
+
]},
|
|
1599
|
+
{ id:'law', cat:'pro', name:'法律合规', ds:'合规形势 · 体系建设 · 重点工作', main:'executive', pages:[
|
|
1600
|
+
P.cover('企业数据合规<br>体系建设方案', '法务合规部 · 2026 年度'),
|
|
1601
|
+
P.toc('目录', ['合规形势', '体系建设', '重点工作', '保障措施']),
|
|
1602
|
+
P.points('合规形势', 'TREND', 'executive', ['《个人信息保护法》执法力度持续加大', '数据出境安全评估成为企业刚需', '违规成本显著上升,最高罚上年营业额 5%']),
|
|
1603
|
+
P.cards('体系建设', 'SYSTEM', 'executive', [{h:'制度体系', en:'Policy', p:'制定 12 项数据管理制度'}, {h:'技术防线', en:'Tech', p:'加密、脱敏、审计四道防线'}, {h:'审计监督', en:'Audit', p:'季度自查 + 年度第三方审计'}]),
|
|
1604
|
+
P.points('重点工作', 'FOCUS', 'executive', ['隐私政策与授权链路全面梳理', '数据分类分级与加密存储落地', '年度合规培训覆盖率 100%']),
|
|
1605
|
+
P.nums('保障措施', 'GUARD', 'executive', [{b:'4', s:'道技术防线'}, {b:'12', s:'项核心制度'}, {b:'100%', s:'培训覆盖'}, {b:'0', s:'起重大违规'}]),
|
|
1606
|
+
P.end()
|
|
1607
|
+
]},
|
|
1608
|
+
{ id:'gov', cat:'gov', name:'政务汇报', ds:'总体情况 · 重点工作 · 数字政府', main:'executive', pages:[
|
|
1609
|
+
P.cover('2026 年上半年<br>重点工作汇报', '市数据管理局 · 2026 年 7 月'),
|
|
1610
|
+
P.toc('目录', ['总体情况', '重点工作', '数字政府', '下一步打算']),
|
|
1611
|
+
P.nums('总体情况', 'SUMMARY', 'executive', [{b:'68', s:'项重点任务'}, {b:'95%', s:'按期完成率'}, {b:'30万', s:'服务事项'}, {b:'99.9%', s:'群众满意度'}]),
|
|
1612
|
+
P.cards('重点工作', 'FOCUS', 'executive', [{h:'一网通办 2.0', en:'Online', p:'千项政务服务全程网办'}, {h:'城市大脑升级', en:'City Brain', p:'城市运行一屏统览'}, {h:'数据共享攻坚', en:'Data', p:'打通 45 个部门数据壁垒'}]),
|
|
1613
|
+
P.chart('数字政府', 'DIGITAL', 'executive', 'bars', {t:'网上办事率(%)', en:'BARS GROW', data:[{n:'2024', v:62}, {n:'2025', v:78}, {n:'2026', v:92}]}, '建设成效', ['全程网办事项占比 92%', '办事材料平均精简 55%', '平均办事时限压缩 70%']),
|
|
1614
|
+
P.points('下一步打算', 'NEXT', 'executive', ['深化数据要素市场化配置改革', '推进 AI 政务大模型试点应用', '建设一体化数据资源底座']),
|
|
1615
|
+
P.end()
|
|
1616
|
+
]},
|
|
1617
|
+
{ id:'party', cat:'gov', name:'党建汇报', ds:'政治建设 · 组织建设 · 作风建设', main:'executive', pages:[
|
|
1618
|
+
P.cover('2026 年度党建工作汇报', '中共星海科技党委 · 2026 年 12 月'),
|
|
1619
|
+
P.toc('目录', ['政治建设', '组织建设', '作风建设', '明年展望']),
|
|
1620
|
+
P.points('政治建设', 'POLITICS', 'executive', ['深入学习贯彻党的创新理论', '开展主题教育专题学习 12 场次', '党委理论学习中心组学习 24 次']),
|
|
1621
|
+
P.nums('组织建设', 'ORG', 'executive', [{b:'36', s:'个党支部'}, {b:'850', s:'名党员'}, {b:'42', s:'名新发展党员'}, {b:'100%', s:'三会一课落实'}]),
|
|
1622
|
+
P.points('作风建设', 'STYLE', 'executive', ['落实中央八项规定精神常态化长效化', '开展警示教育 6 场,覆盖全员', '党员群众满意度持续提升']),
|
|
1623
|
+
P.chart('明年展望', 'VISION', 'executive', 'ring', {t:'党建品牌创建进度', en:'RING SWEEP', data:[{pct:80, s:'品牌创建'}]}, '创建目标', ['打造 3 个党建示范点', '推动党建与业务深度融合', '党员志愿服务常态化开展']),
|
|
1624
|
+
P.end()
|
|
1625
|
+
]},
|
|
1626
|
+
{ id:'food', cat:'life', name:'餐饮品牌', ds:'品牌故事 · 招牌菜单 · 口碑数据', main:'magazine', pages:[
|
|
1627
|
+
P.cover('山野食堂<br>一家有故事的云南菜馆', '从食材到餐桌 · 四季的味道'),
|
|
1628
|
+
P.toc('目录', ['品牌故事', '招牌菜单', '食材溯源', '口碑数据']),
|
|
1629
|
+
P.points('品牌故事', 'STORY', 'magazine', ['创立于 2016 年,名字取自云南的山野', '坚持「不时不食」,只做当季菜', '每一道菜背后都有一位手艺人']),
|
|
1630
|
+
P.cards('招牌菜单', 'MENU', 'magazine', [{h:'汽锅鸡', en:'Steam Pot', p:'古法汽锅,原汁原味'}, {h:'野生菌火锅', en:'Mushroom', p:'当季鲜菌,山珍荟萃'}, {h:'鲜花饼', en:'Flower Cake', p:'现烤现卖,玫瑰馅料'}]),
|
|
1631
|
+
P.points('食材溯源', 'SOURCE', 'magazine', ['清晨 5 点直采,当日送达门店', '与 27 家农户签订直供协议', '扫码即可查看每一份食材的产地故事']),
|
|
1632
|
+
P.chart('口碑数据', 'REPUTATION', 'magazine', 'bars', {t:'各平台评分', en:'BARS GROW', data:[{n:'大众点评', v:92}, {n:'美团', v:90}, {n:'小红书', v:95}, {n:'抖音', v:88}]}, '经营表现', ['人均客单价 128 元', '全年客流 40 万人次', '顾客复购率 58%']),
|
|
1633
|
+
P.end()
|
|
1634
|
+
]},
|
|
1635
|
+
{ id:'travel', cat:'life', name:'旅游攻略', ds:'行程总览 · 景点美食 · 预算构成', main:'magazine', pages:[
|
|
1636
|
+
P.cover('云南七日<br>从昆明到大理丽江', '自由行攻略 · 人均预算 3500 元'),
|
|
1637
|
+
P.toc('目录', ['行程总览', '景点推荐', '美食地图', '预算构成']),
|
|
1638
|
+
P.cards('行程总览', 'ROUTE', 'magazine', [{h:'DAY 1-2 昆明', en:'Kunming', p:'滇池海鸥 · 石林奇观'}, {h:'DAY 3-4 大理', en:'Dali', p:'洱海骑行 · 古城慢生活'}, {h:'DAY 5-7 丽江', en:'Lijiang', p:'玉龙雪山 · 束河古镇'}]),
|
|
1639
|
+
P.points('景点推荐', 'SPOTS', 'magazine', ['洱海环湖骑行,看日出与日落', '玉龙雪山,提前三天订大索道票', '束河古镇,比大研更安静惬意']),
|
|
1640
|
+
P.points('美食地图', 'FOOD', 'magazine', ['昆明:过桥米线、汽锅鸡', '大理:酸辣鱼、烤乳扇', '丽江:腊排骨、鸡豆凉粉']),
|
|
1641
|
+
P.chart('预算构成', 'BUDGET', 'magazine', 'pie', {t:'人均花费占比', en:'PIE SWEEP', data:[{n:'交通', v:35}, {n:'住宿', v:30}, {n:'餐饮', v:20}, {n:'门票娱乐', v:15}]}, '省钱贴士', ['人均总预算 3500 元', '机票提前 1 个月订最划算', '古城内住宿节假日价格翻倍']),
|
|
1642
|
+
P.end()
|
|
1643
|
+
]},
|
|
1644
|
+
{ id:'festival', cat:'life', name:'节日庆典', ds:'活动主题 · 氛围布置 · 节目安排', main:'poster', pages:[
|
|
1645
|
+
P.cover('中秋国庆双节<br>活动策划方案', '团圆月 · 家国情 · 2026'),
|
|
1646
|
+
P.toc('目录', ['活动主题', '节目安排', '氛围布置']),
|
|
1647
|
+
P.points('活动主题', 'THEME', 'poster', ['主视觉以「月亮与城市剪影」为核心元素', '双节同庆,营造家国同梦的氛围', '覆盖全年龄层,人人皆可参与']),
|
|
1648
|
+
P.cards('节目安排', 'SHOW', 'poster', [{h:'中秋游园会', en:'Garden', p:'猜灯谜、做月饼、赏月会'}, {h:'国庆升旗仪式', en:'Ceremony', p:'晨光中同唱一首歌'}, {h:'亲子手作市集', en:'Market', p:'花灯、纸鸢、非遗体验'}]),
|
|
1649
|
+
P.nums('氛围布置', 'DECOR', 'poster', [{b:'500米', s:'主题灯带'}, {b:'80', s:'组花灯'}, {b:'12', s:'处打卡点'}, {b:'30', s:'名志愿者'}]),
|
|
1650
|
+
P.end()
|
|
1651
|
+
]},
|
|
1652
|
+
{ id:'charity', cat:'life', name:'公益慈善', ds:'项目背景 · 行动方案 · 参与方式', main:'minimal', pages:[
|
|
1653
|
+
P.cover('一束光公益计划<br>乡村儿童阅读行动', '让每一本书都有人读'),
|
|
1654
|
+
P.toc('目录', ['项目背景', '行动方案', '预期成效', '如何参与']),
|
|
1655
|
+
P.points('项目背景', 'BACKGROUND', 'minimal', ['乡村学校藏书量不足城市学校的 1/5', '超 60% 乡村儿童课外阅读量偏少', '阅读是打破认知差距的最低成本方式']),
|
|
1656
|
+
P.cards('行动方案', 'ACTION', 'minimal', [{h:'捐建图书角', en:'Library', p:'100 所学校落地标准图书角'}, {h:'陪伴共读', en:'Reading', p:'线上共读会每周一场'}, {h:'教师培训', en:'Training', p:'阅读指导方法进乡村课堂'}]),
|
|
1657
|
+
P.nums('预期成效', 'IMPACT', 'minimal', [{b:'100', s:'所学校'}, {b:'5万', s:'本图书'}, {b:'1万+', s:'儿童受益'}, {b:'200', s:'名志愿者'}]),
|
|
1658
|
+
P.points('如何参与', 'JOIN', 'minimal', ['捐一本书,写一句寄语', '成为线上共读志愿者', '企业冠名捐赠图书角']),
|
|
1659
|
+
P.end()
|
|
1660
|
+
]}
|
|
1661
|
+
];
|
|
1662
|
+
|
|
530
1663
|
function tplOf(s){ return s.getAttribute('data-template') || 'classic'; }
|
|
531
1664
|
function ensureOrigin(s){ if (!s._origin) s._origin = s.innerHTML; }
|
|
532
1665
|
function isSpecialPage(s){
|
|
@@ -623,14 +1756,98 @@ function wrapMagazine(s){
|
|
|
623
1756
|
while (s.firstChild) s.removeChild(s.firstChild);
|
|
624
1757
|
s.appendChild(mw);
|
|
625
1758
|
}
|
|
1759
|
+
function wrapSteps(s){
|
|
1760
|
+
var cards = s.querySelectorAll('.card');
|
|
1761
|
+
if (!cards.length) return;
|
|
1762
|
+
var host = cards[0].parentNode;
|
|
1763
|
+
var st = document.createElement('div'); st.className = 'st-wrap';
|
|
1764
|
+
Array.prototype.forEach.call(cards, function(card, k){
|
|
1765
|
+
var step = document.createElement('div'); step.className = 'st-step';
|
|
1766
|
+
var no = document.createElement('div'); no.className = 'st-no'; no.textContent = k + 1;
|
|
1767
|
+
step.appendChild(no);
|
|
1768
|
+
var h4 = card.querySelector('h4');
|
|
1769
|
+
if (h4){
|
|
1770
|
+
var t4 = document.createElement('h4');
|
|
1771
|
+
t4.textContent = h4.childNodes[0] ? h4.childNodes[0].textContent.trim() : h4.textContent.trim();
|
|
1772
|
+
step.appendChild(t4);
|
|
1773
|
+
}
|
|
1774
|
+
var p = card.querySelector('p');
|
|
1775
|
+
if (p){ var np = document.createElement('p'); np.textContent = p.textContent; step.appendChild(np); }
|
|
1776
|
+
st.appendChild(step);
|
|
1777
|
+
});
|
|
1778
|
+
host.parentNode.insertBefore(st, host);
|
|
1779
|
+
host.parentNode.removeChild(host);
|
|
1780
|
+
}
|
|
1781
|
+
function wrapPoster(s){
|
|
1782
|
+
var items = s.querySelectorAll('.points li, .card');
|
|
1783
|
+
if (!items.length) return;
|
|
1784
|
+
var host = items[0].parentNode;
|
|
1785
|
+
var band = document.createElement('div');
|
|
1786
|
+
Array.prototype.forEach.call(items, function(it){
|
|
1787
|
+
var b = document.createElement('div'); b.className = 'pt-band';
|
|
1788
|
+
var h4 = it.querySelector('h4');
|
|
1789
|
+
var main = h4 && h4.childNodes[0] ? h4.childNodes[0].textContent.trim() : it.textContent.trim().split('\n')[0];
|
|
1790
|
+
b.appendChild(document.createTextNode(main));
|
|
1791
|
+
var sub = it.querySelector('p') || it.querySelector('.en');
|
|
1792
|
+
if (sub && sub.textContent.trim()){
|
|
1793
|
+
var sp = document.createElement('span'); sp.textContent = sub.textContent.trim(); b.appendChild(sp);
|
|
1794
|
+
}
|
|
1795
|
+
band.appendChild(b);
|
|
1796
|
+
});
|
|
1797
|
+
host.parentNode.insertBefore(band, host);
|
|
1798
|
+
host.parentNode.removeChild(host);
|
|
1799
|
+
}
|
|
1800
|
+
function wrapVintage(s){
|
|
1801
|
+
var cards = s.querySelectorAll('.card');
|
|
1802
|
+
if (!cards.length) return;
|
|
1803
|
+
var host = cards[0].parentNode;
|
|
1804
|
+
var vc = document.createElement('div'); vc.className = 'v-col';
|
|
1805
|
+
Array.prototype.forEach.call(cards, function(card){ vc.appendChild(card); });
|
|
1806
|
+
host.parentNode.insertBefore(vc, host);
|
|
1807
|
+
host.parentNode.removeChild(host);
|
|
1808
|
+
}
|
|
1809
|
+
function wrapFinance(s){
|
|
1810
|
+
var nums = s.querySelectorAll('.bignum');
|
|
1811
|
+
if (!nums.length) return;
|
|
1812
|
+
var host = nums[0].parentNode;
|
|
1813
|
+
var row = document.createElement('div');
|
|
1814
|
+
row.style.cssText = 'display:flex;justify-content:space-around;align-items:center;flex:1;gap:20px;';
|
|
1815
|
+
Array.prototype.forEach.call(nums, function(n){
|
|
1816
|
+
var b = n.querySelector('b');
|
|
1817
|
+
var cap = n.querySelector('span');
|
|
1818
|
+
var bt = b ? b.textContent.trim() : '';
|
|
1819
|
+
var m = bt.match(/^(\d+(?:\.\d+)?)\s*%$/);
|
|
1820
|
+
if (m){
|
|
1821
|
+
var pct = Math.max(4, Math.min(100, parseFloat(m[1])));
|
|
1822
|
+
var cell = document.createElement('div'); cell.style.textAlign = 'center';
|
|
1823
|
+
var ring = document.createElement('div'); ring.className = 'fn-ring';
|
|
1824
|
+
ring.style.setProperty('--pn', pct + '%');
|
|
1825
|
+
var rb = document.createElement('b'); rb.textContent = bt; ring.appendChild(rb);
|
|
1826
|
+
cell.appendChild(ring);
|
|
1827
|
+
if (cap){ var cp = document.createElement('div'); cp.className = 'fn-caption'; cp.textContent = cap.textContent.trim(); cell.appendChild(cp); }
|
|
1828
|
+
row.appendChild(cell);
|
|
1829
|
+
} else {
|
|
1830
|
+
row.appendChild(n);
|
|
1831
|
+
}
|
|
1832
|
+
});
|
|
1833
|
+
host.parentNode.insertBefore(row, host);
|
|
1834
|
+
host.parentNode.removeChild(host);
|
|
1835
|
+
}
|
|
626
1836
|
function applyTpl(s, tpl){
|
|
627
1837
|
ensureOrigin(s);
|
|
628
1838
|
s.innerHTML = s._origin;
|
|
629
1839
|
if (tpl === 'classic'){ s.removeAttribute('data-template'); return; }
|
|
630
1840
|
s.setAttribute('data-template', tpl);
|
|
1841
|
+
/* 图表页保护:含 chart-card 的页面跳过重排包装器(timeline/keynote/magazine/steps/poster
|
|
1842
|
+
会替换容器或清空整页,吞掉图表),保留语义结构,图表动画照常触发 */
|
|
1843
|
+
if (s.querySelector('[data-anim-chart]')) return;
|
|
631
1844
|
if (tpl === 'timeline') wrapTimeline(s);
|
|
632
1845
|
else if (tpl === 'keynote' && !isSpecialPage(s)) wrapKeynote(s);
|
|
633
1846
|
else if (tpl === 'magazine' && !isSpecialPage(s)) wrapMagazine(s);
|
|
1847
|
+
else if (tpl === 'steps' && !isSpecialPage(s)) wrapSteps(s);
|
|
1848
|
+
else if (tpl === 'vintage' && !isSpecialPage(s)) wrapVintage(s);
|
|
1849
|
+
else if (tpl === 'poster' && !isSpecialPage(s)) wrapPoster(s);
|
|
1850
|
+
else if (tpl === 'finance' && !isSpecialPage(s)) wrapFinance(s);
|
|
634
1851
|
}
|
|
635
1852
|
function applyScope(tpl, scope, selected){
|
|
636
1853
|
var n = 0;
|
|
@@ -647,12 +1864,86 @@ var tplList = document.getElementById('tplList');
|
|
|
647
1864
|
var tplDo = document.getElementById('tplDo');
|
|
648
1865
|
var btnTemplate = document.getElementById('btnTemplate');
|
|
649
1866
|
var selTpl = 'classic';
|
|
650
|
-
|
|
1867
|
+
var previewSnap = null;
|
|
1868
|
+
var tplPreview = document.getElementById('tplPreview');
|
|
1869
|
+
var tabLayout = document.getElementById('tabLayout');
|
|
1870
|
+
var tabProf = document.getElementById('tabProf');
|
|
1871
|
+
var tplScopeRow = document.getElementById('tplScopeRow');
|
|
1872
|
+
var tplHeadNote = document.getElementById('tplHeadNote');
|
|
1873
|
+
var tplTab = 'layout';
|
|
1874
|
+
var selProf = null;
|
|
1875
|
+
var profArmed = false;
|
|
1876
|
+
function tplById(id){ return TPLS.filter(function(x){ return x.id === id; })[0] || TPLS[0]; }
|
|
1877
|
+
function renderTplCards(){
|
|
1878
|
+
var html = '';
|
|
1879
|
+
TPLS.forEach(function(tp){
|
|
1880
|
+
html += '<div class="tpl-card' + (tp.id === selTpl ? ' on' : '') + '" data-tpl="' + tp.id + '">'
|
|
1881
|
+
+ '<span class="tpl-mini">' + (tp.mini || '') + '</span>'
|
|
1882
|
+
+ '<span class="nm">' + tp.name + '</span><span class="ds">' + tp.ds + '</span></div>';
|
|
1883
|
+
});
|
|
1884
|
+
tplCards.innerHTML = html;
|
|
1885
|
+
}
|
|
1886
|
+
function renderProfCards(){
|
|
1887
|
+
var html = '';
|
|
1888
|
+
PROF_CATS.forEach(function(cat){
|
|
1889
|
+
var list = PROF.filter(function(p){ return p.cat === cat.id; });
|
|
1890
|
+
if (!list.length) return;
|
|
1891
|
+
html += '<div class="tpl-cat">' + cat.name + '</div>';
|
|
1892
|
+
list.forEach(function(pr){
|
|
1893
|
+
var tp = tplById(pr.main);
|
|
1894
|
+
html += '<div class="tpl-card prof' + (pr.id === selProf ? ' on' : '') + '" data-prof="' + pr.id + '">'
|
|
1895
|
+
+ '<span class="tpl-mini">' + (tp.mini || '') + '</span>'
|
|
1896
|
+
+ '<span class="nm">' + pr.name + '<i class="pg">' + pr.pages.length + ' 页</i></span>'
|
|
1897
|
+
+ '<span class="ds">' + pr.ds + '</span></div>';
|
|
1898
|
+
});
|
|
1899
|
+
});
|
|
1900
|
+
tplCards.innerHTML = html;
|
|
1901
|
+
}
|
|
1902
|
+
function setTplTab(tab){
|
|
1903
|
+
tplTab = tab;
|
|
1904
|
+
tabLayout.classList.toggle('on', tab === 'layout');
|
|
1905
|
+
tabProf.classList.toggle('on', tab === 'prof');
|
|
1906
|
+
tplScopeRow.style.display = (tab === 'layout') ? '' : 'none';
|
|
1907
|
+
tplList.classList.remove('show');
|
|
1908
|
+
tplPreview.style.display = (tab === 'layout') ? '' : 'none';
|
|
1909
|
+
tplHeadNote.textContent = (tab === 'layout')
|
|
1910
|
+
? '模板只改版式,内容与配色不动;先「预览本页」看效果,满意再应用'
|
|
1911
|
+
: '领域 / 业务成套模板:一键生成整套通用页面(封面 · 目录 · 内容页 · 图表页),原页面替换为模板骨架,可撤销';
|
|
1912
|
+
if (previewSnap){
|
|
1913
|
+
var s0 = slides[cur];
|
|
1914
|
+
s0.innerHTML = previewSnap.html;
|
|
1915
|
+
setTplAttr(s0, previewSnap.tpl);
|
|
1916
|
+
previewSnap = null;
|
|
1917
|
+
tplPreview.textContent = '👁 预览本页';
|
|
1918
|
+
}
|
|
1919
|
+
if (tab === 'prof') renderProfCards();
|
|
1920
|
+
else renderTplCards();
|
|
1921
|
+
updateTplBtn();
|
|
1922
|
+
}
|
|
1923
|
+
tabLayout.addEventListener('click', function(){ setTplTab('layout'); });
|
|
1924
|
+
tabProf.addEventListener('click', function(){ setTplTab('prof'); });
|
|
1925
|
+
function closeTplPanel(){
|
|
1926
|
+
if (previewSnap){
|
|
1927
|
+
var s = slides[cur];
|
|
1928
|
+
s.innerHTML = previewSnap.html;
|
|
1929
|
+
setTplAttr(s, previewSnap.tpl);
|
|
1930
|
+
previewSnap = null;
|
|
1931
|
+
tplPreview.textContent = '👁 预览本页';
|
|
1932
|
+
}
|
|
1933
|
+
tplMask.classList.remove('open');
|
|
1934
|
+
}
|
|
651
1935
|
function updateTplListVis(){
|
|
652
1936
|
var sc = tplMask.querySelector('input[name="tplScope"]:checked');
|
|
653
1937
|
tplList.classList.toggle('show', !!(sc && sc.value === 'selected'));
|
|
654
1938
|
}
|
|
655
1939
|
function updateTplBtn(){
|
|
1940
|
+
if (tplTab === 'prof'){
|
|
1941
|
+
var pr = PROF.filter(function(x){ return x.id === selProf; })[0];
|
|
1942
|
+
tplDo.textContent = profArmed
|
|
1943
|
+
? '⚠ 确认:整份替换为「' + pr.name + '」(可撤销)'
|
|
1944
|
+
: (pr ? '生成成套页面(' + pr.pages.length + ' 页)' : '生成成套页面');
|
|
1945
|
+
return;
|
|
1946
|
+
}
|
|
656
1947
|
var sc = tplMask.querySelector('input[name="tplScope"]:checked');
|
|
657
1948
|
var n = N;
|
|
658
1949
|
if (sc && sc.value === 'selected') n = tplMask.querySelectorAll('.tpl-check:checked').length;
|
|
@@ -661,13 +1952,8 @@ function updateTplBtn(){
|
|
|
661
1952
|
}
|
|
662
1953
|
function openTplPanel(){
|
|
663
1954
|
selTpl = tplOf(slides[cur]);
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
html += '<div class="tpl-card' + (tp.id === selTpl ? ' on' : '') + '" data-tpl="' + tp.id + '">'
|
|
667
|
-
+ '<span class="ic">' + tp.ic + '</span>'
|
|
668
|
-
+ '<span><span class="nm">' + tp.name + '</span><span class="ds">' + tp.ds + '</span></span></div>';
|
|
669
|
-
});
|
|
670
|
-
tplCards.innerHTML = html;
|
|
1955
|
+
selProf = null;
|
|
1956
|
+
profArmed = false;
|
|
671
1957
|
var pageHtml = '';
|
|
672
1958
|
for (var i = 0; i < N; i++) {
|
|
673
1959
|
pageHtml += '<label class="cp-item"><input type="checkbox" class="tpl-check" value="' + i + '" checked>'
|
|
@@ -677,11 +1963,30 @@ function openTplPanel(){
|
|
|
677
1963
|
tplList.innerHTML = pageHtml;
|
|
678
1964
|
tplMask.querySelector('input[name="tplScope"][value="all"]').checked = true;
|
|
679
1965
|
updateTplListVis();
|
|
680
|
-
|
|
681
|
-
|
|
1966
|
+
closeCopyPanel(); closeShotPanel(); closeThemePanel();
|
|
1967
|
+
setTplTab(tplTab || 'layout');
|
|
682
1968
|
tplMask.classList.add('open');
|
|
683
1969
|
}
|
|
1970
|
+
function applyProf(){
|
|
1971
|
+
var pr = PROF.filter(function(x){ return x.id === selProf; })[0];
|
|
1972
|
+
if (!pr) return;
|
|
1973
|
+
if (!profArmed){ profArmed = true; updateTplBtn(); return; }
|
|
1974
|
+
profArmed = false;
|
|
1975
|
+
pushUndo();
|
|
1976
|
+
deck.innerHTML = pr.pages.join('');
|
|
1977
|
+
refreshSlides();
|
|
1978
|
+
slides.forEach(function(s){
|
|
1979
|
+
var tp = tplOf(s);
|
|
1980
|
+
if (tp !== 'classic' && !isSpecialPage(s)) applyTpl(s, tp);
|
|
1981
|
+
});
|
|
1982
|
+
buildThumbs();
|
|
1983
|
+
closeTplPanel();
|
|
1984
|
+
cur = 0; go(0);
|
|
1985
|
+
btnTemplate.textContent = '✓ 已套用「' + pr.name + '」';
|
|
1986
|
+
setTimeout(function(){ btnTemplate.textContent = '🎨 模板'; }, 1500);
|
|
1987
|
+
}
|
|
684
1988
|
function doApplyTpl(){
|
|
1989
|
+
if (tplTab === 'prof'){ applyProf(); return; }
|
|
685
1990
|
var sc = tplMask.querySelector('input[name="tplScope"]:checked');
|
|
686
1991
|
if (!sc) return;
|
|
687
1992
|
var selected = [];
|
|
@@ -689,7 +1994,16 @@ function doApplyTpl(){
|
|
|
689
1994
|
Array.prototype.forEach.call(tplMask.querySelectorAll('.tpl-check:checked'), function(box){ selected.push(parseInt(box.value, 10)); });
|
|
690
1995
|
if (!selected.length) return;
|
|
691
1996
|
}
|
|
1997
|
+
if (previewSnap){
|
|
1998
|
+
var s0 = slides[cur];
|
|
1999
|
+
s0.innerHTML = previewSnap.html;
|
|
2000
|
+
setTplAttr(s0, previewSnap.tpl);
|
|
2001
|
+
previewSnap = null;
|
|
2002
|
+
tplPreview.textContent = '👁 预览本页';
|
|
2003
|
+
}
|
|
2004
|
+
pushUndo();
|
|
692
2005
|
var n = applyScope(selTpl, sc.value, selected);
|
|
2006
|
+
buildThumbs();
|
|
693
2007
|
closeTplPanel();
|
|
694
2008
|
btnTemplate.textContent = '✓ 已应用 ' + n + ' 页';
|
|
695
2009
|
setTimeout(function(){ btnTemplate.textContent = '🎨 模板'; }, 1500);
|
|
@@ -697,12 +2011,22 @@ function doApplyTpl(){
|
|
|
697
2011
|
btnTemplate.addEventListener('click', openTplPanel);
|
|
698
2012
|
document.getElementById('tplCancel').addEventListener('click', closeTplPanel);
|
|
699
2013
|
tplDo.addEventListener('click', doApplyTpl);
|
|
2014
|
+
tplPreview.addEventListener('click', previewTpl);
|
|
700
2015
|
tplCards.addEventListener('click', function(e){
|
|
701
2016
|
var c = e.target.closest('.tpl-card');
|
|
702
2017
|
if (!c) return;
|
|
2018
|
+
if (c.hasAttribute('data-prof')){
|
|
2019
|
+
selProf = c.getAttribute('data-prof');
|
|
2020
|
+
profArmed = false;
|
|
2021
|
+
Array.prototype.forEach.call(tplCards.querySelectorAll('.tpl-card'), function(x){ x.classList.remove('on'); });
|
|
2022
|
+
c.classList.add('on');
|
|
2023
|
+
updateTplBtn();
|
|
2024
|
+
return;
|
|
2025
|
+
}
|
|
703
2026
|
selTpl = c.getAttribute('data-tpl');
|
|
704
|
-
Array.prototype.forEach.call(tplCards.
|
|
2027
|
+
Array.prototype.forEach.call(tplCards.querySelectorAll('.tpl-card'), function(x){ x.classList.remove('on'); });
|
|
705
2028
|
c.classList.add('on');
|
|
2029
|
+
if (previewSnap) applyTpl(slides[cur], selTpl);
|
|
706
2030
|
});
|
|
707
2031
|
tplMask.addEventListener('change', function(e){
|
|
708
2032
|
if (e.target.name === 'tplScope'){
|
|
@@ -715,37 +2039,248 @@ tplMask.addEventListener('change', function(e){
|
|
|
715
2039
|
});
|
|
716
2040
|
tplMask.addEventListener('click', function(e){ if (e.target === tplMask) closeTplPanel(); });
|
|
717
2041
|
|
|
2042
|
+
/* ── 撤销 / 重做(deck 快照 + 每页元信息;所有编辑操作可回退) ── */
|
|
2043
|
+
var deck = document.getElementById('deck');
|
|
2044
|
+
var undoStack = [], redoStack = [];
|
|
2045
|
+
/* 演示页领域卡点击:打开模板面板并选中对应成套模板 */
|
|
2046
|
+
deck.addEventListener('click', function(e){
|
|
2047
|
+
var c = e.target.closest('.prof-demo');
|
|
2048
|
+
if (!c) return;
|
|
2049
|
+
openTplPanel();
|
|
2050
|
+
setTplTab('prof');
|
|
2051
|
+
selProf = c.getAttribute('data-prof');
|
|
2052
|
+
profArmed = false;
|
|
2053
|
+
renderProfCards();
|
|
2054
|
+
updateTplBtn();
|
|
2055
|
+
});
|
|
2056
|
+
var btnUndo = document.getElementById('btnUndo');
|
|
2057
|
+
var btnRedo = document.getElementById('btnRedo');
|
|
2058
|
+
function snap(){
|
|
2059
|
+
return {
|
|
2060
|
+
html: deck.innerHTML,
|
|
2061
|
+
cur: cur,
|
|
2062
|
+
metas: slides.map(function(s){
|
|
2063
|
+
return { o: s._origin || null, t: s.getAttribute('data-template'), th: s.getAttribute('data-theme') };
|
|
2064
|
+
})
|
|
2065
|
+
};
|
|
2066
|
+
}
|
|
2067
|
+
function pushUndo(){
|
|
2068
|
+
undoStack.push(snap());
|
|
2069
|
+
if (undoStack.length > 20) undoStack.shift();
|
|
2070
|
+
redoStack = [];
|
|
2071
|
+
updateUndoBtns();
|
|
2072
|
+
}
|
|
2073
|
+
function restore(sn){
|
|
2074
|
+
deck.innerHTML = sn.html;
|
|
2075
|
+
refreshSlides();
|
|
2076
|
+
slides.forEach(function(s, k){
|
|
2077
|
+
var m = sn.metas[k];
|
|
2078
|
+
if (!m) return;
|
|
2079
|
+
if (m.o) s._origin = m.o;
|
|
2080
|
+
if (m.t) s.setAttribute('data-template', m.t);
|
|
2081
|
+
if (m.th) s.setAttribute('data-theme', m.th);
|
|
2082
|
+
});
|
|
2083
|
+
buildThumbs();
|
|
2084
|
+
updateUndoBtns();
|
|
2085
|
+
go(Math.min(sn.cur, N - 1));
|
|
2086
|
+
}
|
|
2087
|
+
function undo(){ if (!undoStack.length) return; redoStack.push(snap()); restore(undoStack.pop()); }
|
|
2088
|
+
function redo(){ if (!redoStack.length) return; undoStack.push(snap()); restore(redoStack.pop()); }
|
|
2089
|
+
function updateUndoBtns(){
|
|
2090
|
+
btnUndo.disabled = !undoStack.length;
|
|
2091
|
+
btnRedo.disabled = !redoStack.length;
|
|
2092
|
+
}
|
|
2093
|
+
btnUndo.addEventListener('click', undo);
|
|
2094
|
+
btnRedo.addEventListener('click', redo);
|
|
2095
|
+
function anyMaskOpen(){
|
|
2096
|
+
return tplMask.classList.contains('open') || copyMask.classList.contains('open')
|
|
2097
|
+
|| shotMask.classList.contains('open') || addMask.classList.contains('open')
|
|
2098
|
+
|| helpMask.classList.contains('open') || themeMask.classList.contains('open');
|
|
2099
|
+
}
|
|
2100
|
+
|
|
2101
|
+
/* ── 预览本页:临时套模板看效果,不落 data-template,取消自动还原 ── */
|
|
2102
|
+
function setTplAttr(s, tpl){
|
|
2103
|
+
if (tpl === 'classic') s.removeAttribute('data-template');
|
|
2104
|
+
else s.setAttribute('data-template', tpl);
|
|
2105
|
+
}
|
|
2106
|
+
function previewTpl(){
|
|
2107
|
+
var s = slides[cur];
|
|
2108
|
+
if (previewSnap){
|
|
2109
|
+
s.innerHTML = previewSnap.html;
|
|
2110
|
+
setTplAttr(s, previewSnap.tpl);
|
|
2111
|
+
previewSnap = null;
|
|
2112
|
+
tplPreview.textContent = '👁 预览本页';
|
|
2113
|
+
return;
|
|
2114
|
+
}
|
|
2115
|
+
previewSnap = { tpl: tplOf(s), html: s.innerHTML };
|
|
2116
|
+
applyTpl(s, selTpl);
|
|
2117
|
+
tplPreview.textContent = '👁 还原本页';
|
|
2118
|
+
}
|
|
2119
|
+
|
|
2120
|
+
/* ── 页面管理边栏(缩略图浏览 / 点击跳转 / 复页 / 排序 / 删页 / 新页) ── */
|
|
2121
|
+
var sidePanel = document.getElementById('sidePanel');
|
|
2122
|
+
var spList = document.getElementById('spList');
|
|
2123
|
+
function refreshSlides(){
|
|
2124
|
+
slides = Array.prototype.slice.call(deck.querySelectorAll('.slide'));
|
|
2125
|
+
N = slides.length;
|
|
2126
|
+
}
|
|
2127
|
+
function buildThumbs(){
|
|
2128
|
+
var html = '';
|
|
2129
|
+
slides.forEach(function(s, k){
|
|
2130
|
+
var t = s.getAttribute('data-title') || ('第 ' + (k + 1) + ' 页');
|
|
2131
|
+
html += '<div class="thumb' + (k === cur ? ' cur' : '') + '" data-i="' + k + '">'
|
|
2132
|
+
+ '<span class="thumb-no">' + (k + 1) + '</span>'
|
|
2133
|
+
+ '<span class="thumb-t">' + escapeHtml(t) + '</span>'
|
|
2134
|
+
+ '<div class="thumb-ops">'
|
|
2135
|
+
+ '<button data-act="dup" title="复制本页为副本(插在其后)">⧉</button>'
|
|
2136
|
+
+ '<button data-act="up" title="上移" ' + (k === 0 ? 'disabled' : '') + '>↑</button>'
|
|
2137
|
+
+ '<button data-act="down" title="下移" ' + (k === N - 1 ? 'disabled' : '') + '>↓</button>'
|
|
2138
|
+
+ '<button class="op-del" data-act="del" title="删除本页" ' + (N === 1 ? 'disabled' : '') + '>🗑</button>'
|
|
2139
|
+
+ '</div>'
|
|
2140
|
+
+ '<div class="thumb-wrap">' + s.outerHTML + '</div></div>';
|
|
2141
|
+
});
|
|
2142
|
+
spList.innerHTML = html;
|
|
2143
|
+
Array.prototype.forEach.call(spList.querySelectorAll('.thumb-wrap .slide'), function(cl){
|
|
2144
|
+
cl.className = 'thumb-slide';
|
|
2145
|
+
var w = cl.parentNode.clientWidth || 180;
|
|
2146
|
+
cl.style.transform = 'scale(' + (w / 1280) + ')';
|
|
2147
|
+
});
|
|
2148
|
+
}
|
|
2149
|
+
function thumbCur(){
|
|
2150
|
+
Array.prototype.forEach.call(spList.children, function(t, k){ t.classList.toggle('cur', k === cur); });
|
|
2151
|
+
}
|
|
2152
|
+
spList.addEventListener('click', function(e){
|
|
2153
|
+
var act = e.target.closest('[data-act]');
|
|
2154
|
+
if (act){
|
|
2155
|
+
var i = parseInt(act.closest('.thumb').getAttribute('data-i'), 10);
|
|
2156
|
+
var a = act.getAttribute('data-act');
|
|
2157
|
+
if (a === 'del' && N > 1){ pushUndo(); deletePage(i); }
|
|
2158
|
+
else if (a === 'dup'){ pushUndo(); dupPage(i); }
|
|
2159
|
+
else if (a === 'up'){ pushUndo(); movePage(i, -1); }
|
|
2160
|
+
else if (a === 'down'){ pushUndo(); movePage(i, 1); }
|
|
2161
|
+
return;
|
|
2162
|
+
}
|
|
2163
|
+
var th = e.target.closest('.thumb');
|
|
2164
|
+
if (th) leaveThenGo(parseInt(th.getAttribute('data-i'), 10));
|
|
2165
|
+
});
|
|
2166
|
+
document.getElementById('btnPages').addEventListener('click', function(){ toggleSide(); });
|
|
2167
|
+
document.getElementById('btnTools').addEventListener('click', function(){ toggleSide('tools'); });
|
|
2168
|
+
document.getElementById('spAdd').addEventListener('click', openAddPanel);
|
|
2169
|
+
document.getElementById('spClose').addEventListener('click', function(){ sidePanel.classList.remove('open'); });
|
|
2170
|
+
|
|
2171
|
+
/* ── 新增 / 删除页面 ── */
|
|
2172
|
+
function blankSlideHtml(tpl){
|
|
2173
|
+
var tp = TPLS.filter(function(x){ return x.id === tpl; })[0] || TPLS[0];
|
|
2174
|
+
return '<section class="slide" data-title="新页面"' + (tpl === 'classic' ? '' : ' data-template="' + tpl + '"') + '>'
|
|
2175
|
+
+ '<div class="s-head"><h2>新页面标题</h2><span class="tag">' + tp.name + '</span></div>'
|
|
2176
|
+
+ '<div class="grid2">'
|
|
2177
|
+
+ '<div class="card"><h4>要点一<span class="en">Point 1</span></h4><p>在这里写下要点内容,然后按 F 放映。</p></div>'
|
|
2178
|
+
+ '<div class="card"><h4>要点二<span class="en">Point 2</span></h4><p>支持全部 16 套版式与 16 套主题。</p></div>'
|
|
2179
|
+
+ '</div></section>';
|
|
2180
|
+
}
|
|
2181
|
+
function addPage(tpl){
|
|
2182
|
+
var div = document.createElement('div');
|
|
2183
|
+
div.innerHTML = blankSlideHtml(tpl);
|
|
2184
|
+
var s = div.firstChild;
|
|
2185
|
+
deck.insertBefore(s, slides[cur].nextSibling);
|
|
2186
|
+
refreshSlides();
|
|
2187
|
+
var tp = tplOf(s);
|
|
2188
|
+
if (tp !== 'classic' && !isSpecialPage(s)) applyTpl(s, tp);
|
|
2189
|
+
buildThumbs();
|
|
2190
|
+
go(cur + 1);
|
|
2191
|
+
}
|
|
2192
|
+
function deletePage(i){
|
|
2193
|
+
if (N <= 1) return;
|
|
2194
|
+
deck.removeChild(slides[i]);
|
|
2195
|
+
refreshSlides();
|
|
2196
|
+
buildThumbs();
|
|
2197
|
+
if (cur >= N) cur = N - 1;
|
|
2198
|
+
go(cur);
|
|
2199
|
+
}
|
|
2200
|
+
function dupPage(i){
|
|
2201
|
+
var src = slides[i];
|
|
2202
|
+
var cp = src.cloneNode(true);
|
|
2203
|
+
cp.classList.remove('active');
|
|
2204
|
+
deck.insertBefore(cp, src.nextSibling);
|
|
2205
|
+
refreshSlides();
|
|
2206
|
+
buildThumbs();
|
|
2207
|
+
go(i + 1);
|
|
2208
|
+
}
|
|
2209
|
+
function movePage(i, dir){
|
|
2210
|
+
var j = i + dir;
|
|
2211
|
+
if (j < 0 || j >= N) return;
|
|
2212
|
+
var s = slides[i];
|
|
2213
|
+
if (dir < 0) deck.insertBefore(s, slides[j]);
|
|
2214
|
+
else deck.insertBefore(s, slides[j].nextSibling);
|
|
2215
|
+
refreshSlides();
|
|
2216
|
+
buildThumbs();
|
|
2217
|
+
go(j);
|
|
2218
|
+
}
|
|
2219
|
+
|
|
2220
|
+
/* ── 新增页面板(16 版式任选,插在当前页之后) ── */
|
|
2221
|
+
var addMask = document.getElementById('addMask');
|
|
2222
|
+
var addCards = document.getElementById('addCards');
|
|
2223
|
+
function openAddPanel(){
|
|
2224
|
+
themeMask.classList.remove('open');
|
|
2225
|
+
var html = '';
|
|
2226
|
+
TPLS.forEach(function(tp){
|
|
2227
|
+
html += '<div class="add-card" data-tpl="' + tp.id + '">'
|
|
2228
|
+
+ '<div class="tpl-mini">' + (tp.mini || '') + '</div>'
|
|
2229
|
+
+ '<span class="nm">' + tp.name + '</span></div>';
|
|
2230
|
+
});
|
|
2231
|
+
addCards.innerHTML = html;
|
|
2232
|
+
addMask.classList.add('open');
|
|
2233
|
+
}
|
|
2234
|
+
document.getElementById('addCancel').addEventListener('click', function(){ addMask.classList.remove('open'); });
|
|
2235
|
+
addMask.addEventListener('click', function(e){ if (e.target === addMask) addMask.classList.remove('open'); });
|
|
2236
|
+
addCards.addEventListener('click', function(e){
|
|
2237
|
+
var c = e.target.closest('.add-card');
|
|
2238
|
+
if (!c) return;
|
|
2239
|
+
pushUndo();
|
|
2240
|
+
addPage(c.getAttribute('data-tpl'));
|
|
2241
|
+
addMask.classList.remove('open');
|
|
2242
|
+
});
|
|
2243
|
+
|
|
718
2244
|
/* ── 翻页 / 键盘 ── */
|
|
719
2245
|
document.getElementById('btnPrev').addEventListener('click', prev);
|
|
720
2246
|
document.getElementById('btnNext').addEventListener('click', next);
|
|
721
2247
|
document.addEventListener('keydown', function(e){
|
|
722
2248
|
if (e.target.tagName === 'INPUT' || e.target.tagName === 'SELECT') return;
|
|
2249
|
+
if ((e.ctrlKey || e.metaKey) && (e.key === 'z' || e.key === 'Z')){
|
|
2250
|
+
if (!anyMaskOpen()) (e.shiftKey ? redo() : undo());
|
|
2251
|
+
e.preventDefault(); return;
|
|
2252
|
+
}
|
|
2253
|
+
if ((e.ctrlKey || e.metaKey) && (e.key === 'y' || e.key === 'Y')){
|
|
2254
|
+
if (!anyMaskOpen()) redo();
|
|
2255
|
+
e.preventDefault(); return;
|
|
2256
|
+
}
|
|
723
2257
|
if (e.repeat) return;
|
|
724
2258
|
switch (e.key) {
|
|
725
2259
|
case 'ArrowRight': case 'ArrowDown': case 'PageDown': next(); e.preventDefault(); break;
|
|
726
2260
|
case 'ArrowLeft': case 'ArrowUp': case 'PageUp': prev(); e.preventDefault(); break;
|
|
727
2261
|
case ' ': next(); e.preventDefault(); break;
|
|
728
|
-
case 'Home':
|
|
729
|
-
case 'End':
|
|
2262
|
+
case 'Home': leaveThenGo(0); break;
|
|
2263
|
+
case 'End': leaveThenGo(N - 1); break;
|
|
730
2264
|
case 'p': case 'P': playing ? stopPlay() : startPlay(); break;
|
|
731
2265
|
case 's': case 'S': shotPage(); break;
|
|
732
2266
|
case 'c': case 'C': copyPage(); break;
|
|
733
2267
|
case 'f': case 'F': toggleFull(); break;
|
|
2268
|
+
case 'g': case 'G': toggleSide(); break;
|
|
734
2269
|
case '?': helpMask.classList.add('open'); break;
|
|
735
|
-
case 'Escape': helpMask.classList.remove('open');
|
|
2270
|
+
case 'Escape': helpMask.classList.remove('open'); closeCopyPanel(); closeShotPanel(); closeTplPanel(); closeThemePanel(); addMask.classList.remove('open'); sidePanel.classList.remove('open'); if (document.fullscreenElement) document.exitFullscreen(); break;
|
|
736
2271
|
default:
|
|
737
|
-
if (/^[1-9]$/.test(e.key) && parseInt(e.key, 10) <= N)
|
|
2272
|
+
if (/^[1-9]$/.test(e.key) && parseInt(e.key, 10) <= N) leaveThenGo(parseInt(e.key, 10) - 1);
|
|
738
2273
|
}
|
|
739
2274
|
});
|
|
740
2275
|
|
|
741
2276
|
/* ── 页内连接 / 外部链接 / hash 定位 ── */
|
|
742
2277
|
document.getElementById('deck').addEventListener('click', function(e){
|
|
743
2278
|
var t = e.target.closest('[data-goto]');
|
|
744
|
-
if (t)
|
|
2279
|
+
if (t) leaveThenGo(parseInt(t.getAttribute('data-goto'), 10));
|
|
745
2280
|
});
|
|
746
2281
|
window.addEventListener('hashchange', function(){
|
|
747
2282
|
var m = location.hash.match(/^#\/(\d+)$/);
|
|
748
|
-
if (m)
|
|
2283
|
+
if (m) leaveThenGo(parseInt(m[1], 10) - 1);
|
|
749
2284
|
});
|
|
750
2285
|
|
|
751
2286
|
/* ── 全屏 ── */
|
|
@@ -785,6 +2320,7 @@ function pagePreview(i){
|
|
|
785
2320
|
return line.length > 26 ? line.slice(0, 26) + '…' : line;
|
|
786
2321
|
}
|
|
787
2322
|
function openCopyPanel(){
|
|
2323
|
+
themeMask.classList.remove('open');
|
|
788
2324
|
var html = '';
|
|
789
2325
|
for (var i = 0; i < N; i++) {
|
|
790
2326
|
html += '<label class="cp-item"><input type="checkbox" class="cp-check" value="' + i + '" checked>'
|
|
@@ -819,6 +2355,7 @@ function copySelectedPages(){
|
|
|
819
2355
|
} else { fallbackCopy(all); done(); }
|
|
820
2356
|
}
|
|
821
2357
|
btnCopyMulti.addEventListener('click', openCopyPanel);
|
|
2358
|
+
document.getElementById('btnCopy').addEventListener('click', copyPage);
|
|
822
2359
|
document.getElementById('cpCancel').addEventListener('click', closeCopyPanel);
|
|
823
2360
|
cpDo.addEventListener('click', copySelectedPages);
|
|
824
2361
|
cpAll.addEventListener('change', function(){
|
|
@@ -840,20 +2377,25 @@ copyMask.addEventListener('click', function(e){ if (e.target === copyMask) close
|
|
|
840
2377
|
/* ── 截图(SVG foreignObject → Canvas → PNG 2x,只含主体):单页 + 选页批量共用 renderShot ── */
|
|
841
2378
|
function renderShot(i, cb){
|
|
842
2379
|
var clone = slides[i].cloneNode(true);
|
|
843
|
-
clone.classList.remove('dim');
|
|
2380
|
+
clone.classList.remove('dim'); clone.classList.add('active', 'shot-clone');
|
|
844
2381
|
clone.style.position = 'relative'; clone.style.inset = 'auto';
|
|
845
2382
|
clone.style.padding = '64px 80px'; clone.style.display = 'flex';
|
|
846
2383
|
clone.style.opacity = '1'; clone.style.visibility = 'visible';
|
|
847
2384
|
clone.style.transform = 'none'; clone.style.transition = 'none';
|
|
848
2385
|
var styleText = Array.prototype.slice.call(document.querySelectorAll('style')).map(function(x){ return x.textContent; }).join('\n');
|
|
2386
|
+
styleText += '\n.shot-clone [data-anim], .shot-clone [data-anim-emphasis], .shot-clone [data-anim-leave]{ opacity:1 !important; animation:none !important; }';
|
|
849
2387
|
var wrap = document.createElement('div');
|
|
850
2388
|
wrap.setAttribute('data-theme', document.documentElement.getAttribute('data-theme') || 'tech');
|
|
851
2389
|
wrap.style.width = '1280px'; wrap.style.height = '720px';
|
|
852
2390
|
wrap.style.background = 'var(--bg)';
|
|
853
2391
|
wrap.appendChild(clone);
|
|
2392
|
+
/* foreignObject 内要求 XHTML 良构:空标签自闭合(<br>/<img> 等),否则 SVG 无法解析 */
|
|
2393
|
+
var shotHtml = wrap.outerHTML.replace(/<(br|hr|img|input|meta|link|source|wbr|col)\b([^>]*)>/gi, function(m, tag, rest){
|
|
2394
|
+
return '<' + tag + rest.replace(/\/\s*$/, '') + '/>';
|
|
2395
|
+
});
|
|
854
2396
|
var svg = '<svg xmlns="http://www.w3.org/2000/svg" width="1280" height="720" viewBox="0 0 1280 720">'
|
|
855
2397
|
+ '<foreignObject width="1280" height="720">'
|
|
856
|
-
+ '<div xmlns="http://www.w3.org/1999/xhtml"><style>' + styleText + '</style>' +
|
|
2398
|
+
+ '<div xmlns="http://www.w3.org/1999/xhtml"><style>' + styleText + '</style>' + shotHtml + '</div>'
|
|
857
2399
|
+ '</foreignObject></svg>';
|
|
858
2400
|
var img = new Image();
|
|
859
2401
|
img.onload = function(){
|
|
@@ -883,6 +2425,7 @@ var spAll = document.getElementById('spAll');
|
|
|
883
2425
|
var spDo = document.getElementById('spDo');
|
|
884
2426
|
var btnShotMulti = document.getElementById('btnShotMulti');
|
|
885
2427
|
function openShotPanel(){
|
|
2428
|
+
themeMask.classList.remove('open');
|
|
886
2429
|
var html = '';
|
|
887
2430
|
for (var i = 0; i < N; i++) {
|
|
888
2431
|
html += '<label class="cp-item"><input type="checkbox" class="sp-check" value="' + i + '" checked>'
|
|
@@ -921,6 +2464,7 @@ function shotSelectedPages(){
|
|
|
921
2464
|
step();
|
|
922
2465
|
}
|
|
923
2466
|
btnShotMulti.addEventListener('click', openShotPanel);
|
|
2467
|
+
document.getElementById('btnShot').addEventListener('click', shotPage);
|
|
924
2468
|
document.getElementById('spCancel').addEventListener('click', closeShotPanel);
|
|
925
2469
|
spDo.addEventListener('click', shotSelectedPages);
|
|
926
2470
|
spAll.addEventListener('change', function(){
|
|
@@ -967,7 +2511,184 @@ if (shotParam && shotParam !== 'all' && /^\d+$/.test(shotParam)){
|
|
|
967
2511
|
if (p >= 1 && p <= N){ go(p - 1); jumped = true; }
|
|
968
2512
|
}
|
|
969
2513
|
fit();
|
|
2514
|
+
buildThumbs();
|
|
970
2515
|
if (!jumped) go(0);
|
|
2516
|
+
|
|
2517
|
+
/* ═══ 动画控制:翻页八套 + 入场/离场/强调 + 标题文字动画 + 应用范围(localStorage 记忆,失败静默)═══ */
|
|
2518
|
+
var deckEl = document.getElementById('deck');
|
|
2519
|
+
var TRANS_LIST = ['slide-lr','fade','slide-ud','zoom','flip','cube','wipe','dissolve'];
|
|
2520
|
+
var sideTabSaved = null; try{ sideTabSaved = localStorage.getItem('md-deck-side-tab'); }catch(e){}
|
|
2521
|
+
var leaving = false;
|
|
2522
|
+
|
|
2523
|
+
function openSideTab(name){
|
|
2524
|
+
Array.prototype.forEach.call(document.querySelectorAll('.sp-tab'), function(b){
|
|
2525
|
+
b.classList.toggle('on', b.getAttribute('data-tab') === name);
|
|
2526
|
+
});
|
|
2527
|
+
document.getElementById('panePages').classList.toggle('on', name === 'pages');
|
|
2528
|
+
document.getElementById('paneTools').classList.toggle('on', name === 'tools');
|
|
2529
|
+
}
|
|
2530
|
+
function openSide(name){
|
|
2531
|
+
buildThumbs();
|
|
2532
|
+
var t = name || sideTabSaved || 'pages';
|
|
2533
|
+
if (t !== 'pages' && t !== 'tools') t = 'pages';
|
|
2534
|
+
openSideTab(t);
|
|
2535
|
+
sidePanel.classList.add('open');
|
|
2536
|
+
}
|
|
2537
|
+
function toggleSide(name){
|
|
2538
|
+
if (sidePanel.classList.contains('open')){ sidePanel.classList.remove('open'); return; }
|
|
2539
|
+
openSide(name);
|
|
2540
|
+
}
|
|
2541
|
+
|
|
2542
|
+
/* ── 离场引擎:翻离当前页前先播元素离场动画(0.48s 窗口),再切页 ── */
|
|
2543
|
+
function leaveThenGo(i){
|
|
2544
|
+
if (leaving) return;
|
|
2545
|
+
i = Math.max(0, Math.min(N - 1, i));
|
|
2546
|
+
if (i === cur){ go(i); return; }
|
|
2547
|
+
var s = slides[cur];
|
|
2548
|
+
var nodes = s ? s.querySelectorAll('[data-anim-leave]:not([data-anim-leave="none"])') : [];
|
|
2549
|
+
if (nodes.length === 0 || deckEl.getAttribute('data-anim') === 'off'){ go(i); return; }
|
|
2550
|
+
leaving = true;
|
|
2551
|
+
s.classList.add('leaving');
|
|
2552
|
+
Array.prototype.forEach.call(nodes, function(el){
|
|
2553
|
+
el.style.animation = 'none'; void el.offsetWidth; el.style.animation = '';
|
|
2554
|
+
});
|
|
2555
|
+
setTimeout(function(){
|
|
2556
|
+
s.classList.remove('leaving');
|
|
2557
|
+
leaving = false;
|
|
2558
|
+
go(i);
|
|
2559
|
+
}, 480);
|
|
2560
|
+
}
|
|
2561
|
+
|
|
2562
|
+
/* ── 工具 Tab:动画库 / 应用范围 / 标题文字 ── */
|
|
2563
|
+
(function(){
|
|
2564
|
+
/* 应用范围:全部页面 / 仅本页 */
|
|
2565
|
+
var scope = 'all';
|
|
2566
|
+
var savedScope = null; try{ savedScope = localStorage.getItem('md-deck-anim-scope'); }catch(e){}
|
|
2567
|
+
if (savedScope === 'current' || savedScope === 'all') scope = savedScope;
|
|
2568
|
+
var scopeRadios = Array.prototype.slice.call(document.querySelectorAll('input[name="animScope"]'));
|
|
2569
|
+
function syncScope(){
|
|
2570
|
+
scopeRadios.forEach(function(r){
|
|
2571
|
+
var sel = (r.value === scope);
|
|
2572
|
+
r.checked = sel;
|
|
2573
|
+
if (r.closest('label')) r.closest('label').classList.toggle('sel', sel);
|
|
2574
|
+
});
|
|
2575
|
+
}
|
|
2576
|
+
syncScope();
|
|
2577
|
+
scopeRadios.forEach(function(r){ r.addEventListener('change', function(){
|
|
2578
|
+
if (r.checked){ scope = r.value; try{ localStorage.setItem('md-deck-anim-scope', scope); }catch(e){} syncScope(); }
|
|
2579
|
+
}); });
|
|
2580
|
+
function animSlides(){ return scope === 'all' ? slides : [slides[cur]]; }
|
|
2581
|
+
function animEls(s){
|
|
2582
|
+
return s.querySelectorAll('[data-anim]:not(.tchar):not(.tword):not(.tline), [data-anim-emphasis], [data-anim-leave]');
|
|
2583
|
+
}
|
|
2584
|
+
|
|
2585
|
+
/* 翻页风格:八套按钮网格 */
|
|
2586
|
+
var tgBtns = Array.prototype.slice.call(document.querySelectorAll('#tgGrid [data-tg]'));
|
|
2587
|
+
function setTransition(v){
|
|
2588
|
+
deckEl.setAttribute('data-transition', v);
|
|
2589
|
+
tgBtns.forEach(function(b){ b.classList.toggle('on', b.getAttribute('data-tg') === v); });
|
|
2590
|
+
try{ localStorage.setItem('md-deck-transition', v); }catch(e){}
|
|
2591
|
+
}
|
|
2592
|
+
var savedT = null; try{ savedT = localStorage.getItem('md-deck-transition'); }catch(e){}
|
|
2593
|
+
if (savedT && TRANS_LIST.indexOf(savedT) !== -1){ setTransition(savedT); }
|
|
2594
|
+
else { setTransition(deckEl.getAttribute('data-transition') || 'slide-lr'); }
|
|
2595
|
+
tgBtns.forEach(function(b){ b.addEventListener('click', function(){ setTransition(b.getAttribute('data-tg')); }); });
|
|
2596
|
+
|
|
2597
|
+
/* 入场开关 */
|
|
2598
|
+
var chkA = document.getElementById('chkAnim');
|
|
2599
|
+
function setAnim(v){
|
|
2600
|
+
deckEl.setAttribute('data-anim', v ? 'on' : 'off');
|
|
2601
|
+
try{ localStorage.setItem('md-deck-anim', v ? 'on' : 'off'); }catch(e){}
|
|
2602
|
+
}
|
|
2603
|
+
var savedA = null; try{ savedA = localStorage.getItem('md-deck-anim'); }catch(e){}
|
|
2604
|
+
if (savedA === 'off' || savedA === 'on'){ setAnim(savedA === 'on'); chkA.checked = savedA === 'on'; }
|
|
2605
|
+
else { chkA.checked = deckEl.getAttribute('data-anim') !== 'off'; }
|
|
2606
|
+
chkA.addEventListener('change', function(){ setAnim(chkA.checked); });
|
|
2607
|
+
|
|
2608
|
+
/* 入场 / 离场 / 强调:点选即应用到范围内带标记的元素 */
|
|
2609
|
+
var enterBtns = Array.prototype.slice.call(document.querySelectorAll('#enterGrid [data-a]'));
|
|
2610
|
+
var leaveBtns = Array.prototype.slice.call(document.querySelectorAll('#leaveGrid [data-l]'));
|
|
2611
|
+
var emphBtns = Array.prototype.slice.call(document.querySelectorAll('#emphGrid [data-e]'));
|
|
2612
|
+
function mark(btns, v, attr){ btns.forEach(function(b){ b.classList.toggle('on', b.getAttribute(attr) === v); }); }
|
|
2613
|
+
function applyEnter(v){
|
|
2614
|
+
animSlides().forEach(function(s){ animEls(s).forEach(function(el){
|
|
2615
|
+
el.setAttribute('data-anim', v);
|
|
2616
|
+
if (v === 'none') el.removeAttribute('data-anim-delay');
|
|
2617
|
+
el.removeAttribute('data-anim-emphasis');
|
|
2618
|
+
}); });
|
|
2619
|
+
mark(enterBtns, v, 'data-a');
|
|
2620
|
+
}
|
|
2621
|
+
function applyLeave(v){
|
|
2622
|
+
animSlides().forEach(function(s){ animEls(s).forEach(function(el){
|
|
2623
|
+
if (v === 'none') el.removeAttribute('data-anim-leave');
|
|
2624
|
+
else el.setAttribute('data-anim-leave', v);
|
|
2625
|
+
}); });
|
|
2626
|
+
mark(leaveBtns, v, 'data-l');
|
|
2627
|
+
}
|
|
2628
|
+
function applyEmph(v){
|
|
2629
|
+
animSlides().forEach(function(s){ animEls(s).forEach(function(el){
|
|
2630
|
+
if (v === 'none') el.removeAttribute('data-anim-emphasis');
|
|
2631
|
+
else { el.setAttribute('data-anim-emphasis', v); el.removeAttribute('data-anim'); el.removeAttribute('data-anim-delay'); }
|
|
2632
|
+
}); });
|
|
2633
|
+
mark(emphBtns, v, 'data-e');
|
|
2634
|
+
}
|
|
2635
|
+
enterBtns.forEach(function(b){ b.addEventListener('click', function(){ applyEnter(b.getAttribute('data-a')); }); });
|
|
2636
|
+
leaveBtns.forEach(function(b){ b.addEventListener('click', function(){ applyLeave(b.getAttribute('data-l')); }); });
|
|
2637
|
+
emphBtns.forEach(function(b){ b.addEventListener('click', function(){ applyEmph(b.getAttribute('data-e')); }); });
|
|
2638
|
+
|
|
2639
|
+
/* 标题文字动画:拆 h1/h2/h3/.s-title 为字 / 词 / 行,复用入场错落;data-md-orig 保存原文可还原 */
|
|
2640
|
+
var textBtns = Array.prototype.slice.call(document.querySelectorAll('#textGrid [data-ta]'));
|
|
2641
|
+
function restoreText(el){
|
|
2642
|
+
if (el.hasAttribute('data-md-orig')){ el.innerHTML = el.getAttribute('data-md-orig'); el.removeAttribute('data-md-orig'); }
|
|
2643
|
+
}
|
|
2644
|
+
function splitText(el, mode){
|
|
2645
|
+
var raw = el.getAttribute('data-md-orig') || el.innerHTML;
|
|
2646
|
+
if (!el.hasAttribute('data-md-orig')) el.setAttribute('data-md-orig', raw);
|
|
2647
|
+
var lines = raw.split(/<br\s*\/?>/i);
|
|
2648
|
+
var out = '';
|
|
2649
|
+
for (var li = 0; li < lines.length; li++){
|
|
2650
|
+
var plain = lines[li].replace(/<[^>]*>/g, '');
|
|
2651
|
+
var pieces;
|
|
2652
|
+
if (mode === 'char') pieces = plain.split('');
|
|
2653
|
+
else if (mode === 'word') pieces = plain.split(/\s+/).filter(function(x){ return x.length > 0; });
|
|
2654
|
+
else pieces = [plain];
|
|
2655
|
+
for (var pi = 0; pi < pieces.length; pi++){
|
|
2656
|
+
if (pieces[pi] === ' ') { out += ' '; continue; }
|
|
2657
|
+
var cls = mode === 'char' ? 'tchar' : (mode === 'word' ? 'tword' : 'tline');
|
|
2658
|
+
out += '<span class="' + cls + '" data-anim="fade-up" style="animation-delay:' + Math.min(pi * 60, 600) + 'ms">' + escapeHtml(pieces[pi]) + '</span>';
|
|
2659
|
+
if (mode === 'word' && pi < pieces.length - 1) out += ' ';
|
|
2660
|
+
}
|
|
2661
|
+
if (li < lines.length - 1) out += '<br>';
|
|
2662
|
+
}
|
|
2663
|
+
el.innerHTML = out;
|
|
2664
|
+
}
|
|
2665
|
+
function applyText(mode){
|
|
2666
|
+
animSlides().forEach(function(s){
|
|
2667
|
+
s.querySelectorAll('h1,h2,h3,.s-title').forEach(function(el){
|
|
2668
|
+
restoreText(el);
|
|
2669
|
+
if (mode !== 'none') splitText(el, mode);
|
|
2670
|
+
});
|
|
2671
|
+
});
|
|
2672
|
+
mark(textBtns, mode, 'data-ta');
|
|
2673
|
+
}
|
|
2674
|
+
var savedTA = null; try{ savedTA = localStorage.getItem('md-deck-text-anim'); }catch(e){}
|
|
2675
|
+
if (savedTA === 'char' || savedTA === 'word' || savedTA === 'line'){ applyText(savedTA); }
|
|
2676
|
+
else { mark(textBtns, 'none', 'data-ta'); }
|
|
2677
|
+
textBtns.forEach(function(b){ b.addEventListener('click', function(){
|
|
2678
|
+
var m = b.getAttribute('data-ta');
|
|
2679
|
+
applyText(m);
|
|
2680
|
+
try{ localStorage.setItem('md-deck-text-anim', m); }catch(e){}
|
|
2681
|
+
}); });
|
|
2682
|
+
|
|
2683
|
+
/* 双 Tab 切换 */
|
|
2684
|
+
Array.prototype.forEach.call(document.querySelectorAll('.sp-tab'), function(b){
|
|
2685
|
+
b.addEventListener('click', function(){
|
|
2686
|
+
openSideTab(b.getAttribute('data-tab'));
|
|
2687
|
+
try{ localStorage.setItem('md-deck-side-tab', b.getAttribute('data-tab')); }catch(e){}
|
|
2688
|
+
});
|
|
2689
|
+
});
|
|
2690
|
+
openSideTab(sideTabSaved === 'tools' ? 'tools' : 'pages');
|
|
2691
|
+
})();
|
|
971
2692
|
</script>
|
|
972
2693
|
</body>
|
|
973
2694
|
</html>
|