{"id":109,"date":"2026-04-25T22:27:46","date_gmt":"2026-04-25T14:27:46","guid":{"rendered":"https:\/\/www.tom-thu.cn:18434\/?p=109"},"modified":"2026-04-25T22:27:47","modified_gmt":"2026-04-25T14:27:47","slug":"%e3%80%90%e5%b7%a5%e5%85%b7%e3%80%91ai%e5%86%99ppt%e6%a0%b7%e5%bc%8fhtml%e6%b3%a8%e6%84%8f%e4%ba%8b%e9%a1%b9","status":"publish","type":"post","link":"https:\/\/www.tom-thu.cn\/?p=109","title":{"rendered":"\u3010\u5de5\u5177\u3011AI\u5199PPT\u6837\u5f0fHTML\u6ce8\u610f\u4e8b\u9879"},"content":{"rendered":"<p><!DOCTYPE html><br \/>\n<html><br \/>\n<head><br \/>\n<title>blog_part2_technical.md<\/title><br \/>\n<meta http-equiv=\"Content-type\" content=\"text\/html;charset=UTF-8\"><\/p>\n<style>\n\/* https:\/\/github.com\/microsoft\/vscode\/blob\/master\/extensions\/markdown-language-features\/media\/markdown.css *\/\n\/*---------------------------------------------------------------------------------------------\n *  Copyright (c) Microsoft Corporation. All rights reserved.\n *  Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*\/<\/p>\n<p>body {\n\tfont-family: var(--vscode-markdown-font-family, -apple-system, BlinkMacSystemFont, \"Segoe WPC\", \"Segoe UI\", \"Ubuntu\", \"Droid Sans\", sans-serif);\n\tfont-size: var(--vscode-markdown-font-size, 14px);\n\tpadding: 0 26px;\n\tline-height: var(--vscode-markdown-line-height, 22px);\n\tword-wrap: break-word;\n}<\/p>\n<p>#code-csp-warning {\n\tposition: fixed;\n\ttop: 0;\n\tright: 0;\n\tcolor: white;\n\tmargin: 16px;\n\ttext-align: center;\n\tfont-size: 12px;\n\tfont-family: sans-serif;\n\tbackground-color:#444444;\n\tcursor: pointer;\n\tpadding: 6px;\n\tbox-shadow: 1px 1px 1px rgba(0,0,0,.25);\n}<\/p>\n<p>#code-csp-warning:hover {\n\ttext-decoration: none;\n\tbackground-color:#007acc;\n\tbox-shadow: 2px 2px 2px rgba(0,0,0,.25);\n}<\/p>\n<p>body.scrollBeyondLastLine {\n\tmargin-bottom: calc(100vh - 22px);\n}<\/p>\n<p>body.showEditorSelection .code-line {\n\tposition: relative;\n}<\/p>\n<p>body.showEditorSelection .code-active-line:before,\nbody.showEditorSelection .code-line:hover:before {\n\tcontent: \"\";\n\tdisplay: block;\n\tposition: absolute;\n\ttop: 0;\n\tleft: -12px;\n\theight: 100%;\n}<\/p>\n<p>body.showEditorSelection li.code-active-line:before,\nbody.showEditorSelection li.code-line:hover:before {\n\tleft: -30px;\n}<\/p>\n<p>.vscode-light.showEditorSelection .code-active-line:before {\n\tborder-left: 3px solid rgba(0, 0, 0, 0.15);\n}<\/p>\n<p>.vscode-light.showEditorSelection .code-line:hover:before {\n\tborder-left: 3px solid rgba(0, 0, 0, 0.40);\n}<\/p>\n<p>.vscode-light.showEditorSelection .code-line .code-line:hover:before {\n\tborder-left: none;\n}<\/p>\n<p>.vscode-dark.showEditorSelection .code-active-line:before {\n\tborder-left: 3px solid rgba(255, 255, 255, 0.4);\n}<\/p>\n<p>.vscode-dark.showEditorSelection .code-line:hover:before {\n\tborder-left: 3px solid rgba(255, 255, 255, 0.60);\n}<\/p>\n<p>.vscode-dark.showEditorSelection .code-line .code-line:hover:before {\n\tborder-left: none;\n}<\/p>\n<p>.vscode-high-contrast.showEditorSelection .code-active-line:before {\n\tborder-left: 3px solid rgba(255, 160, 0, 0.7);\n}<\/p>\n<p>.vscode-high-contrast.showEditorSelection .code-line:hover:before {\n\tborder-left: 3px solid rgba(255, 160, 0, 1);\n}<\/p>\n<p>.vscode-high-contrast.showEditorSelection .code-line .code-line:hover:before {\n\tborder-left: none;\n}<\/p>\n<p>img {\n\tmax-width: 100%;\n\tmax-height: 100%;\n}<\/p>\n<p>a {\n\ttext-decoration: none;\n}<\/p>\n<p>a:hover {\n\ttext-decoration: underline;\n}<\/p>\n<p>a:focus,\ninput:focus,\nselect:focus,\ntextarea:focus {\n\toutline: 1px solid -webkit-focus-ring-color;\n\toutline-offset: -1px;\n}<\/p>\n<p>hr {\n\tborder: 0;\n\theight: 2px;\n\tborder-bottom: 2px solid;\n}<\/p>\n<p>h1 {\n\tpadding-bottom: 0.3em;\n\tline-height: 1.2;\n\tborder-bottom-width: 1px;\n\tborder-bottom-style: solid;\n}<\/p>\n<p>h1, h2, h3 {\n\tfont-weight: normal;\n}<\/p>\n<p>table {\n\tborder-collapse: collapse;\n}<\/p>\n<p>table > thead > tr > th {\n\ttext-align: left;\n\tborder-bottom: 1px solid;\n}<\/p>\n<p>table > thead > tr > th,\ntable > thead > tr > td,\ntable > tbody > tr > th,\ntable > tbody > tr > td {\n\tpadding: 5px 10px;\n}<\/p>\n<p>table > tbody > tr + tr > td {\n\tborder-top: 1px solid;\n}<\/p>\n<p>blockquote {\n\tmargin: 0 7px 0 5px;\n\tpadding: 0 16px 0 10px;\n\tborder-left-width: 5px;\n\tborder-left-style: solid;\n}<\/p>\n<p>code {\n\tfont-family: Menlo, Monaco, Consolas, \"Droid Sans Mono\", \"Courier New\", monospace, \"Droid Sans Fallback\";\n\tfont-size: 1em;\n\tline-height: 1.357em;\n}<\/p>\n<p>body.wordWrap pre {\n\twhite-space: pre-wrap;\n}<\/p>\n<p>pre:not(.hljs),\npre.hljs code > div {\n\tpadding: 16px;\n\tborder-radius: 3px;\n\toverflow: auto;\n}<\/p>\n<p>pre code {\n\tcolor: var(--vscode-editor-foreground);\n\ttab-size: 4;\n}<\/p>\n<p>\/** Theming *\/<\/p>\n<p>.vscode-light pre {\n\tbackground-color: rgba(220, 220, 220, 0.4);\n}<\/p>\n<p>.vscode-dark pre {\n\tbackground-color: rgba(10, 10, 10, 0.4);\n}<\/p>\n<p>.vscode-high-contrast pre {\n\tbackground-color: rgb(0, 0, 0);\n}<\/p>\n<p>.vscode-high-contrast h1 {\n\tborder-color: rgb(0, 0, 0);\n}<\/p>\n<p>.vscode-light table > thead > tr > th {\n\tborder-color: rgba(0, 0, 0, 0.69);\n}<\/p>\n<p>.vscode-dark table > thead > tr > th {\n\tborder-color: rgba(255, 255, 255, 0.69);\n}<\/p>\n<p>.vscode-light h1,\n.vscode-light hr,\n.vscode-light table > tbody > tr + tr > td {\n\tborder-color: rgba(0, 0, 0, 0.18);\n}<\/p>\n<p>.vscode-dark h1,\n.vscode-dark hr,\n.vscode-dark table > tbody > tr + tr > td {\n\tborder-color: rgba(255, 255, 255, 0.18);\n}<\/p>\n<\/style>\n<style>\n\/* Tomorrow Theme *\/\n\/* http:\/\/jmblog.github.com\/color-themes-for-google-code-highlightjs *\/\n\/* Original theme - https:\/\/github.com\/chriskempson\/tomorrow-theme *\/<\/p>\n<p>\/* Tomorrow Comment *\/\n.hljs-comment,\n.hljs-quote {\n\tcolor: #8e908c;\n}<\/p>\n<p>\/* Tomorrow Red *\/\n.hljs-variable,\n.hljs-template-variable,\n.hljs-tag,\n.hljs-name,\n.hljs-selector-id,\n.hljs-selector-class,\n.hljs-regexp,\n.hljs-deletion {\n\tcolor: #c82829;\n}<\/p>\n<p>\/* Tomorrow Orange *\/\n.hljs-number,\n.hljs-built_in,\n.hljs-builtin-name,\n.hljs-literal,\n.hljs-type,\n.hljs-params,\n.hljs-meta,\n.hljs-link {\n\tcolor: #f5871f;\n}<\/p>\n<p>\/* Tomorrow Yellow *\/\n.hljs-attribute {\n\tcolor: #eab700;\n}<\/p>\n<p>\/* Tomorrow Green *\/\n.hljs-string,\n.hljs-symbol,\n.hljs-bullet,\n.hljs-addition {\n\tcolor: #718c00;\n}<\/p>\n<p>\/* Tomorrow Blue *\/\n.hljs-title,\n.hljs-section {\n\tcolor: #4271ae;\n}<\/p>\n<p>\/* Tomorrow Purple *\/\n.hljs-keyword,\n.hljs-selector-tag {\n\tcolor: #8959a8;\n}<\/p>\n<p>.hljs {\n\tdisplay: block;\n\toverflow-x: auto;\n\tcolor: #4d4d4c;\n\tpadding: 0.5em;\n}<\/p>\n<p>.hljs-emphasis {\n\tfont-style: italic;\n}<\/p>\n<p>.hljs-strong {\n\tfont-weight: bold;\n}\n<\/style>\n<style>\n\/*\n * Markdown PDF CSS\n *\/<\/p>\n<p> body {\n\tfont-family: -apple-system, BlinkMacSystemFont, \"Segoe WPC\", \"Segoe UI\", \"Ubuntu\", \"Droid Sans\", sans-serif, \"Meiryo\";\n\tpadding: 0 12px;\n}<\/p>\n<p>pre {\n\tbackground-color: #f8f8f8;\n\tborder: 1px solid #cccccc;\n\tborder-radius: 3px;\n\toverflow-x: auto;\n\twhite-space: pre-wrap;\n\toverflow-wrap: break-word;\n}<\/p>\n<p>pre:not(.hljs) {\n\tpadding: 23px;\n\tline-height: 19px;\n}<\/p>\n<p>blockquote {\n\tbackground: rgba(127, 127, 127, 0.1);\n\tborder-color: rgba(0, 122, 204, 0.5);\n}<\/p>\n<p>.emoji {\n\theight: 1.4em;\n}<\/p>\n<p>code {\n\tfont-size: 14px;\n\tline-height: 19px;\n}<\/p>\n<p>\/* for inline code *\/\n:not(pre):not(.hljs) > code {\n\tcolor: #C9AE75; \/* Change the old color so it seems less like an error *\/\n\tfont-size: inherit;\n}<\/p>\n<p>\/* Page Break : use <\/p>\n<div class=\"page\"\/> to insert page break\n-------------------------------------------------------- *\/\n.page {\n\tpage-break-after: always;\n}<\/p>\n<\/style>\n<p><script src=\"https:\/\/unpkg.com\/mermaid\/dist\/mermaid.min.js\"><\/script><br \/>\n<\/head><br \/>\n<body><br \/>\n  <script>\n    mermaid.initialize({\n      startOnLoad: true,\n      theme: document.body.classList.contains('vscode-dark') || document.body.classList.contains('vscode-high-contrast')\n          ? 'dark'\n          : 'default'\n    });\n  <\/script><\/p>\n<h1 id=\"html-%E6%BC%94%E7%A4%BA%E6%96%87%E7%A8%BF%E9%85%8D%E7%BD%AE%E6%89%8B%E5%86%8C%E4%BB%8E%E6%8E%A7%E4%BB%B6%E5%88%B0%E7%BC%A9%E6%94%BE\">HTML \u6f14\u793a\u6587\u7a3f\u914d\u7f6e\u624b\u518c\u2014\u2014\u4ece\u63a7\u4ef6\u5230\u7f29\u653e<\/h1>\n<blockquote>\n<p>\u57fa\u4e8e opencode + deepseekv4 \u7684\u5b9e\u8df5\u603b\u7ed3\u3002\u9002\u7528\u4e8e\u7528 AI Agent \u751f\u6210 HTML \u6f14\u793a\u6587\u7a3f\u65f6\u7684\u63a7\u4ef6\u3001\u7f29\u653e\u3001\u5b57\u4f53\u7b49\u914d\u7f6e\u3002<\/p>\n<\/blockquote>\n<hr>\n<h2 id=\"%E4%B8%80canvas-%E5%B0%BA%E5%AF%B8\">\u4e00\u3001Canvas \u5c3a\u5bf8<\/h2>\n<p><strong>\u63a8\u8350\u5c3a\u5bf8\uff1a1200 \u00d7 675\uff0816:9 \u5bbd\u5c4f\u6bd4\u4f8b\uff09<\/strong><\/p>\n<p>\u8fd9\u4e2a\u6bd4\u4f8b\u9002\u914d\u5927\u591a\u6570\u5c4f\u5e55\uff0816:9 \u6295\u5f71\u3001\u7b14\u8bb0\u672c\uff09\uff0c\u4e5f\u662f PPT \u7684\u6807\u51c6\u6bd4\u4f8b\u3002\u6240\u6709\u540e\u7eed\u5e03\u5c40\u4ee5\u6b64\u4e3a\u57fa\u7840\u3002<\/p>\n<pre class=\"hljs\"><code><div>+--{ canvas-wrapper: \u5168\u5c4f\u80cc\u666f }--+\n|  +--{ canvas-center: 1200px }--+  \u2190 \u56fa\u5b9a\u5bbd\u5ea6\u5bb9\u5668\n|  |  +- presentation-container -+  |  \u2190 transform \u4f5c\u7528\u57df\uff081200\u00d7675\uff09\n|  |  |  slides                |  |\n|  |  +------------------------+  |\n|  |  controls-bar                |\n|  +------------------------------+\n+---------------------------------+\n<\/div><\/code><\/pre>\n<hr>\n<h2 id=\"%E4%BA%8Chtml-%E5%B1%82%E7%BA%A7%E7%BB%93%E6%9E%84%E5%BF%85%E8%AE%B0\">\u4e8c\u3001HTML \u5c42\u7ea7\u7ed3\u6784\uff08\u5fc5\u8bb0\uff09<\/h2>\n<pre class=\"hljs\"><code><div><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">body<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"canvas-wrapper\"<\/span> <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"canvasWrapper\"<\/span>&gt;<\/span>   <span class=\"hljs-comment\">&lt;!-- \u5168\u5c4f\u80cc\u666f\uff0cpadding 40px --&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"canvas-center\"<\/span>&gt;<\/span>                    <span class=\"hljs-comment\">&lt;!-- \u56fa\u5b9a 1200px\uff0c\u65e0 padding --&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"presentation-container\"<\/span>&gt;<\/span>       <span class=\"hljs-comment\">&lt;!-- transform: scale() \u4f5c\u7528\u57df --&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"slide-viewport\"<\/span>&gt;<\/span>           <span class=\"hljs-comment\">&lt;!-- overflow: hidden --&gt;<\/span>\n                <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"slide\"<\/span>&gt;<\/span>...<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>       <span class=\"hljs-comment\">&lt;!-- \u6bcf\u9875\u5e7b\u706f\u7247 --&gt;<\/span>\n                ...\n            <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"controls-bar\"<\/span>&gt;<\/span>             <span class=\"hljs-comment\">&lt;!-- \u5de5\u5177\u680f\u6309\u94ae --&gt;<\/span>\n                ...\n            <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">body<\/span>&gt;<\/span>\n<\/div><\/code><\/pre>\n<h3 id=\"%E5%B1%82%E7%BA%A7%E8%AF%B4%E6%98%8E\">\u5c42\u7ea7\u8bf4\u660e<\/h3>\n<table>\n<thead>\n<tr>\n<th>\u5c42\u7ea7<\/th>\n<th>\u4f5c\u7528<\/th>\n<th>\u5173\u952e\u5c5e\u6027<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>canvas-wrapper<\/td>\n<td>\u5168\u5c4f\u80cc\u666f\uff0cpadding 40px \u63d0\u4f9b\u89c6\u89c9\u6846\u67b6<\/td>\n<td><code>padding: 40px<\/code>, <code>overflow: auto<\/code><\/td>\n<\/tr>\n<tr>\n<td>canvas-center<\/td>\n<td>\u56fa\u5b9a\u5bbd\u5ea6\u5bb9\u5668\uff0c\u4fdd\u6301 presContainer \u5bbd\u5ea6\u7edf\u4e00<\/td>\n<td><code>width: 1200px<\/code>, <code>padding: 0<\/code><\/td>\n<\/tr>\n<tr>\n<td>presentation-container<\/td>\n<td>transform \u7f29\u653e\u7684\u76ee\u6807\u5143\u7d20<\/td>\n<td><code>width: 100%<\/code>, <code>height: 675px<\/code><\/td>\n<\/tr>\n<tr>\n<td>slide-viewport<\/td>\n<td>\u88c1\u526a\u533a\u57df\uff0c\u81ea\u9002\u5e94\u6a21\u578b\u4e0b\u65e0\u6eda\u52a8<\/td>\n<td><code>overflow: hidden<\/code><\/td>\n<\/tr>\n<tr>\n<td>controls-bar<\/td>\n<td>\u6309\u94ae\u5de5\u5177\u680f\uff0c\u5fc5\u987b\u5728\u6b64\u4f4d\u7f6e<\/td>\n<td><code>flex-shrink: 0<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<hr>\n<h2 id=\"%E4%B8%89%E8%87%AA%E9%80%82%E5%BA%94%E7%BC%A9%E6%94%BE%E6%A8%A1%E5%9E%8B%E6%8E%A8%E8%8D%90\">\u4e09\u3001\u81ea\u9002\u5e94\u7f29\u653e\u6a21\u578b\uff08\u63a8\u8350\uff09<\/h2>\n<h3 id=\"%E6%A0%B8%E5%BF%83%E6%A6%82%E5%BF%B5\">\u6838\u5fc3\u6982\u5ff5<\/h3>\n<p>Canvas\uff081200\u00d7675\uff09\u662f\u8bbe\u8ba1\u57fa\u51c6\uff0c\u901a\u8fc7 <code>transform: scale()<\/code> \u81ea\u9002\u5e94\u586b\u5145\u89c6\u7a97\uff0c<strong>\u65e0\u6eda\u52a8\u6761<\/strong>\u3002<\/p>\n<p>\u4e0e\u5730\u56fe\u6a21\u578b\u7684\u533a\u522b\uff1a<\/p>\n<table>\n<thead>\n<tr>\n<th>\u6a21\u578b<\/th>\n<th>\u884c\u4e3a<\/th>\n<th>\u9002\u7528\u573a\u666f<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><strong>\u5730\u56fe\u6a21\u578b<\/strong><\/td>\n<td>Canvas \u56fa\u5b9a\u5c3a\u5bf8\uff0c\u89c6\u7a97\u88c1\u526a\uff0c\u6eda\u52a8\u6d4f\u89c8<\/td>\n<td>\u5927\u753b\u5e03\u3001\u7cbe\u7ec6\u5185\u5bb9<\/td>\n<\/tr>\n<tr>\n<td><strong>\u81ea\u9002\u5e94\u6a21\u578b\uff08\u63a8\u8350\uff09<\/strong><\/td>\n<td>Canvas \u7f29\u653e\u5230\u89c6\u7a97\u5185\uff0c\u59cb\u7ec8\u5b8c\u5168\u53ef\u89c1<\/td>\n<td>\u6f14\u793a\u6587\u7a3f\u3001PPT<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><strong>\u4e24\u8005\u4e92\u65a5\uff0c\u4e0d\u53ef\u6df7\u5408\u4f7f\u7528\u3002<\/strong><\/p>\n<h3 id=\"css-%E5%B8%83%E5%B1%80\">CSS \u5e03\u5c40<\/h3>\n<pre class=\"hljs\"><code><div><span class=\"hljs-selector-class\">.canvas-wrapper<\/span> {\n    <span class=\"hljs-attribute\">width<\/span>: <span class=\"hljs-number\">100%<\/span>;\n    <span class=\"hljs-attribute\">min-width<\/span>: <span class=\"hljs-number\">100vw<\/span>;\n    <span class=\"hljs-attribute\">height<\/span>: <span class=\"hljs-number\">100vh<\/span>;\n    <span class=\"hljs-attribute\">overflow<\/span>: auto;\n    <span class=\"hljs-attribute\">background<\/span>: <span class=\"hljs-built_in\">var<\/span>(--bg);\n    <span class=\"hljs-attribute\">display<\/span>: flex;\n    <span class=\"hljs-attribute\">flex-direction<\/span>: column;\n    <span class=\"hljs-attribute\">align-items<\/span>: center;\n    <span class=\"hljs-attribute\">padding<\/span>: <span class=\"hljs-number\">40px<\/span>;\n}\n<span class=\"hljs-selector-class\">.canvas-center<\/span> {\n    <span class=\"hljs-attribute\">width<\/span>: <span class=\"hljs-number\">1200px<\/span>;\n    <span class=\"hljs-attribute\">flex-shrink<\/span>: <span class=\"hljs-number\">0<\/span>;\n    <span class=\"hljs-attribute\">padding<\/span>: <span class=\"hljs-number\">0<\/span>;\n}\n<span class=\"hljs-selector-class\">.presentation-container<\/span> {\n    <span class=\"hljs-attribute\">width<\/span>: <span class=\"hljs-number\">100%<\/span>;\n    <span class=\"hljs-attribute\">height<\/span>: <span class=\"hljs-number\">675px<\/span>;\n    <span class=\"hljs-attribute\">background<\/span>: <span class=\"hljs-built_in\">var<\/span>(--slide-bg);\n    <span class=\"hljs-attribute\">box-shadow<\/span>: <span class=\"hljs-built_in\">var<\/span>(--shadow-lg);\n    <span class=\"hljs-attribute\">overflow<\/span>: hidden;\n    <span class=\"hljs-attribute\">display<\/span>: flex;\n    <span class=\"hljs-attribute\">flex-direction<\/span>: column;\n}\n<span class=\"hljs-selector-class\">.slide-viewport<\/span> {\n    <span class=\"hljs-attribute\">flex<\/span>: <span class=\"hljs-number\">1<\/span>;\n    <span class=\"hljs-attribute\">position<\/span>: relative;\n    <span class=\"hljs-attribute\">overflow<\/span>: hidden;\n}\n<\/div><\/code><\/pre>\n<h3 id=\"%E5%AE%8C%E6%95%B4-js-%E7%BC%A9%E6%94%BE%E9%80%BB%E8%BE%91\">\u5b8c\u6574 JS \u7f29\u653e\u903b\u8f91<\/h3>\n<pre class=\"hljs\"><code><div><span class=\"hljs-keyword\">const<\/span> CANVAS_WIDTH = <span class=\"hljs-number\">1200<\/span>;\n<span class=\"hljs-keyword\">const<\/span> CANVAS_HEIGHT = <span class=\"hljs-number\">675<\/span>;\n<span class=\"hljs-keyword\">let<\/span> wasInFullscreen = <span class=\"hljs-literal\">false<\/span>;\n\n<span class=\"hljs-comment\">\/\/ \u81ea\u52a8\u7f29\u653e\uff1a\u7a97\u53e3\u5c0f\u4e8e Canvas \u65f6\u7f29\u5c0f\u9002\u914d<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">updateAutoScale<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n    <span class=\"hljs-keyword\">const<\/span> isFS = !!(<span class=\"hljs-built_in\">document<\/span>.fullscreenElement || <span class=\"hljs-built_in\">document<\/span>.webkitFullscreenElement);\n    <span class=\"hljs-keyword\">if<\/span> (isFS) {\n        <span class=\"hljs-comment\">\/\/ \u5168\u5c4f\u65f6\u4e0d\u5e72\u6270\uff0c\u7531 updateFullscreenUI \u7ba1\u7406<\/span>\n        presContainer.style.transform = <span class=\"hljs-string\">''<\/span>;\n        presContainer.style.transformOrigin = <span class=\"hljs-string\">''<\/span>;\n        presContainer.style.width = <span class=\"hljs-string\">''<\/span>;\n        presContainer.style.height = <span class=\"hljs-string\">''<\/span>;\n        <span class=\"hljs-keyword\">return<\/span>;\n    }\n    <span class=\"hljs-keyword\">const<\/span> screenW = <span class=\"hljs-built_in\">window<\/span>.innerWidth;\n    <span class=\"hljs-keyword\">const<\/span> screenH = <span class=\"hljs-built_in\">window<\/span>.innerHeight;\n    <span class=\"hljs-keyword\">const<\/span> scaleX = screenW \/ CANVAS_WIDTH;\n    <span class=\"hljs-keyword\">const<\/span> scaleY = screenH \/ CANVAS_HEIGHT;\n    <span class=\"hljs-keyword\">const<\/span> fitScale = <span class=\"hljs-built_in\">Math<\/span>.min(scaleX, scaleY, <span class=\"hljs-number\">1.0<\/span>);\n\n    <span class=\"hljs-keyword\">if<\/span> (fitScale &lt; <span class=\"hljs-number\">1.0<\/span>) {\n        presContainer.style.transform = <span class=\"hljs-string\">`scale(<span class=\"hljs-subst\">${fitScale}<\/span>)`<\/span>;\n        presContainer.style.transformOrigin = <span class=\"hljs-string\">'center center'<\/span>;\n        presContainer.style.width = CANVAS_WIDTH + <span class=\"hljs-string\">'px'<\/span>;\n        presContainer.style.height = CANVAS_HEIGHT + <span class=\"hljs-string\">'px'<\/span>;\n    } <span class=\"hljs-keyword\">else<\/span> {\n        presContainer.style.transform = <span class=\"hljs-string\">''<\/span>;\n        presContainer.style.transformOrigin = <span class=\"hljs-string\">''<\/span>;\n        presContainer.style.width = <span class=\"hljs-string\">''<\/span>;\n        presContainer.style.height = <span class=\"hljs-string\">''<\/span>;\n    }\n}\n\n<span class=\"hljs-comment\">\/\/ \u5168\u5c4f\u7f29\u653e\uff1a\u586b\u6ee1\u5c4f\u5e55<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">updateFullscreenUI<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n    <span class=\"hljs-keyword\">const<\/span> isFS = !!(<span class=\"hljs-built_in\">document<\/span>.fullscreenElement || <span class=\"hljs-built_in\">document<\/span>.webkitFullscreenElement);\n    btnFullscreen.style.display = isFS ? <span class=\"hljs-string\">'none'<\/span> : <span class=\"hljs-string\">''<\/span>;\n    btnExitFs.style.display = isFS ? <span class=\"hljs-string\">''<\/span> : <span class=\"hljs-string\">'none'<\/span>;\n\n    <span class=\"hljs-keyword\">if<\/span> (isFS) {\n        <span class=\"hljs-built_in\">document<\/span>.body.classList.add(<span class=\"hljs-string\">'fullscreen-mode'<\/span>);\n        <span class=\"hljs-keyword\">const<\/span> screenW = <span class=\"hljs-built_in\">window<\/span>.innerWidth;\n        <span class=\"hljs-keyword\">const<\/span> screenH = <span class=\"hljs-built_in\">window<\/span>.innerHeight;\n        <span class=\"hljs-keyword\">const<\/span> scaleX = screenW \/ CANVAS_WIDTH;\n        <span class=\"hljs-keyword\">const<\/span> scaleY = screenH \/ CANVAS_HEIGHT;\n        <span class=\"hljs-keyword\">const<\/span> scale = <span class=\"hljs-built_in\">Math<\/span>.min(scaleX, scaleY);\n        presContainer.style.transformOrigin = <span class=\"hljs-string\">'center center'<\/span>;\n        presContainer.style.transform = <span class=\"hljs-string\">`scale(<span class=\"hljs-subst\">${scale}<\/span>)`<\/span>;\n        wasInFullscreen = <span class=\"hljs-literal\">true<\/span>;\n    } <span class=\"hljs-keyword\">else<\/span> <span class=\"hljs-keyword\">if<\/span> (wasInFullscreen) {\n        <span class=\"hljs-built_in\">document<\/span>.body.classList.remove(<span class=\"hljs-string\">'fullscreen-mode'<\/span>);\n        presContainer.style.transform = <span class=\"hljs-string\">''<\/span>;\n        presContainer.style.transformOrigin = <span class=\"hljs-string\">''<\/span>;\n        wasInFullscreen = <span class=\"hljs-literal\">false<\/span>;\n    }\n}\n\n<span class=\"hljs-built_in\">window<\/span>.addEventListener(<span class=\"hljs-string\">'resize'<\/span>, () =&gt; {\n    updateAutoScale();\n    updateFullscreenUI();\n});\n<\/div><\/code><\/pre>\n<h3 id=\"%E5%85%A8%E5%B1%8F-css\">\u5168\u5c4f CSS<\/h3>\n<pre class=\"hljs\"><code><div><span class=\"hljs-selector-tag\">body<\/span><span class=\"hljs-selector-class\">.fullscreen-mode<\/span> <span class=\"hljs-selector-class\">.canvas-wrapper<\/span> {\n    <span class=\"hljs-attribute\">display<\/span>: flex;\n    <span class=\"hljs-attribute\">align-items<\/span>: center;\n    <span class=\"hljs-attribute\">justify-content<\/span>: center;\n    <span class=\"hljs-attribute\">overflow<\/span>: hidden;\n    <span class=\"hljs-attribute\">padding<\/span>: <span class=\"hljs-number\">0<\/span>;\n}\n<span class=\"hljs-selector-tag\">body<\/span><span class=\"hljs-selector-class\">.fullscreen-mode<\/span> <span class=\"hljs-selector-class\">.slide-viewport<\/span> {\n    <span class=\"hljs-attribute\">overflow<\/span>: hidden;\n}\n<span class=\"hljs-selector-tag\">body<\/span><span class=\"hljs-selector-class\">.fullscreen-mode<\/span> <span class=\"hljs-selector-class\">.canvas-center<\/span> {\n    <span class=\"hljs-attribute\">padding<\/span>: <span class=\"hljs-number\">0<\/span>;\n}\n<span class=\"hljs-selector-tag\">body<\/span><span class=\"hljs-selector-class\">.fullscreen-mode<\/span> <span class=\"hljs-selector-class\">.presentation-container<\/span> {\n    <span class=\"hljs-attribute\">transform-origin<\/span>: center center;\n}\n<\/div><\/code><\/pre>\n<hr>\n<h2 id=\"%E5%9B%9B%E5%85%A8%E5%B1%8F%E9%80%BB%E8%BE%91%E4%B8%8E-wasinfullscreen-%E9%98%B2%E5%86%B2%E7%AA%81\">\u56db\u3001\u5168\u5c4f\u903b\u8f91\u4e0e wasInFullscreen \u9632\u51b2\u7a81<\/h2>\n<p><strong>\u6838\u5fc3\u95ee\u9898<\/strong>\uff1a\u5168\u5c4f\u9000\u51fa\u65f6\uff0cauto-scale \u4f1a\u68c0\u67e5\u7a97\u53e3\u5927\u5c0f\u5e76\u5c1d\u8bd5\u53e0\u52a0\u53e6\u4e00\u4e2a transform\uff0c\u5bfc\u81f4\u5e03\u5c40\u9519\u4e71\u3002<\/p>\n<p><strong>\u89e3\u51b3\u65b9\u6848<\/strong>\uff1a<code>wasInFullscreen<\/code> \u6807\u5fd7\u4f4d\u3002<\/p>\n<p>\u5168\u5c4f\u8fdb\u5165\u65f6 <code>wasInFullscreen = true<\/code>\uff0c\u9000\u51fa\u5168\u5c4f\u65f6\u624d\u6e05\u9664 transform\u3002auto-scale \u68c0\u6d4b\u5230\u5168\u5c4f\u72b6\u6001\u65f6\u76f4\u63a5 return\uff0c\u4e0d\u5e72\u6270\u5168\u5c4f\u7f29\u653e\u3002<\/p>\n<pre class=\"hljs\"><code><div><span class=\"hljs-keyword\">let<\/span> wasInFullscreen = <span class=\"hljs-literal\">false<\/span>;\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">updateFullscreenUI<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n    <span class=\"hljs-comment\">\/\/ ...<\/span>\n    <span class=\"hljs-keyword\">if<\/span> (isFS) {\n        presContainer.style.transform = <span class=\"hljs-string\">`scale(<span class=\"hljs-subst\">${scale}<\/span>)`<\/span>;\n        wasInFullscreen = <span class=\"hljs-literal\">true<\/span>;\n    } <span class=\"hljs-keyword\">else<\/span> <span class=\"hljs-keyword\">if<\/span> (wasInFullscreen) {\n        presContainer.style.transform = <span class=\"hljs-string\">''<\/span>;\n        wasInFullscreen = <span class=\"hljs-literal\">false<\/span>;\n    }\n}\n<\/div><\/code><\/pre>\n<hr>\n<h2 id=\"%E4%BA%94controls-bar-%E8%A7%84%E8%8C%83\">\u4e94\u3001controls-bar \u89c4\u8303<\/h2>\n<h3 id=\"%E4%BD%8D%E7%BD%AE%E5%85%B3%E9%94%AE\">\u4f4d\u7f6e\uff08\u5173\u952e\uff09<\/h3>\n<p>controls-bar <strong>\u5fc5\u987b<\/strong>\u4f4d\u4e8e <code>presentation-container<\/code> \u5185\u90e8\u3001<code>slide-viewport<\/code> \u5916\u90e8\u3002<\/p>\n<pre class=\"hljs\"><code><div><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"presentation-container\"<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"slide-viewport\"<\/span>&gt;<\/span>\n        <span class=\"hljs-comment\">&lt;!-- slides --&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"controls-bar\"<\/span>&gt;<\/span>   <span class=\"hljs-comment\">&lt;!-- \u2190 \u5728\u8fd9\u91cc --&gt;<\/span>\n        ...\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n<\/div><\/code><\/pre>\n<p>\u9519\u8bef\u4f4d\u7f6e\u4f1a\u5bfc\u81f4\uff1a<\/p>\n<ul>\n<li>\u5de5\u5177\u680f\u968f slide \u5207\u6362\u800c\u6d88\u5931<\/li>\n<li>\u5de5\u5177\u680f\u88ab\u88c1\u526a\u6216\u663e\u793a\u5f02\u5e38<\/li>\n<\/ul>\n<h3 id=\"%E6%8C%89%E9%92%AE%E9%A1%BA%E5%BA%8F\">\u6309\u94ae\u987a\u5e8f<\/h3>\n<pre class=\"hljs\"><code><div>\u2190 Prev  |  \u9875\u7801  |  \u2192 Next  |  \u5206\u5272\u7ebf  |  \u26f6 \u5168\u5c4f  |  \u2715 Exit FS\n<\/div><\/code><\/pre>\n<table>\n<thead>\n<tr>\n<th>\u6309\u94ae<\/th>\n<th>ID<\/th>\n<th>\u8bf4\u660e<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>\u4e0a\u4e00\u9875<\/td>\n<td><code>btnPrev<\/code><\/td>\n<td>\u6216 <code>\u2190 Prev<\/code><\/td>\n<\/tr>\n<tr>\n<td>\u9875\u7801<\/td>\n<td><code>slideIndicator<\/code><\/td>\n<td>\u683c\u5f0f &quot;3 \/ 15&quot;<\/td>\n<\/tr>\n<tr>\n<td>\u4e0b\u4e00\u9875<\/td>\n<td><code>btnNext<\/code><\/td>\n<td>\u6216 <code>Next \u2192<\/code><\/td>\n<\/tr>\n<tr>\n<td>\u5168\u5c4f<\/td>\n<td><code>btnFullscreen<\/code><\/td>\n<td>\u5168\u5c4f\u65f6\u9690\u85cf<\/td>\n<\/tr>\n<tr>\n<td>\u9000\u51fa\u5168\u5c4f<\/td>\n<td><code>btnExitFs<\/code><\/td>\n<td>\u4ec5\u5168\u5c4f\u65f6\u663e\u793a<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3 id=\"css\">CSS<\/h3>\n<pre class=\"hljs\"><code><div><span class=\"hljs-selector-class\">.controls-bar<\/span> {\n    <span class=\"hljs-attribute\">display<\/span>: flex;\n    <span class=\"hljs-attribute\">align-items<\/span>: center;\n    <span class=\"hljs-attribute\">justify-content<\/span>: center;\n    <span class=\"hljs-attribute\">gap<\/span>: <span class=\"hljs-number\">12px<\/span>;\n    <span class=\"hljs-attribute\">padding<\/span>: <span class=\"hljs-number\">10px<\/span> <span class=\"hljs-number\">20px<\/span>;\n    <span class=\"hljs-attribute\">background<\/span>: <span class=\"hljs-number\">#e8e4dc<\/span>;\n    <span class=\"hljs-attribute\">border-top<\/span>: <span class=\"hljs-number\">1px<\/span> solid <span class=\"hljs-built_in\">var<\/span>(--border);\n    <span class=\"hljs-attribute\">flex-shrink<\/span>: <span class=\"hljs-number\">0<\/span>;\n}\n<span class=\"hljs-selector-class\">.controls-bar<\/span> <span class=\"hljs-selector-tag\">button<\/span> {\n    <span class=\"hljs-attribute\">font-size<\/span>: <span class=\"hljs-number\">14px<\/span>;\n    <span class=\"hljs-attribute\">padding<\/span>: <span class=\"hljs-number\">8px<\/span> <span class=\"hljs-number\">16px<\/span>;\n    <span class=\"hljs-attribute\">border<\/span>: <span class=\"hljs-number\">1.5px<\/span> solid <span class=\"hljs-built_in\">var<\/span>(--primary);\n    <span class=\"hljs-attribute\">background<\/span>: <span class=\"hljs-number\">#fff<\/span>;\n    <span class=\"hljs-attribute\">color<\/span>: <span class=\"hljs-built_in\">var<\/span>(--primary);\n    <span class=\"hljs-attribute\">border-radius<\/span>: <span class=\"hljs-number\">5px<\/span>;\n    <span class=\"hljs-attribute\">cursor<\/span>: pointer;\n    <span class=\"hljs-attribute\">font-weight<\/span>: <span class=\"hljs-number\">600<\/span>;\n}\n<\/div><\/code><\/pre>\n<h3 id=\"%E9%94%AE%E7%9B%98%E5%BF%AB%E6%8D%B7%E9%94%AE\">\u952e\u76d8\u5feb\u6377\u952e<\/h3>\n<pre class=\"hljs\"><code><div><span class=\"hljs-built_in\">document<\/span>.addEventListener(<span class=\"hljs-string\">'keydown'<\/span>, (e) =&gt; {\n    <span class=\"hljs-keyword\">if<\/span> (e.key === <span class=\"hljs-string\">'ArrowLeft'<\/span> || e.key === <span class=\"hljs-string\">'ArrowUp'<\/span> || e.key === <span class=\"hljs-string\">'PageUp'<\/span>) {\n        e.preventDefault(); showSlide(currentIndex - <span class=\"hljs-number\">1<\/span>);\n    }\n    <span class=\"hljs-keyword\">else<\/span> <span class=\"hljs-keyword\">if<\/span> (e.key === <span class=\"hljs-string\">'ArrowRight'<\/span> || e.key === <span class=\"hljs-string\">'ArrowDown'<\/span> || e.key === <span class=\"hljs-string\">' '<\/span> || e.key === <span class=\"hljs-string\">'PageDown'<\/span>) {\n        e.preventDefault(); showSlide(currentIndex + <span class=\"hljs-number\">1<\/span>);\n    }\n    <span class=\"hljs-keyword\">else<\/span> <span class=\"hljs-keyword\">if<\/span> (e.key === <span class=\"hljs-string\">'Home'<\/span>) { e.preventDefault(); showSlide(<span class=\"hljs-number\">0<\/span>); }\n    <span class=\"hljs-keyword\">else<\/span> <span class=\"hljs-keyword\">if<\/span> (e.key === <span class=\"hljs-string\">'End'<\/span>) { e.preventDefault(); showSlide(totalSlides - <span class=\"hljs-number\">1<\/span>); }\n    <span class=\"hljs-keyword\">else<\/span> <span class=\"hljs-keyword\">if<\/span> (e.key === <span class=\"hljs-string\">'f'<\/span> || e.key === <span class=\"hljs-string\">'F'<\/span>) { e.preventDefault(); toggleFullscreen(); }\n});\n<\/div><\/code><\/pre>\n<p>\u652f\u6301\u7ffb\u9875\u7b14\u7684 PageUp\/PageDown \u952e\u6620\u5c04\u3002<\/p>\n<hr>\n<h2 id=\"%E5%85%ADreference-%E9%A1%B5%E9%9D%A2prescontainer-%E5%AE%BD%E5%BA%A6%E4%B8%80%E8%87%B4%E6%80%A7\">\u516d\u3001Reference \u9875\u9762\uff1apresContainer \u5bbd\u5ea6\u4e00\u81f4\u6027<\/h2>\n<h3 id=\"%E9%97%AE%E9%A2%98\">\u95ee\u9898<\/h3>\n<p>\u5168\u5c4f\u524d\u540e\u3001\u6d4f\u89c8\u5668 zoom\u3001\u7a97\u53e3 resize \u90fd\u4f1a\u4f7f Reference \u9875\u7684\u53ef\u89c1\u6761\u76ee\u6570\u91cf\u53d8\u5316\uff0814\u219216 \u6761\uff09\u3002<\/p>\n<h3 id=\"%E6%A0%B9%E5%9B%A0%E5%88%86%E6%9E%90\">\u6839\u56e0\u5206\u6790<\/h3>\n<p>\u4e0d\u540c\u6a21\u5f0f\u4e0b <code>presContainer<\/code> \u5bbd\u5ea6\u4e0d\u4e00\u81f4\uff1a<\/p>\n<table>\n<thead>\n<tr>\n<th>\u6a21\u5f0f<\/th>\n<th style=\"text-align:center\">\u5bbd\u5ea6<\/th>\n<th style=\"text-align:center\">\u6587\u672c\u5bbd\u5ea6<\/th>\n<th style=\"text-align:center\">\u884c\u6570\uff0818\u6761\uff09<\/th>\n<th style=\"text-align:center\">\u6548\u679c<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>\u666e\u901a\u6a21\u5f0f\uff08\u6709 padding\uff09<\/td>\n<td style=\"text-align:center\">1120px<\/td>\n<td style=\"text-align:center\">1048px<\/td>\n<td style=\"text-align:center\">~38\u884c<\/td>\n<td style=\"text-align:center\">\u88c1\u526a2-4\u6761<\/td>\n<\/tr>\n<tr>\n<td>auto-scale \/ \u5168\u5c4f<\/td>\n<td style=\"text-align:center\">1200px<\/td>\n<td style=\"text-align:center\">1128px<\/td>\n<td style=\"text-align:center\">~30\u884c<\/td>\n<td style=\"text-align:center\">\u5168\u663e\u793a<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><strong>80px \u5bbd\u5ea6\u5dee \u2192 \u6539\u53d8\u6587\u672c\u6362\u884c \u2192 ~138px \u884c\u9ad8\u5dee\u5f02 \u2192 4 \u6761\u53d8\u5316\u3002<\/strong><\/p>\n<p>\u4e0d\u662f\u5b50\u50cf\u7d20\u56db\u820d\u4e94\u5165\uff08\u00b113px \u53ea\u80fd\u89e3\u91ca 0-1 \u6761\uff09\u3002<\/p>\n<h3 id=\"%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88\">\u89e3\u51b3\u65b9\u6848<\/h3>\n<p><strong>\u6240\u6709\u6a21\u5f0f\u4e0b presContainer \u5bbd\u5ea6\u7edf\u4e00\u4e3a 1200px\u3002<\/strong><\/p>\n<ul>\n<li>\u6b63\u5e38\u6a21\u5f0f\uff1acanvas-wrapper <code>padding: 40px<\/code>\uff0ccanvas-center <code>width: 1200px; padding: 0<\/code> \u2192 presContainer <code>100% = 1200px<\/code><\/li>\n<li>Auto-scale\uff1aJS \u8bbe\u7f6e <code>presContainer.style.width = 1200px<\/code><\/li>\n<li>\u5168\u5c4f\uff1acanvas-center <code>padding: 0<\/code>\uff0cpresContainer <code>100% = 1200px<\/code><\/li>\n<\/ul>\n<h3 id=\"reference-%E9%A1%B5-css\">Reference \u9875 CSS<\/h3>\n<pre class=\"hljs\"><code><div><span class=\"hljs-selector-class\">.slide-body<\/span><span class=\"hljs-selector-class\">.ref-slide<\/span> { <span class=\"hljs-attribute\">gap<\/span>: <span class=\"hljs-number\">0<\/span>; <span class=\"hljs-attribute\">font-family<\/span>: <span class=\"hljs-string\">'Georgia'<\/span>, <span class=\"hljs-string\">'Times New Roman'<\/span>, serif; }\n<span class=\"hljs-selector-class\">.slide-body<\/span><span class=\"hljs-selector-class\">.ref-slide<\/span> <span class=\"hljs-selector-tag\">p<\/span> { <span class=\"hljs-attribute\">font-size<\/span>: <span class=\"hljs-number\">15px<\/span>; <span class=\"hljs-attribute\">line-height<\/span>: <span class=\"hljs-number\">1.15<\/span>; <span class=\"hljs-attribute\">margin<\/span>: <span class=\"hljs-number\">0<\/span>; }\n<span class=\"hljs-selector-class\">.slide-body<\/span><span class=\"hljs-selector-class\">.ref-slide<\/span> <span class=\"hljs-selector-class\">.ref-item<\/span> { <span class=\"hljs-attribute\">margin-bottom<\/span>: <span class=\"hljs-number\">2px<\/span>; }\n<\/div><\/code><\/pre>\n<hr>\n<h2 id=\"%E4%B8%83zoom-%E7%A6%81%E7%94%A8\">\u4e03\u3001Zoom \u7981\u7528<\/h2>\n<p>\u81ea\u9002\u5e94\u6a21\u578b\u4e0e\u6d4f\u89c8\u5668 zoom\uff08Ctrl+\u6eda\u8f6e\u3001\u53cc\u6307\u7f29\u653e\uff09\u4e92\u65a5\u3002auto-scale \u4e0d\u65ad\u62b5\u6d88 zoom\uff0c\u4f53\u9a8c\u6781\u5dee\u3002<\/p>\n<p><strong>\u5fc5\u987b\u5f7b\u5e95\u7981\u7528 zoom\u3002<\/strong><\/p>\n<h3 id=\"%E6%96%B9%E6%B3%95%E4%B8%80meta-viewport\">\u65b9\u6cd5\u4e00\uff1ameta viewport<\/h3>\n<pre class=\"hljs\"><code><div><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">meta<\/span> <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">\"viewport\"<\/span> <span class=\"hljs-attr\">content<\/span>=<span class=\"hljs-string\">\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no\"<\/span>&gt;<\/span>\n<\/div><\/code><\/pre>\n<p>\u963b\u6b62\u79fb\u52a8\u7aef\u53cc\u6307\u7f29\u653e\u548c\u6d4f\u89c8\u5668\u952e\u76d8\u7f29\u653e\u7684\u57fa\u7840\u884c\u4e3a\u3002<\/p>\n<h3 id=\"%E6%96%B9%E6%B3%95%E4%BA%8Cjs-%E9%98%BB%E6%AD%A2-ctrl%E6%BB%9A%E8%BD%AE\">\u65b9\u6cd5\u4e8c\uff1aJS \u963b\u6b62 Ctrl+\u6eda\u8f6e<\/h3>\n<pre class=\"hljs\"><code><div><span class=\"hljs-built_in\">document<\/span>.addEventListener(<span class=\"hljs-string\">'wheel'<\/span>, (e) =&gt; {\n    <span class=\"hljs-keyword\">if<\/span> (e.ctrlKey || e.metaKey) e.preventDefault();\n}, { <span class=\"hljs-attr\">passive<\/span>: <span class=\"hljs-literal\">false<\/span> });\n<\/div><\/code><\/pre>\n<hr>\n<h2 id=\"%E5%85%AB%E5%AD%97%E4%BD%93%E6%96%B9%E6%A1%88\">\u516b\u3001\u5b57\u4f53\u65b9\u6848<\/h2>\n<h3 id=\"%E5%AD%97%E4%BD%93%E5%88%86%E7%B1%BB\">\u5b57\u4f53\u5206\u7c7b<\/h3>\n<table>\n<thead>\n<tr>\n<th>\u7528\u9014<\/th>\n<th>\u63a8\u8350\u5b57\u4f53<\/th>\n<th>\u8bf4\u660e<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><strong>\u897f\u6587\u6b63\u6587<\/strong><\/td>\n<td><code>Palatino Linotype, Helvetica Neue, Segoe UI<\/code><\/td>\n<td>\u6709\u886c\u7ebf\uff0c\u5b66\u672f\u611f<\/td>\n<\/tr>\n<tr>\n<td><strong>\u897f\u6587\u56fe\u8868<\/strong><\/td>\n<td><code>Inter, Segoe UI<\/code><\/td>\n<td>\u65e0\u886c\u7ebf\uff0c\u5c0f\u5b57\u6e05\u6670<\/td>\n<\/tr>\n<tr>\n<td><strong>\u897f\u6587 Reference<\/strong><\/td>\n<td><code>Georgia, Times New Roman<\/code><\/td>\n<td>\u886c\u7ebf\uff0c\u5b66\u672f\u5f15\u7528<\/td>\n<\/tr>\n<tr>\n<td><strong>\u4e2d\u6587\u6b63\u6587<\/strong><\/td>\n<td><code>Noto Serif SC, Source Han Serif SC<\/code><\/td>\n<td>\u601d\u6e90\u5b8b\u4f53\uff0c\u5b66\u672f\u611f<\/td>\n<\/tr>\n<tr>\n<td><strong>\u4e2d\u6587\u8868\u683c<\/strong><\/td>\n<td><code>Noto Sans SC, Source Han Sans SC<\/code><\/td>\n<td>\u601d\u6e90\u9ed1\u4f53\uff0c\u5c0f\u5b57\u6e05\u6670<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3 id=\"google-fonts-%E5%BC%95%E5%85%A5\">Google Fonts \u5f15\u5165<\/h3>\n<pre class=\"hljs\"><code><div><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">link<\/span> <span class=\"hljs-attr\">href<\/span>=<span class=\"hljs-string\">\"https:\/\/fonts.googleapis.com\/css2?family=Inter:wght@400;500;600;700&amp;family=Noto+Serif+SC:wght@400;600;700&amp;family=Noto+Sans+SC:wght@400;500;700&amp;display=swap\"<\/span> <span class=\"hljs-attr\">rel<\/span>=<span class=\"hljs-string\">\"stylesheet\"<\/span>&gt;<\/span>\n<\/div><\/code><\/pre>\n<h3 id=\"css-%E5%8F%98%E9%87%8F\">CSS \u53d8\u91cf<\/h3>\n<pre class=\"hljs\"><code><div><span class=\"hljs-selector-pseudo\">:root<\/span> {\n    <span class=\"hljs-attribute\">--font-zh-body<\/span>: <span class=\"hljs-string\">'Noto Serif SC'<\/span>, <span class=\"hljs-string\">'Source Han Serif SC'<\/span>, <span class=\"hljs-string\">'SimSun'<\/span>, serif;\n    <span class=\"hljs-attribute\">--font-zh-chart<\/span>: <span class=\"hljs-string\">'Noto Sans SC'<\/span>, <span class=\"hljs-string\">'Source Han Sans SC'<\/span>, <span class=\"hljs-string\">'Microsoft YaHei'<\/span>, sans-serif;\n    <span class=\"hljs-attribute\">--font-zh-table<\/span>: <span class=\"hljs-string\">'Noto Sans SC'<\/span>, <span class=\"hljs-string\">'Source Han Sans SC'<\/span>, <span class=\"hljs-string\">'Microsoft YaHei'<\/span>, sans-serif;\n}\n<span class=\"hljs-selector-class\">.slide-body<\/span> { <span class=\"hljs-attribute\">font-family<\/span>: <span class=\"hljs-built_in\">var<\/span>(--font-zh-body); }\n<span class=\"hljs-selector-class\">.data-table<\/span> { <span class=\"hljs-attribute\">font-family<\/span>: <span class=\"hljs-built_in\">var<\/span>(--font-zh-table); }\n<span class=\"hljs-selector-tag\">svg<\/span> <span class=\"hljs-selector-tag\">text<\/span> { <span class=\"hljs-attribute\">font-family<\/span>: <span class=\"hljs-string\">'Inter'<\/span>, <span class=\"hljs-string\">'Segoe UI'<\/span>, sans-serif; }\n<\/div><\/code><\/pre>\n<hr>\n<h2 id=\"%E4%B9%9D%E7%BB%8F%E9%AA%8C%E6%B8%85%E5%8D%95\">\u4e5d\u3001\u7ecf\u9a8c\u6e05\u5355<\/h2>\n<table>\n<thead>\n<tr>\n<th>#<\/th>\n<th>\u7c7b\u522b<\/th>\n<th>\u6559\u8bad<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>1<\/td>\n<td><strong>\u622a\u56fe<\/strong><\/td>\n<td>Playwright \u622a\u56fe\u53d7 CSS <code>max-width<\/code> \u5f71\u54cd\uff0c\u9700\u914d\u5408 <code>transform: scale()<\/code> \u8c03\u6574<\/td>\n<\/tr>\n<tr>\n<td>2<\/td>\n<td><strong>\u56fe\u8868<\/strong><\/td>\n<td>Chart.js \u622a\u56fe\u65f6\u52a8\u753b\u672a\u5b8c\u6210\uff0c\u9700\u7b49\u5f85 2.5s<\/td>\n<\/tr>\n<tr>\n<td>3<\/td>\n<td><strong>SVG \u56fe\u8868<\/strong><\/td>\n<td>SVG y \u5750\u6807\u4ece\u4e0a\u5f80\u4e0b\uff0c\u67f1\u5b50 <code>y = \u57fa\u7ebf - \u9ad8\u5ea6<\/code><\/td>\n<\/tr>\n<tr>\n<td>4<\/td>\n<td><strong>\u7f16\u8f91<\/strong><\/td>\n<td>\u5927\u5e45\u7ed3\u6784\u8c03\u6574\u7528 <code>write<\/code> \u91cd\u5199\uff0c\u4e0d\u8981\u591a\u6b21 <code>edit<\/code> \u62fc\u51d1<\/td>\n<\/tr>\n<tr>\n<td>5<\/td>\n<td><strong>\u5de5\u5177\u680f<\/strong><\/td>\n<td>controls-bar \u5fc5\u987b\u653e\u5728 presentation-container \u5185\u90e8\u3001slide-viewport \u5916\u90e8<\/td>\n<\/tr>\n<tr>\n<td>6<\/td>\n<td><strong>\u5168\u5c4f<\/strong><\/td>\n<td><code>wasInFullscreen<\/code> \u6807\u5fd7\u9632\u9000\u51fa\u51b2\u7a81<\/td>\n<\/tr>\n<tr>\n<td>7<\/td>\n<td><strong>\u7f29\u653e\u6a21\u578b<\/strong><\/td>\n<td>\u5730\u56fe\u6a21\u578b\u4e0e\u81ea\u9002\u5e94\u6a21\u578b\u4e92\u65a5\uff0c\u9009\u4e00\u4e2a<\/td>\n<\/tr>\n<tr>\n<td>8<\/td>\n<td><strong>Reference<\/strong><\/td>\n<td>presContainer \u5bbd\u5ea6\u5fc5\u987b\u6240\u6709\u6a21\u5f0f\u7edf\u4e00<\/td>\n<\/tr>\n<tr>\n<td>9<\/td>\n<td><strong>Zoom<\/strong><\/td>\n<td>\u81ea\u9002\u5e94\u6a21\u578b\u5fc5\u987b\u7981\u7528\u6d4f\u89c8\u5668 zoom<\/td>\n<\/tr>\n<tr>\n<td>10<\/td>\n<td><strong>\u5b57\u53f7<\/strong><\/td>\n<td>\u7528\u6574\u6570 px \u503c\u6d88\u9664\u5b50\u50cf\u7d20\u56db\u820d\u4e94\u5165<\/td>\n<\/tr>\n<tr>\n<td>11<\/td>\n<td><strong>Canvas \u6bd4\u4f8b<\/strong><\/td>\n<td>1200\u00d7675 \u662f\u6700\u4f73 16:9 \u8bbe\u8ba1\u5c3a\u5bf8<\/td>\n<\/tr>\n<tr>\n<td>12<\/td>\n<td><strong>\u7ffb\u9875\u7b14<\/strong><\/td>\n<td>PageUp\/PageDown \u7ed1\u5230\u4e0a\u4e00\u9875\/\u4e0b\u4e00\u9875<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<hr>\n<h2 id=\"%E9%99%84%E5%BD%95%E5%AE%8C%E6%95%B4%E9%85%8D%E7%BD%AE%E6%B8%85%E5%8D%95agentsmd\">\u9644\u5f55\uff1a\u5b8c\u6574\u914d\u7f6e\u6e05\u5355\uff08AGENTS.md\uff09<\/h2>\n<p>\u4ee5\u4e0b\u4e3a\u9879\u76ee\u5168\u7a0b\u79ef\u7d2f\u7684\u89c4\u8303\u6587\u6863\u3002\u5982\u4f7f\u7528 AI Agent \u8fdb\u884c HTML \u6f14\u793a\u6587\u7a3f\u5f00\u53d1\uff0c\u53ef\u76f4\u63a5\u5c06\u4e0b\u65b9\u4ee3\u7801\u5757\u7c98\u8d34\u81f3\u5de5\u4f5c\u76ee\u5f55\u4e0b\u7684 <code>AGENTS.md<\/code>\uff1a<\/p>\n<pre class=\"hljs\"><code><div><span class=\"hljs-section\"># OpenCode \u4efb\u52a1\u5904\u7406\u8bb0\u5f55<\/span>\n\n<span class=\"hljs-section\">## \u4e00\u3001\u4efb\u52a1\u7c7b\u578b<\/span>\n\n<span class=\"hljs-section\">### 1. \u6587\u4ef6\u683c\u5f0f\u8f6c\u6362\u7c7b<\/span>\n<span class=\"hljs-bullet\">- <\/span><span class=\"hljs-strong\">**HTML \u2192 \u56fe\u7247 \u2192 PPTX**<\/span>\uff1a\u4ece HTML \u5e7b\u706f\u7247\u51fa\u53d1\uff0c\u901a\u8fc7\u6d4f\u89c8\u5668\u622a\u56fe\u751f\u6210\u9ad8\u6e05\u56fe\u7247\uff0c\u518d\u5408\u6210 PPT\u3002\n<span class=\"hljs-bullet\">- <\/span>\u5173\u952e\u5de5\u5177\uff1aPlaywright\uff08\u6d4f\u89c8\u5668\u622a\u56fe\uff09\u3001python-pptx\uff08\u5408\u6210 PPT\uff09\u3001Pillow\uff08\u68c0\u67e5\u56fe\u7247\u5c3a\u5bf8\uff09\u3002\n\n<span class=\"hljs-section\">### 2. \u6279\u91cf\u56fe\u7247\u5904\u7406\u7c7b<\/span>\n<span class=\"hljs-bullet\">- <\/span>\u622a\u53d6\u591a\u9875\u5e7b\u706f\u7247\uff0c\u7edf\u4e00\u5206\u8fa8\u7387\u3001\u5bbd\u9ad8\u6bd4\uff0c\u6279\u91cf\u5199\u5165 PPT\u3002\n<span class=\"hljs-bullet\">- <\/span>\u6838\u5fc3\u9700\u6c42\uff1a\u9ad8\u5206\u8fa8\u7387\uff08\u907f\u514d\u5b57\u4f53\u6a21\u7cca\uff09\u3001\u6bd4\u4f8b\u4e00\u81f4\uff08\u907f\u514d\u62c9\u4f38\uff09\u3002\n\n<span class=\"hljs-section\">### 3. \u524d\u7aef HTML \u5185\u5bb9\u7f16\u8f91\u7c7b<\/span>\n<span class=\"hljs-bullet\">- <\/span>\u7ed3\u6784\u8c03\u6574\uff1a\u7ae0\u8282\u91cd\u7f16\u53f7\u3001\u76ee\u5f55\u91cd\u7ec4\u3001\u9875\u9762\u589e\u5220\u3002\n<span class=\"hljs-bullet\">- <\/span>\u6837\u5f0f\u8c03\u6574\uff1aCSS \u8865\u5168\u3001\u5e03\u5c40\u6539\u52a8\uff08\u6307\u5bfc\u8001\u5e08\u4f4d\u7f6e\u3001\u76ee\u5f55\u7ed3\u6784\u3001\u6807\u9898\u683c\u5f0f\uff09\u3002\n<span class=\"hljs-bullet\">- <\/span>\u5185\u5bb9\u6e05\u7406\uff1a\u53bb\u9664\u5197\u4f59\u6ce8\u91ca\u3001\u4fee\u6b63\u8bed\u4e49\u9519\u8bef\uff08\u5982\u81f4\u8c22\u9875\u5220\u9664\u540e\u53c8\u91cd\u65b0\u52a0\u4e0a\uff09\u3002\n\n<span class=\"hljs-section\">### 4. \u81ea\u52a8\u5316\u811a\u672c\u7f16\u5199\u7c7b<\/span>\n<span class=\"hljs-bullet\">- <\/span>Node.js \u811a\u672c\uff1a\u63a7\u5236 Playwright \u622a\u53d6\u5e7b\u706f\u7247\u3002\n<span class=\"hljs-bullet\">- <\/span>Python \u811a\u672c\uff1a\u751f\u6210 PPT\u3001\u63a7\u5236\u56fe\u7247\u7f29\u653e\u6bd4\u4f8b\u548c\u4f4d\u7f6e\u3002\n\n---\n\n<span class=\"hljs-section\">## \u4e8c\u3001\u9047\u5230\u7684\u4e00\u4e9b\u5751<\/span>\n\n<span class=\"hljs-section\">### 1. Playwright \u622a\u56fe\u5c3a\u5bf8\u95ee\u9898<\/span>\n<span class=\"hljs-bullet\">- <\/span><span class=\"hljs-strong\">**\u73b0\u8c61**<\/span>\uff1aviewport deviceScaleFactor=2 \u4ecd\u7136\u53ea\u6709 1100px \u5bbd\uff0c\u56fe\u7247\u6ca1\u6709\u6309\u9884\u671f\u653e\u5927\u3002\n<span class=\"hljs-bullet\">- <\/span><span class=\"hljs-strong\">**\u539f\u56e0**<\/span>\uff1aCSS \u4e2d <span class=\"hljs-code\">`.slide`<\/span> \u7684 <span class=\"hljs-code\">`max-width: 1100px`<\/span> \u9650\u5236\u4e86\u5b9e\u9645\u6e32\u67d3\u5bbd\u5ea6\uff0c\u622a\u56fe\u53ea\u622a\u5230\u4e86\u88ab max-width \u7ea6\u675f\u540e\u7684\u5185\u5bb9\u3002\n<span class=\"hljs-bullet\">- <\/span><span class=\"hljs-strong\">**\u89e3\u51b3**<\/span>\uff1a\u901a\u8fc7 <span class=\"hljs-code\">`element.style.transform = 'scale(N)'`<\/span> \u653e\u5927\u5143\u7d20 + \u8bbe\u7f6e\u5bf9\u5e94\u5bbd\u7684 viewport + deviceScaleFactor=2\uff0c\u4e09\u8005\u914d\u5408\u624d\u80fd\u5f97\u5230\u5927\u5c3a\u5bf8\u56fe\u7247\u3002\n\n<span class=\"hljs-section\">### 2. Chart.js \u56fe\u8868\u622a\u53d6\u4e3a\u7a7a\u767d<\/span>\n<span class=\"hljs-bullet\">- <\/span><span class=\"hljs-strong\">**\u73b0\u8c61**<\/span>\uff1a\u5305\u542b Chart.js \u56fe\u8868\u7684\u9875\u9762\u622a\u56fe\u65f6\uff0c\u56fe\u8868\u533a\u57df\u662f\u7a7a\u767d\u6216\u53ea\u6709\u5360\u4f4d\u7b26\u3002\n<span class=\"hljs-bullet\">- <\/span><span class=\"hljs-strong\">**\u539f\u56e0**<\/span>\uff1a\u622a\u56fe\u65f6 Chart.js \u52a8\u753b\u5c1a\u672a\u5b8c\u6210\uff08\u5c24\u5176\u662f\u997c\u56fe\u9996\u6b21\u6e32\u67d3\uff09\uff0c\u4e14 Pie Chart \u5728 slide \u5207\u6362\u540e\u9700\u8981\u91cd\u65b0\u5b9e\u4f8b\u5316\u624d\u80fd\u663e\u793a\u3002\n<span class=\"hljs-bullet\">- <\/span><span class=\"hljs-strong\">**\u89e3\u51b3**<\/span>\uff1a\u5207\u6362\u5230\u76ee\u6807 slide \u540e\u7b49\u5f85\u8db3\u591f\u65f6\u95f4\uff08\u5982 2500ms\uff09\uff0c\u786e\u4fdd\u52a8\u753b\u5b8c\u6210\u540e\u518d\u622a\u56fe\u3002\n\n<span class=\"hljs-section\">### 3. \u591a\u6b21\u7f16\u8f91\u5bfc\u81f4 HTML \u7ed3\u6784\u9519\u4e71<\/span>\n<span class=\"hljs-bullet\">- <\/span><span class=\"hljs-strong\">**\u73b0\u8c61**<\/span>\uff1a\u91cd\u590d\u7f16\u8f91\u540e\u51fa\u73b0\u91cd\u590d\u7684 slide \u5757\u3001\u7f16\u53f7\u8df3\u53f7\u3001\u6807\u7b7e\u4e0d\u5339\u914d\u3002\n<span class=\"hljs-bullet\">- <\/span><span class=\"hljs-strong\">**\u539f\u56e0**<\/span>\uff1a\u4e4b\u524d\u591a\u6b21\u5c40\u90e8 edit \u65f6\u65b0\u5185\u5bb9\u8986\u76d6\u4e86\u65e7\u5185\u5bb9\u4f46\u6ca1\u5b8c\u5168\u6e05\u7406\u5e72\u51c0\uff0c\u52a0\u4e0a grep \u641c\u7d22\u53ea\u80fd\u5b9a\u4f4d\u884c\u53f7\u800c\u65e0\u6cd5\u611f\u77e5\u7ed3\u6784\u91cd\u53e0\u3002\n<span class=\"hljs-bullet\">- <\/span><span class=\"hljs-strong\">**\u89e3\u51b3**<\/span>\uff1a\u9762\u5bf9\u5927\u5e45\u5ea6\u7ed3\u6784\u8c03\u6574\u65f6\uff0c\u4f18\u5148\u91cd\u5199\u6574\u4e2a\u6587\u4ef6\u800c\u975e\u9010\u5757\u4fee\u6539\uff0c\u907f\u514d\u79ef\u7d2f\u6027\u7684\u7f16\u8f91\u9519\u8bef\u3002\n\n<span class=\"hljs-section\">### 4. PowerShell \u547d\u4ee4\u89e3\u6790\u9519\u8bef<\/span>\n<span class=\"hljs-bullet\">- <\/span><span class=\"hljs-strong\">**\u73b0\u8c61**<\/span>\uff1a<span class=\"hljs-code\">`cd \/d path &amp;&amp; cmd`<\/span> \u62a5\u9519\uff1b<span class=\"hljs-code\">`head`<\/span> \u88ab\u5f53\u4f5c cmdlet \u4e0d\u5b58\u5728\u3002\n<span class=\"hljs-bullet\">- <\/span><span class=\"hljs-strong\">**\u539f\u56e0**<\/span>\uff1aPowerShell 5.1 \u4e0d\u652f\u6301 <span class=\"hljs-code\">`&amp;&amp;`<\/span> \u4e32\u8054\u547d\u4ee4\uff1b<span class=\"hljs-code\">`head`<\/span> \u662f Linux \u547d\u4ee4\u5728 PowerShell \u4e2d\u4e0d\u5b58\u5728\u3002\n<span class=\"hljs-bullet\">- <\/span><span class=\"hljs-strong\">**\u89e3\u51b3**<\/span>\uff1a\u4f7f\u7528 <span class=\"hljs-code\">`;`<\/span> \u4ee3\u66ff <span class=\"hljs-code\">`&amp;&amp;`<\/span>\uff0c\u6216\u62c6\u5206\u6210\u591a\u4e2a Bash \u5de5\u5177\u8c03\u7528\uff1b\u7528 Python \u66ff\u4ee3 <span class=\"hljs-code\">`head`<\/span> \u7b49 shell \u547d\u4ee4\u505a\u6570\u636e\u68c0\u67e5\u3002\n\n<span class=\"hljs-section\">### 5. PPT \u751f\u6210\u65f6\u56fe\u7247\u6bd4\u4f8b\u62c9\u4f38<\/span>\n<span class=\"hljs-bullet\">- <\/span><span class=\"hljs-strong\">**\u73b0\u8c61**<\/span>\uff1a\u56fe\u7247\u653e\u5165 16:9 \u5e7b\u706f\u7247\u540e\u88ab\u4e25\u91cd\u62c9\u4f38\u6216\u7559\u767d\u8fc7\u591a\u3002\n<span class=\"hljs-bullet\">- <\/span><span class=\"hljs-strong\">**\u539f\u56e0**<\/span>\uff1a\u56fe\u7247\u5bbd\u9ad8\u6bd4\uff083300:1650 = 2:1\uff09\u4e0e PPT \u6bd4\u4f8b\uff0816:9 \u2248 1.78:1\uff09\u4e0d\u4e00\u81f4\uff0c<span class=\"hljs-code\">`scale = min(scale_w, scale_h)`<\/span> \u8ba9\u56fe\u7247\u586b\u4e0d\u6ee1\u3002\n<span class=\"hljs-bullet\">- <\/span><span class=\"hljs-strong\">**\u89e3\u51b3**<\/span>\uff1a\u4ee5\u5bbd\u5ea6\u4e3a\u57fa\u51c6\u7f29\u653e\uff08\u5bbd\u5ea6\u6491\u6ee1\uff0c\u5de6\u4e0a\u5bf9\u9f50\uff09\uff0c\u6216\u5728 PPT \u5c3a\u5bf8\u8bbe\u7f6e\u65f6\u6539\u7528\u66f4\u5bbd\u7684\u5e7b\u706f\u7247\u6bd4\u4f8b\u5339\u914d\u56fe\u7247\u3002\n\n<span class=\"hljs-section\">### 6. Python pptx \u5e93\u5bfc\u5165\u9519\u8bef<\/span>\n<span class=\"hljs-bullet\">- <\/span><span class=\"hljs-strong\">**\u73b0\u8c61**<\/span>\uff1a<span class=\"hljs-code\">`from pptx.dml.color import RgbColor`<\/span> \u62a5\u9519\uff0c\u8be5\u6a21\u5757\u4e0d\u5b58\u5728\u3002\n<span class=\"hljs-bullet\">- <\/span><span class=\"hljs-strong\">**\u539f\u56e0**<\/span>\uff1apptx \u5e93\u7684 <span class=\"hljs-code\">`dml.color`<\/span> \u5b50\u6a21\u5757\u4e2d\u6ca1\u6709 <span class=\"hljs-code\">`RgbColor`<\/span>\uff0c\u662f\u8bb0\u5fc6\u6027\u9519\u8bef\u3002\n<span class=\"hljs-bullet\">- <\/span><span class=\"hljs-strong\">**\u89e3\u51b3**<\/span>\uff1a\u76f4\u63a5\u7528 <span class=\"hljs-code\">`from pptx import Presentation`<\/span> + <span class=\"hljs-code\">`from pptx.util import Inches`<\/span>\uff0c\u4e0d\u5f15\u7528\u4e0d\u5b58\u5728\u7684\u5b50\u6a21\u5757\u3002\n\n<span class=\"hljs-section\">### 7. \u8def\u5f84\u4e2d\u5305\u542b\u4e2d\u6587\u5b57\u7b26<\/span>\n<span class=\"hljs-bullet\">- <\/span><span class=\"hljs-strong\">**\u73b0\u8c61**<\/span>\uff1a\u6587\u4ef6\u8def\u5f84\u542b\u4e2d\u6587\u65f6\uff0cPython \u8bfb\u53d6\u6b63\u5e38\u4f46 PowerShell \u547d\u4ee4\u89e3\u6790\u53ef\u80fd\u51fa\u9519\u3002\n<span class=\"hljs-bullet\">- <\/span><span class=\"hljs-strong\">**\u539f\u56e0**<\/span>\uff1aPowerShell \u9ed8\u8ba4\u7f16\u7801\u4e0d\u662f UTF-8\u3002\n<span class=\"hljs-bullet\">- <\/span><span class=\"hljs-strong\">**\u89e3\u51b3**<\/span>\uff1aPowerShell \u811a\u672c\u5f00\u5934\u52a0 <span class=\"hljs-code\">`[Console]::OutputEncoding = [System.Text.Encoding]::UTF8`<\/span>\uff1bPython \u4f7f\u7528 <span class=\"hljs-code\">`-X utf8`<\/span> \u53c2\u6570\u6216\u5728\u4ee3\u7801\u4e2d <span class=\"hljs-code\">`sys.stdout.reconfigure(encoding='utf-8')`<\/span>\u3002\n\n<span class=\"hljs-section\">### 8. controls-bar \u4f4d\u7f6e\u9519\u8bef\u5bfc\u81f4\u5de5\u5177\u680f\u6d88\u5931<\/span>\n<span class=\"hljs-bullet\">- <\/span><span class=\"hljs-strong\">**\u73b0\u8c61**<\/span>\uff1a\u5de5\u5177\u680f\u53ea\u5728\u6700\u540e\u4e00\u9875\u663e\u793a\uff0c\u6216\u51fa\u73b0\u5728 slide \u4e0a\u9762\u800c\u4e0d\u662f\u4e0b\u9762\u3002\n<span class=\"hljs-bullet\">- <\/span><span class=\"hljs-strong\">**\u539f\u56e0**<\/span>\uff1aHTML \u5d4c\u5957\u7ed3\u6784\u9519\u8bef\uff0cclosing tag \u7f3a\u5931\u5bfc\u81f4 controls-bar \u88ab\u5305\u542b\u5728 slide \u6216 slide-viewport \u5185\u90e8\u3002\n<span class=\"hljs-bullet\">- <\/span><span class=\"hljs-strong\">**\u89e3\u51b3**<\/span>\uff1acontrols-bar \u5fc5\u987b\u4f4d\u4e8e presentation-container \u5185\u90e8\u3001slide-viewport \u5916\u90e8\u3002\u6b63\u786e\u7ed3\u6784\uff1a\n  <span class=\"hljs-code\">```<\/span>\n  presentation-container\n<span class=\"hljs-code\">    slide-viewport<\/span>\n<span class=\"hljs-code\">      slide (\u6240\u6709\u9875)<\/span>\n<span class=\"hljs-code\">    controls-bar  \u2190 \u5728\u8fd9\u91cc<\/span>\n  <span class=\"hljs-code\">```<\/span>\n\n<span class=\"hljs-section\">### 9. SVG \u56fe\u8868\u67f1\u5b50\u9ad8\u5ea6\u8ba1\u7b97\u9519\u8bef<\/span>\n<span class=\"hljs-bullet\">- <\/span><span class=\"hljs-strong\">**\u73b0\u8c61**<\/span>\uff1a\u67f1\u72b6\u56fe\u67f1\u5b50\u9ad8\u5ea6\u4e0e\u6570\u636e\u4e0d\u6210\u6bd4\u4f8b\uff0c\u67f1\u5b50\u9876\u5230\u9876\u90e8\u6216\u4f4e\u4e8e\u57fa\u7ebf\u3002\n<span class=\"hljs-bullet\">- <\/span><span class=\"hljs-strong\">**\u539f\u56e0**<\/span>\uff1aSVG y \u5750\u6807\u662f\u4ece\u4e0a\u5f80\u4e0b\u8ba1\u7b97\u7684\uff0crect \u7684 y \u662f\u67f1\u5b50\u9876\u90e8\u7684\u4f4d\u7f6e\u800c\u4e0d\u662f\u5e95\u90e8\u3002\u9700\u8981\u7528 <span class=\"hljs-code\">`y = \u57fa\u51c6\u7ebf - \u67f1\u5b50\u9ad8\u5ea6`<\/span> \u8ba1\u7b97\u3002\n<span class=\"hljs-bullet\">- <\/span><span class=\"hljs-strong\">**\u89e3\u51b3**<\/span>\uff1a\u5148\u786e\u5b9a 0% \u57fa\u7ebf\u4f4d\u7f6e\uff08\u5982 y=240\uff09\uff0c\u67f1\u5b50\u9ad8\u5ea6 = \u503c \/ \u6700\u5927\u503c * \u53ef\u7528\u9ad8\u5ea6\uff0c\u67f1\u5b50 y = \u57fa\u51c6\u7ebf - \u67f1\u5b50\u9ad8\u5ea6\u3002\n\n<span class=\"hljs-section\">### 10. \u6d4f\u89c8\u5668 zoom \u5bfc\u81f4\u5185\u5bb9\u6ea2\u51fa\u5230\u8d1f\u5750\u6807<\/span>\n<span class=\"hljs-bullet\">- <\/span><span class=\"hljs-strong\">**\u73b0\u8c61**<\/span>\uff1a\u4f7f\u7528 Ctrl+\/ \u653e\u5927\u6d4f\u89c8\u5668\u540e\uff0c\u5de6\u8fb9\u5185\u5bb9\u88ab\u88c1\u5207\uff0c\u65e0\u6cd5\u6eda\u52a8\u5230\u8d1f\u5750\u6807\u533a\u57df\u3002\n<span class=\"hljs-bullet\">- <\/span><span class=\"hljs-strong\">**\u539f\u56e0**<\/span>\uff1aflexbox \u7684 <span class=\"hljs-code\">`justify-content: center`<\/span> \u5728\u5185\u5bb9\u6ea2\u51fa\u65f6\u5bfc\u81f4\u6ea2\u51fa\u90e8\u5206\u4e0d\u53ef\u8bbf\u95ee\u3002\n<span class=\"hljs-bullet\">- <\/span><span class=\"hljs-strong\">**\u89e3\u51b3**<\/span>\uff1a\u4e0d\u8981\u7528 flexbox center \u914d\u5408 overflow\u3002\u4f7f\u7528 <span class=\"hljs-code\">`margin: 40px auto`<\/span> \u6216 padding \u914d\u5408\u56fa\u5b9a\u5bbd\u5ea6\u5bb9\u5668\uff0c\u786e\u4fdd\u5185\u5bb9\u59cb\u7ec8\u5728\u53ef\u6eda\u52a8\u8303\u56f4\u5185\u3002\n\n<span class=\"hljs-section\">### 11. Reference \u9875\u6761\u76ee\u6570\u91cf\u968f zoom\/resize\/fullscreen \u53d8\u5316<\/span>\n<span class=\"hljs-bullet\">- <\/span><span class=\"hljs-strong\">**\u73b0\u8c61**<\/span>\uff1a\u6309\u4e0b\u5168\u5c4f\u6309\u94ae\u540e\uff0c\u53c2\u8003\u6587\u732e\u9875\u53ef\u89c1\u6761\u76ee\u4ece 14 \u6761\u53d8\u4e3a 16 \u6761\uff1b\u6d4f\u89c8\u5668 zoom \u548c resize \u4e5f\u4f1a\u6539\u53d8\u6761\u76ee\u6570\u91cf\u3002\n<span class=\"hljs-bullet\">- <\/span><span class=\"hljs-strong\">**\u539f\u56e0**<\/span>\uff1a\u4e0d\u540c\u6a21\u5f0f\u4e0b presContainer \u5bbd\u5ea6\u4e0d\u4e00\u81f4\uff08\u666e\u901a\u6a21\u5f0f 1120px vs \u5168\u5c4f\/auto-scale 1200px\uff09\uff0c\u5bfc\u81f4\u6587\u672c\u6362\u884c\u4e0d\u540c \u2192 \u603b\u884c\u6570\u4e0d\u540c \u2192 \u88ab overflow: hidden \u88c1\u526a\u7684\u6761\u76ee\u4e0d\u540c\u3002\n<span class=\"hljs-bullet\">  - <\/span>\u4e0d\u662f\u5b50\u50cf\u7d20\u56db\u820d\u4e94\u5165\u7684\u4e3b\u56e0\uff08\u00b113px \u53ea\u80fd\u89e3\u91ca 0-1 \u6761\uff09\n<span class=\"hljs-bullet\">  - <\/span>80px \u5bbd\u5ea6\u5dee\u6539\u53d8\u4e86 7-8 \u4e2a\u957f\u6761\u76ee\u7684\u6362\u884c\uff08\u6bcf\u7a84 80px \u591a wrap 1 \u884c\uff09\uff0c\u603b\u5dee\u5f02 ~138px\uff0c\u8db3\u591f\u89e3\u91ca 4 \u6761\u53d8\u5316\n<span class=\"hljs-bullet\">- <\/span><span class=\"hljs-strong\">**\u89e3\u51b3**<\/span>\uff1a\u7edf\u4e00 presContainer \u5bbd\u5ea6\u2014\u2014canvas-wrapper \u52a0 padding: 40px\uff0ccanvas-center \u7eaf\u5185\u5bb9 1200px\uff0cpresContainer \u59cb\u7ec8 1200px\u3002\n<span class=\"hljs-bullet\">  - <\/span>\u6d4f\u89c8\u5668 zoom \u7684\u8fde\u9501\u53cd\u5e94\uff1azoom \u653e\u5927 \u2192 viewport \u7f29\u5c0f \u2192 auto-scale \u89e6\u53d1 \u2192 \u628a presContainer \u8bbe\u4e3a 1200px\uff08\u4e0e\u666e\u901a\u6a21\u5f0f\u4e00\u81f4\uff09\n\n<span class=\"hljs-section\">### 12. Zoom \u7981\u7528\u5b9e\u73b0<\/span>\n<span class=\"hljs-bullet\">- <\/span><span class=\"hljs-strong\">**\u73b0\u8c61**<\/span>\uff1a\u81ea\u9002\u5e94\u6a21\u578b\u4e0b\uff0c\u6d4f\u89c8\u5668 zoom \u4ecd\u53ef\u901a\u8fc7 Ctrl+\u6eda\u8f6e\u89e6\u53d1\uff0c\u5bfc\u81f4 auto-scale \u53cd\u590d\u62b5\u6d88\uff0c\u4f53\u9a8c\u4e0d\u4f73\u3002\n<span class=\"hljs-bullet\">- <\/span><span class=\"hljs-strong\">**\u89e3\u51b3**<\/span>\uff1a\n<span class=\"hljs-bullet\">  1. <\/span><span class=\"hljs-code\">`&lt;meta viewport&gt;`<\/span> \u52a0 <span class=\"hljs-code\">`maximum-scale=1.0, user-scalable=no`<\/span>\n<span class=\"hljs-bullet\">  2. <\/span>JS \u963b\u6b62 <span class=\"hljs-code\">`Ctrl\/Cmd + wheel`<\/span> \u4e8b\u4ef6\n  <span class=\"hljs-code\">```<\/span>javascript\n  document.addEventListener('wheel', (e) =&gt; {\n<span class=\"hljs-code\">      if (e.ctrlKey || e.metaKey) e.preventDefault();<\/span>\n  }, { passive: false });\n  <span class=\"hljs-code\">```<\/span>\n\n---\n\n<span class=\"hljs-section\">## \u4e09\u3001\u5e38\u89c1\u89e3\u51b3\u529e\u6cd5<\/span>\n\n<span class=\"hljs-section\">### \u9ad8\u5206\u8fa8\u7387\u622a\u56fe<\/span>\n<span class=\"hljs-code\">```\nviewport: { width: N, height: M }\ndeviceScaleFactor: 2\uff082x \u7f29\u653e\uff09\n\n\u914d\u5408 CSS transform: scale(1.9) + \u76f8\u5e94\u8c03\u6574 container \u5bbd\u5ea6\n```<\/span>\n\n<span class=\"hljs-section\">### \u7b49\u5f85 Chart.js \u6e32\u67d3\u5b8c\u6210<\/span>\n<span class=\"hljs-code\">```javascript\nawait page.waitForTimeout(2500); \/\/ \u5207\u6362 slide \u540e\u7b49\u5f85 2.5 \u79d2\nconst buf = await slide.screenshot({ type: 'png' });\n```<\/span>\n\n<span class=\"hljs-section\">### \u6279\u91cf\u622a\u53d6\u591a\u9875\u5e7b\u706f\u7247<\/span>\n<span class=\"hljs-code\">```javascript\nfor (let i = 0; i &lt; slideCount; i++) {\n    await page.evaluate((idx) =&gt; {\n        const slides = document.querySelectorAll('.slide');\n        slides.forEach((s, i) =&gt; s.classList.toggle('active', i === idx));\n    }, i);\n    await page.waitForTimeout(2500);\n    const slide = await page.locator('.slide.active');\n    await slide.screenshot({ type: 'png', path: `frames\/slide_${i+1}.png` });\n}\n```<\/span>\n\n<span class=\"hljs-section\">### \u751f\u6210 PPT \u5e76\u586b\u5145\u5168\u5bbd\u56fe\u7247<\/span>\n<span class=\"hljs-code\">```python\nfrom pptx import Presentation\nfrom pptx.util import Inches\nfrom PIL import Image\n\nprs = Presentation()\nprs.slide_width = Inches(13.33)  # \u5bbd\u5c4f\u6bd4\u4f8b\uff0c\u5339\u914d 3300:1650 \u2248 2:1\nprs.slide_height = Inches(7.5)\n\nfor i in range(1, 13):\n    img_path = f'frames\/slide_{i:02d}.png'\n    with Image.open(img_path) as img:\n        w, h = img.size\n    scale = Inches(13.33) \/ w\n    pic_w = int(w * scale)\n    pic_h = int(h * scale)\n    slide.shapes.add_picture(img_path, 0, 0, pic_w, pic_h)\n```<\/span>\n\n<span class=\"hljs-section\">### \u5927\u5e45\u7ed3\u6784\u8c03\u6574\u65f6\u91cd\u5199\u6587\u4ef6<\/span>\n\u4e0d\u8981\u4f9d\u8d56\u591a\u6b21 <span class=\"hljs-code\">`edit`<\/span> \u62fc\u51d1\uff0c\u76f4\u63a5 <span class=\"hljs-code\">`write`<\/span> \u6574\u6587\u4ef6\uff0c\u786e\u4fdd\u7ed3\u6784\u5e72\u51c0\u3002\n\n---\n\n<span class=\"hljs-section\">## \u56db\u3001\u6587\u4ef6\u8f93\u51fa<\/span>\n<span class=\"hljs-bullet\">\n- <\/span><span class=\"hljs-code\">`capture_slides.js`<\/span> \u2014 Playwright \u6279\u91cf\u622a\u56fe\u811a\u672c\n<span class=\"hljs-bullet\">- <\/span><span class=\"hljs-code\">`make_pptx.py`<\/span> \u2014 Python PPTX \u751f\u6210\u811a\u672c\n<span class=\"hljs-bullet\">- <\/span><span class=\"hljs-code\">`slides_frames\/`<\/span> \u2014 \u622a\u56fe\u56fe\u7247\u76ee\u5f55\n\n---\n\n<span class=\"hljs-section\">## \u4e94\u3001PPT \u751f\u6210\u89c4\u8303\uff08\u542b\u6309\u94ae\u63a7\u5236\uff09<\/span>\n\n<span class=\"hljs-section\">### \u751f\u6210\u524d\uff1a\u9690\u85cf\u63a7\u5236\u6309\u94ae<\/span>\n\u5728 HTML \u4e2d\u901a\u8fc7 CSS \u9690\u85cf <span class=\"hljs-code\">`.controls-bar`<\/span>\uff0c\u907f\u514d\u622a\u56fe\u4e2d\u51fa\u73b0\"\u4e0a\u4e00\u9875\/\u4e0b\u4e00\u9875\/\u5168\u5c4f\"\u7b49\u6309\u94ae\u3002\n\n\u4fee\u6539\u65b9\u6848\uff08\u4e34\u65f6\u6ce8\u91ca\u6389\uff09\uff1a\n<span class=\"hljs-code\">```css\n\/* .controls-bar { display: none; } *\/\n```<\/span>\n\n\u6216\u8005\u5728\u622a\u56fe\u811a\u672c\u4e2d\u901a\u8fc7 JavaScript \u4e34\u65f6\u9690\u85cf\uff1a\n<span class=\"hljs-code\">```javascript\ndocument.getElementById('controlsBar').style.display = 'none';\n\/\/ \u622a\u56fe\ndocument.getElementById('controlsBar').style.display = '';\n```<\/span>\n\n<span class=\"hljs-section\">### \u622a\u56fe\u5b8c\u6210\u540e\uff1a\u6062\u590d\u63a7\u5236\u6309\u94ae<\/span>\n\u6062\u590d\u4e0a\u8ff0 CSS \u6216 JS \u4ee3\u7801\uff0c\u4f7f HTML \u6062\u590d\u6b63\u5e38\u5c55\u793a\u3002\n\n<span class=\"hljs-section\">### \u5b8c\u6574\u6d41\u7a0b<\/span>\n<span class=\"hljs-bullet\">1. <\/span>\u4fee\u6539 HTML \u9690\u85cf controls-bar\n<span class=\"hljs-bullet\">2. <\/span>\u8fd0\u884c <span class=\"hljs-code\">`capture_slides.js`<\/span> \u622a\u56fe\n<span class=\"hljs-bullet\">3. <\/span>\u8fd0\u884c <span class=\"hljs-code\">`make_pptx.py`<\/span> \u751f\u6210 PPT\n<span class=\"hljs-bullet\">4. <\/span>\u6062\u590d HTML \u4e2d\u7684 controls-bar \u663e\u793a\n\n---\n\n<span class=\"hljs-section\">## \u516d\u3001\u81ea\u9002\u5e94\u7f29\u653e\u6a21\u578b\uff08\u63a8\u8350\uff09<\/span>\n\n<span class=\"hljs-section\">### \u6838\u5fc3\u6982\u5ff5<\/span>\nCanvas\uff081200\u00d7675\uff0c16:9\uff09\u662f\u8bbe\u8ba1\u57fa\u51c6\uff0c\u59cb\u7ec8\u901a\u8fc7 <span class=\"hljs-code\">`transform: scale()`<\/span> \u81ea\u9002\u5e94\u586b\u5145\u89c6\u7a97\u3002\n\n\u4e0e\u5730\u56fe\u6a21\u578b\u7684\u533a\u522b\uff1a\n<span class=\"hljs-bullet\">- <\/span>\u5730\u56fe\u6a21\u578b\uff1aCanvas \u56fa\u5b9a\u5c3a\u5bf8\uff0c\u89c6\u7a97\u53ea\u80fd\u770b\u5230\u4e00\u90e8\u5206\uff0c\u7528\u6eda\u52a8\u6d4f\u89c8\n<span class=\"hljs-bullet\">- <\/span><span class=\"hljs-strong\">**\u81ea\u9002\u5e94\u6a21\u578b\uff08\u63a8\u8350\uff09**<\/span>\uff1aCanvas \u59cb\u7ec8\u7f29\u653e\u81f3\u5b8c\u5168\u53ef\u89c1\uff0c\u65e0\u6eda\u52a8\u6761\uff0czoom \u88ab\u7981\u7528\n\n<span class=\"hljs-section\">### HTML \u7ed3\u6784<\/span>\n<span class=\"hljs-code\">```html\n&lt;body&gt;\n&lt;div class=\"canvas-wrapper\" id=\"canvasWrapper\"&gt;\n    &lt;div class=\"canvas-center\"&gt;\n        &lt;div class=\"presentation-container\" id=\"presContainer\"&gt;\n            &lt;div class=\"slide-viewport\" id=\"slideViewport\"&gt;\n                &lt;!-- \u6240\u6709 slide \u9875\u9762 --&gt;\n            &lt;\/div&gt;\n            &lt;div class=\"controls-bar\" id=\"controlsBar\"&gt;\n                &lt;!-- \u5de5\u5177\u680f\u6309\u94ae --&gt;\n            &lt;\/div&gt;\n        &lt;\/div&gt;\n    &lt;\/div&gt;\n&lt;\/div&gt;\n&lt;\/body&gt;\n```<\/span>\n\n<span class=\"hljs-section\">### CSS \u5e03\u5c40\uff08\u81ea\u9002\u5e94\u6a21\u578b\uff09<\/span>\n<span class=\"hljs-code\">```css\n*, *::before, *::after { box-sizing: border-box; }\n\n.canvas-wrapper {\n    width: 100%;\n    min-width: 100vw;\n    height: 100vh;\n    overflow: auto;\n    background: var(--bg);\n    display: flex;\n    flex-direction: column;\n    align-items: center;\n    padding: 40px;  \/* \u89c6\u89c9 fram \u653e\u5728 wrapper \u4e0a\uff0c\u4e0d\u5f71\u54cd presContainer \u5bbd\u5ea6 *\/\n}\n\n.canvas-center {\n    width: 1200px;           \/* \u56fa\u5b9a\u5bbd\u5ea6 = presContainer \u5bbd\u5ea6 *\/\n    flex-shrink: 0;\n    padding: 0;              \/* padding \u79fb\u5230 wrapper *\/\n}\n\n.presentation-container {\n    width: 100%;             \/* = 1200px *\/\n    height: 675px;\n    background: var(--slide-bg);\n    box-shadow: var(--shadow-lg);\n    overflow: hidden;\n    display: flex;\n    flex-direction: column;\n}\n\n.slide-viewport {\n    flex: 1;\n    position: relative;\n    overflow: hidden;        \/* \u81ea\u9002\u5e94\u6a21\u578b\u65e0\u6eda\u52a8 *\/\n}\n\n\/* \u5168\u5c4f\u6a21\u5f0f *\/\nbody.fullscreen-mode .canvas-wrapper {\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    overflow: hidden;\n    padding: 0;              \/* \u5168\u5c4f\u65f6\u53bb\u6389 fram *\/\n}\nbody.fullscreen-mode .slide-viewport {\n    overflow: hidden;\n}\nbody.fullscreen-mode .canvas-center {\n    padding: 0;\n}\nbody.fullscreen-mode .presentation-container {\n    transform-origin: center center;\n}\n```<\/span>\n\n<span class=\"hljs-section\">### \u7f29\u653e\u903b\u8f91\uff08JS\uff09<\/span>\n<span class=\"hljs-code\">```javascript\nconst CANVAS_WIDTH = 1200;\nconst CANVAS_HEIGHT = 675;\nlet wasInFullscreen = false;\n\n\/\/ \u81ea\u52a8\u7f29\u653e\uff1a\u5f53\u89c6\u7a97\u5c0f\u4e8e Canvas \u65f6\u7f29\u5c0f\u4ee5\u9002\u914d\nfunction updateAutoScale() {\n    const isFS = !!(document.fullscreenElement || document.webkitFullscreenElement);\n    if (isFS) {\n        presContainer.style.transform = '';\n        presContainer.style.transformOrigin = '';\n        presContainer.style.width = '';\n        presContainer.style.height = '';\n        return;\n    }\n    const screenW = window.innerWidth;\n    const screenH = window.innerHeight;\n    const scaleX = screenW \/ CANVAS_WIDTH;\n    const scaleY = screenH \/ CANVAS_HEIGHT;\n    const fitScale = Math.min(scaleX, scaleY, 1.0);\n\n    if (fitScale &lt; 1.0) {\n        presContainer.style.transform = `scale(${fitScale})`;\n        presContainer.style.transformOrigin = 'center center';\n        presContainer.style.width = CANVAS_WIDTH + 'px';\n        presContainer.style.height = CANVAS_HEIGHT + 'px';\n    } else {\n        presContainer.style.transform = '';\n        presContainer.style.transformOrigin = '';\n        presContainer.style.width = '';\n        presContainer.style.height = '';\n    }\n}\n\n\/\/ \u5168\u5c4f\u7f29\u653e\uff1a\u586b\u6ee1\u5c4f\u5e55\nfunction updateFullscreenUI() {\n    const isFS = !!(document.fullscreenElement || document.webkitFullscreenElement);\n    if (isFS) {\n        document.body.classList.add('fullscreen-mode');\n        const screenW = window.innerWidth;\n        const screenH = window.innerHeight;\n        const scaleX = screenW \/ CANVAS_WIDTH;\n        const scaleY = screenH \/ CANVAS_HEIGHT;\n        const scale = Math.min(scaleX, scaleY);\n        presContainer.style.transformOrigin = 'center center';\n        presContainer.style.transform = `scale(${scale})`;\n        wasInFullscreen = true;\n    } else if (wasInFullscreen) {\n        document.body.classList.remove('fullscreen-mode');\n        presContainer.style.transform = '';\n        presContainer.style.transformOrigin = '';\n        wasInFullscreen = false;\n    }\n}\n\nwindow.addEventListener('resize', () =&gt; {\n    updateAutoScale();\n    updateFullscreenUI();\n});\n```<\/span>\n\n<span class=\"hljs-section\">### \u5173\u952e\u5751\u70b9\uff08\u81ea\u9002\u5e94\u6a21\u578b\uff09<\/span>\n<span class=\"hljs-bullet\">1. <\/span><span class=\"hljs-strong\">**presContainer \u5bbd\u5ea6\u5fc5\u987b\u4e00\u81f4**<\/span>\uff1a\u6240\u6709\u6a21\u5f0f\u4e0b presContainer \u5fc5\u987b\u662f\u76f8\u540c CSS \u5bbd\u5ea6\uff081200px\uff09\uff0c\u5426\u5219\u6587\u672c\u6362\u884c\u53d8\u5316\u5bfc\u81f4 Reference \u7b49\u9875\u9762\u6761\u76ee\u6570\u91cf\u53d8\u52a8\u3002\n<span class=\"hljs-bullet\">2. <\/span><span class=\"hljs-strong\">**viewport \u7981\u6b62 zoom**<\/span>\uff1a\u81ea\u9002\u5e94\u6a21\u578b\u4e0e\u6d4f\u89c8\u5668 zoom \u4e92\u65a5\uff0c\u5fc5\u987b\u7981\u7528\u3002\n<span class=\"hljs-bullet\">3. <\/span><span class=\"hljs-strong\">**wasInFullscreen \u6807\u5fd7**<\/span>\uff1a\u9632\u6b62\u9000\u51fa\u5168\u5c4f\u65f6 auto-scale \u9519\u8bef\u53e0\u52a0 transform\u3002\n<span class=\"hljs-bullet\">4. <\/span><span class=\"hljs-strong\">**\u4e0d\u8981\u7528 flexbox center + overflow**<\/span>\uff1a\u5185\u5bb9\u6ea2\u51fa\u5230\u8d1f\u5750\u6807\u4e0d\u53ef\u8bbf\u95ee\u3002\n<span class=\"hljs-bullet\">5. <\/span><span class=\"hljs-strong\">**controls-bar \u5fc5\u987b\u4e25\u683c\u4f4d\u4e8e presentation-container \u5185\u90e8\u3001slide-viewport \u5916\u90e8**<\/span>\u3002\n<span class=\"hljs-bullet\">6. <\/span><span class=\"hljs-strong\">**closing tag \u7f3a\u5931\u4f1a\u5bfc\u81f4\u6574\u4f53\u7ed3\u6784\u9519\u4e71**<\/span>\u3002\n\n---\n\n<span class=\"hljs-section\">## \u4e03\u3001\u5de5\u5177\u680f\uff08Controls Bar\uff09\u89c4\u8303<\/span>\n\n<span class=\"hljs-section\">### \u4f4d\u7f6e\u7ed3\u6784<\/span>\n\u5de5\u5177\u680f\u5fc5\u987b\u4f4d\u4e8e <span class=\"hljs-code\">`presentation-container`<\/span> \u5185\u90e8\u3001<span class=\"hljs-code\">`slide-viewport`<\/span> \u5916\u90e8\u3002\n\n<span class=\"hljs-section\">### HTML \u7ed3\u6784<\/span>\n<span class=\"hljs-code\">```html\n&lt;div class=\"presentation-container\" id=\"presContainer\"&gt;\n    &lt;div class=\"slide-viewport\" id=\"slideViewport\"&gt;\n        &lt;!-- \u6240\u6709 slide \u9875\u9762 --&gt;\n    &lt;\/div&gt;\n    &lt;div class=\"controls-bar\" id=\"controlsBar\"&gt;\n        &lt;button id=\"btnPrev\" title=\"Previous Slide\"&gt;\u2190 Prev&lt;\/button&gt;\n        &lt;span class=\"slide-indicator\" id=\"slideIndicator\"&gt;1 \/ 15&lt;\/span&gt;\n        &lt;button id=\"btnNext\" title=\"Next Slide\"&gt;Next \u2192&lt;\/button&gt;\n        &lt;span class=\"divider\"&gt;&lt;\/span&gt;\n        &lt;button id=\"btnFullscreen\" title=\"Toggle Fullscreen\"&gt;\u26f6 Fullscreen&lt;\/button&gt;\n        &lt;button id=\"btnExitFs\" title=\"Exit Fullscreen\" style=\"display:none;\"&gt;\u2715 Exit FS&lt;\/button&gt;\n    &lt;\/div&gt;\n&lt;\/div&gt;\n```<\/span>\n\n<span class=\"hljs-section\">### CSS \u6837\u5f0f<\/span>\n<span class=\"hljs-code\">```css\n.controls-bar {\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    gap: 12px;\n    padding: 10px 20px;\n    background: #e8e4dc;\n    border-top: 1px solid var(--border);\n    flex-shrink: 0;\n}\n.controls-bar button {\n    font-family: 'Palatino Linotype', 'Helvetica Neue', 'Segoe UI', sans-serif;\n    font-size: 14px;\n    padding: 8px 16px;\n    border: 1.5px solid var(--primary);\n    background: #fff;\n    color: var(--primary);\n    border-radius: 5px;\n    cursor: pointer;\n    font-weight: 600;\n    transition: all 0.2s;\n}\n.controls-bar button:hover { background: var(--primary); color: #fff; }\n.controls-bar button:active { transform: scale(0.96); }\n.controls-bar .slide-indicator { font-size: 14px; color: #555; min-width: 60px; text-align: center; }\n.controls-bar .divider { width: 1px; height: 20px; background: #bbb; }\n```<\/span>\n\n<span class=\"hljs-section\">### \u952e\u76d8\u5feb\u6377\u952e<\/span>\n<span class=\"hljs-code\">```javascript\ndocument.addEventListener('keydown', (e) =&gt; {\n    if (e.key === 'ArrowLeft' || e.key === 'ArrowUp' || e.key === 'PageUp') {\n        e.preventDefault(); showSlide(currentIndex - 1);\n    }\n    else if (e.key === 'ArrowRight' || e.key === 'ArrowDown' || e.key === ' ' || e.key === 'PageDown') {\n        e.preventDefault(); showSlide(currentIndex + 1);\n    }\n    else if (e.key === 'Home') { e.preventDefault(); showSlide(0); }\n    else if (e.key === 'End') { e.preventDefault(); showSlide(totalSlides - 1); }\n    else if (e.key === 'f' || e.key === 'F') { e.preventDefault(); toggleFullscreen(); }\n});\n```<\/span>\n\n\u652f\u6301\u7ffb\u9875\u7b14\u7684 PageUp\/PageDown \u952e\u6620\u5c04\u3002\n\n---\n\n<span class=\"hljs-section\">## \u516b\u3001SVG \u56fe\u8868\u89c4\u8303<\/span>\n\n<span class=\"hljs-section\">### \u67f1\u72b6\u56fe\u7ed3\u6784<\/span>\n<span class=\"hljs-code\">```svg\n&lt;svg viewBox=\"0 0 420 285\" xmlns=\"...\"&gt;\n    &lt;rect x=\"0\" y=\"0\" width=\"420\" height=\"285\" fill=\"#fafaf8\" rx=\"6\"\/&gt;\n    &lt;text x=\"210\" y=\"18\" text-anchor=\"middle\" font-size=\"13\" fill=\"var(--primary)\" font-weight=\"700\"&gt;Chart Title&lt;\/text&gt;\n    &lt;line x1=\"50\" y1=\"40\" x2=\"390\" y2=\"40\" stroke=\"#e0dcd4\" stroke-width=\"1\"\/&gt;\n    &lt;!-- ... \u67f1\u5b50 ... --&gt;\n    &lt;rect x=\"60\" y=\"148\" width=\"48\" height=\"92\" fill=\"var(--chart-1)\" rx=\"4\" opacity=\"0.85\"\/&gt;\n    &lt;text x=\"84\" y=\"143\" text-anchor=\"middle\" font-size=\"11\" fill=\"var(--primary)\" font-weight=\"700\"&gt;10.31&lt;\/text&gt;\n    &lt;text x=\"84\" y=\"256\" text-anchor=\"middle\" font-size=\"10\" fill=\"#555\"&gt;2019&lt;\/text&gt;\n    &lt;line x1=\"50\" y1=\"240\" x2=\"390\" y2=\"240\" stroke=\"#999\" stroke-width=\"1.5\"\/&gt;\n    &lt;text x=\"210\" y=\"280\" text-anchor=\"middle\" font-size=\"9\" fill=\"#777\"&gt;Source: MOE [1]&lt;\/text&gt;\n&lt;\/svg&gt;\n```<\/span>\n\n<span class=\"hljs-section\">### \u5173\u952e\u8ba1\u7b97\u516c\u5f0f<\/span>\n<span class=\"hljs-bullet\">- <\/span><span class=\"hljs-strong\">**\u53ef\u7528\u9ad8\u5ea6**<\/span> = \u57fa\u7ebfy - \u4e0a\u8fb9\u8ddd\uff08\u5982 240 - 40 = 200\uff09\n<span class=\"hljs-bullet\">- <\/span><span class=\"hljs-strong\">**\u67f1\u5b50\u9ad8\u5ea6**<\/span> = \u503c \/ \u6700\u5927\u503c * \u53ef\u7528\u9ad8\u5ea6\n<span class=\"hljs-bullet\">- <\/span><span class=\"hljs-strong\">**\u67f1\u5b50y**<\/span> = \u57fa\u7ebfy - \u67f1\u5b50\u9ad8\u5ea6\n<span class=\"hljs-bullet\">- <\/span><span class=\"hljs-strong\">**\u67f1\u5b50x**<\/span> = \u8d77\u59cbx + \u5e8f\u53f7 * \u95f4\u8ddd\n\n<span class=\"hljs-section\">### \u989c\u8272\u89c4\u8303<\/span>\n<span class=\"hljs-code\">```css\n--chart-1: #2c5f7c;  \/* \u84dd\u8272 - \u4e3b\u8981\u6570\u636e *\/\n--chart-2: #b8860b;  \/* \u91d1\u8272 - \u5f3a\u8c03\u6570\u636e *\/\n--chart-3: #8b3a3a;  \/* \u7ea2\u8272 - \u5371\u9669\/\u8d1f\u9762\u6570\u636e *\/\n--chart-4: #4a7c59;  \/* \u7eff\u8272 - \u6b63\u9762\u6570\u636e *\/\n--danger: #8b1a1a;   \/* \u6df1\u7ea2 - \u6700\u9ad8\u5f3a\u8c03 *\/\n```<\/span>\n\n---\n\n<span class=\"hljs-section\">## \u4e5d\u3001Reference \u9875\u9762\u89c4\u8303<\/span>\n\n<span class=\"hljs-section\">### CSS \u6837\u5f0f<\/span>\n<span class=\"hljs-code\">```css\n.slide-body.ref-slide { gap: 0; font-family: 'Georgia', 'Times New Roman', serif; }\n.slide-body.ref-slide p { font-size: 15px; line-height: 1.15; margin: 0; }\n.slide-body.ref-slide .ref-item { margin-bottom: 2px; }\n```<\/span>\n\n<span class=\"hljs-section\">### \u884c\u95f4\u8ddd\u5173\u952e\u70b9<\/span>\n<span class=\"hljs-bullet\">- <\/span>\u4f7f\u7528 <span class=\"hljs-code\">`font-size: 15px; line-height: 1.15`<\/span> \u4fdd\u8bc1\u6240\u6709 18 \u6761\u53c2\u8003\u6587\u732e\u521a\u597d\u585e\u8fdb 675px \u9ad8\u5ea6\n<span class=\"hljs-bullet\">- <\/span><span class=\"hljs-strong\">**gap: 0**<\/span> \u9632\u6b62 flex \u95f4\u9699\n<span class=\"hljs-bullet\">- <\/span><span class=\"hljs-strong\">**margin-bottom: 2px**<\/span> \u6bb5\u843d\u95f4\u6700\u5c0f\u95f4\u8ddd\n\n---\n\n<span class=\"hljs-section\">## \u5341\u3001\u7248\u672c\u5386\u53f2<\/span>\n\n| \u7248\u672c | \u4e3b\u8981\u529f\u80fd | \u65e5\u671f |\n|------|---------|------|\n| v1.html | \u521d\u59cb\u7248\u672c | 2026-04-21 |\n| v2.html | \u6dfb\u52a0\u63a7\u5236\u680f\u3001\u4fee\u590d\u56fe\u8868 | 2026-04-24 |\n| v3.html | \u4fee\u590d\u56fe\u8868\u6570\u636e\u6807\u6ce8 | 2026-04-25 |\n| v4.html | \u6dfb\u52a0\u7f29\u653e\u903b\u8f91 | 2026-04-25 |\n| v5.html | SVG viewBox \u65b9\u6848\uff08\u5df2\u5e9f\u5f03\uff09 | 2026-04-25 |\n| v6.html | \u5730\u56fe\u5e03\u5c40\u6a21\u578b\uff0c\u4fee\u590d\u5de5\u5177\u680f\u4f4d\u7f6e | 2026-04-25 |\n| v7.html | \u81ea\u9002\u5e94\u7f29\u653e\u6a21\u578b\uff0c\u7981\u7528 zoom\uff0c\u7edf\u4e00 presContainer \u5bbd\u5ea6 | 2026-04-25 |\n\n---\n\n<span class=\"hljs-section\">## \u5341\u4e00\u3001\u5b57\u4f53\u89c4\u8303<\/span>\n\n<span class=\"hljs-section\">### \u5b57\u4f53\u5206\u7c7b<\/span>\n\n| \u7528\u9014 | \u63a8\u8350\u5b57\u4f53 | \u8bf4\u660e |\n|------|---------|------|\n| <span class=\"hljs-strong\">**\u897f\u6587\u6b63\u6587**<\/span> | <span class=\"hljs-code\">`'Palatino Linotype', 'Helvetica Neue', 'Segoe UI', sans-serif`<\/span> | \u897f\u6587\u65e0\u886c\u7ebf\uff0c\u6e05\u6670\u6613\u8bfb |\n| <span class=\"hljs-strong\">**\u897f\u6587\u56fe\u8868**<\/span> | <span class=\"hljs-code\">`'Inter', 'Segoe UI', sans-serif`<\/span> | \u4e13\u95e8\u7528\u4e8e SVG \u5185\u6587\u5b57 |\n| <span class=\"hljs-strong\">**\u897f\u6587 Reference**<\/span> | <span class=\"hljs-code\">`'Georgia', 'Times New Roman', serif`<\/span> | \u886c\u7ebf\u5b57\u4f53\uff0c\u9002\u5408\u5b66\u672f\u5f15\u7528 |\n| <span class=\"hljs-strong\">**\u4e2d\u6587\u6b63\u6587**<\/span> | <span class=\"hljs-code\">`'Source Han Serif SC', 'Noto Serif SC', 'SimSun', serif`<\/span> | \u601d\u6e90\u5b8b\u4f53\uff0c\u4f18\u96c5\u5b66\u672f\u611f |\n| <span class=\"hljs-strong\">**\u4e2d\u6587\u56fe\u8868\/\u8868\u683c**<\/span> | <span class=\"hljs-code\">`'Source Han Sans SC', 'Noto Sans SC', 'Microsoft YaHei', sans-serif`<\/span> | \u601d\u6e90\u9ed1\u4f53\uff0c\u6e05\u6670\u5c0f\u5b57\u53f7 |\n\n<span class=\"hljs-section\">### CSS \u5b57\u4f53\u8bbe\u7f6e<\/span>\n<span class=\"hljs-code\">```css\n:root {\n    --font-zh-body: 'Noto Serif SC', 'Source Han Serif SC', 'SimSun', serif;\n    --font-zh-chart: 'Noto Sans SC', 'Source Han Sans SC', 'Microsoft YaHei', sans-serif;\n    --font-zh-table: 'Noto Sans SC', 'Source Han Sans SC', 'Microsoft YaHei', sans-serif;\n}\n\n.slide-body { font-family: var(--font-zh-body); }      \/* \u6b63\u6587\u5b8b\u4f53\uff08\u5b66\u672f\uff09 *\/\n.data-table { font-family: var(--font-zh-table); }      \/* \u8868\u683c\u9ed1\u4f53\uff08\u6e05\u6670\uff09 *\/\nsvg text { font-family: 'Inter', 'Segoe UI', sans-serif; } \/* SVG \u6570\u5b57 *\/\n```<\/span>\n\n<span class=\"hljs-section\">### Google Fonts \u5f15\u5165<\/span>\n<span class=\"hljs-code\">```html\n&lt;link href=\"https:\/\/fonts.googleapis.com\/css2?family=Inter:wght@400;500;600;700&amp;family=Noto+Serif+SC:wght@400;600;700&amp;family=Noto+Sans+SC:wght@400;500;700&amp;display=swap\" rel=\"stylesheet\"&gt;\n```<\/span>\n\n---\n\n<span class=\"hljs-section\">## \u5341\u4e8c\u3001\u5173\u952e\u539f\u5219<\/span>\n<span class=\"hljs-bullet\">\n1. <\/span><span class=\"hljs-strong\">**HTML \u7ed3\u6784\u4f18\u5148**<\/span>\uff1a\u4fee\u6539\u524d\u5148\u786e\u8ba4 HTML \u5d4c\u5957\u7ed3\u6784\uff0cclosing tag \u7f3a\u5931\u4f1a\u5bfc\u81f4\u707e\u96be\u6027\u95ee\u9898\n<span class=\"hljs-bullet\">2. <\/span><span class=\"hljs-strong\">**\u5927\u5e45\u4fee\u6539\u7528\u91cd\u5199**<\/span>\uff1a\u591a\u6b21\u5c40\u90e8 edit \u4f1a\u5bfc\u81f4\u7ed3\u6784\u9519\u4e71\uff0c\u5927\u6539\u7528 <span class=\"hljs-code\">`write`<\/span> \u6574\u6587\u4ef6\n<span class=\"hljs-bullet\">3. <\/span><span class=\"hljs-strong\">**\u6d4b\u8bd5\u6bcf\u4e2a\u4fee\u6539**<\/span>\uff1a\u6bcf\u6b21\u4fee\u6539\u540e\u622a\u56fe\u9a8c\u8bc1\uff0c\u4e0d\u8981\u8fde\u7eed\u591a\u4e2a\u4fee\u6539\u540e\u518d\u6d4b\u8bd5\n<span class=\"hljs-bullet\">4. <\/span><span class=\"hljs-strong\">**\u4fdd\u7559\u5907\u4efd\u7248\u672c**<\/span>\uff1a\u6bcf\u4e2a\u7248\u672c\u5355\u72ec\u6587\u4ef6\uff0c\u65b9\u4fbf\u56de\u6eaf\n<span class=\"hljs-bullet\">5. <\/span><span class=\"hljs-strong\">**\u7edf\u4e00 presContainer \u5bbd\u5ea6**<\/span>\uff1a\u6240\u6709\u6a21\u5f0f\u4e0b presContainer \u5bbd\u5ea6\u5fc5\u987b\u4e00\u81f4\uff0c\u5426\u5219\u6587\u672c\u6362\u884c\u53d8\u5316\u5bfc\u81f4 Reference \u9875\u9762\u6761\u76ee\u6570\u91cf\u53d8\u5316\n<span class=\"hljs-bullet\">6. <\/span><span class=\"hljs-strong\">**\u7f29\u653e\u6a21\u578b\u9009\u62e9**<\/span>\uff1a\u81ea\u9002\u5e94\u6a21\u578b\uff08\u63a8\u8350\uff09\u548c\u5730\u56fe\u6a21\u578b\u4e92\u65a5\uff0c\u4e0d\u53ef\u6df7\u5408\u4f7f\u7528\n<span class=\"hljs-bullet\">7. <\/span><span class=\"hljs-strong\">**Canvas \u63a8\u8350\u6bd4\u4f8b**<\/span>\uff1a1200 \u00d7 675\uff0816:9\uff09\uff0c\u9002\u914d\u6295\u5f71\u548c\u7b14\u8bb0\u672c\u5c4f\u5e55\n<span class=\"hljs-bullet\">8. <\/span><span class=\"hljs-strong\">**\u7981\u7528\u6d4f\u89c8\u5668 zoom**<\/span>\uff1a\u81ea\u9002\u5e94\u6a21\u578b\u5fc5\u987b\u7981\u7528 Ctrl+\u6eda\u8f6e zoom\uff0c\u4e0e auto-scale \u4e92\u65a5\n<span class=\"hljs-bullet\">9. <\/span><span class=\"hljs-strong\">**\u6574\u6570\u5b57\u53f7\u9632\u5b50\u50cf\u7d20\u8bef\u5dee**<\/span>\uff1a\u7528\u6574\u6570 px \u503c\u4ee3\u66ff 14.86px \u7b49\u5206\u6570\u503c\uff0c\u6d88\u9664 zoom \u5bfc\u81f4\u7684\u56db\u820d\u4e94\u5165\u504f\u5dee\n<\/div><\/code><\/pre>\n<hr>\n<p><em>\u672c\u6587\u57fa\u4e8e opencode + deepseekv4 \u7684\u5b9e\u9645\u9879\u76ee\u7ecf\u9a8c\u64b0\u5199\u3002\u6240\u6709\u914d\u7f6e\u5df2\u5728\u5b9e\u9645 HTML \u6f14\u793a\u6587\u7a3f\u4e2d\u9a8c\u8bc1\u901a\u8fc7\u3002<\/em><\/p>\n<hr>\n<blockquote>\n<p><strong>AI \u751f\u6210\u58f0\u660e<\/strong>\uff1a\u672c\u6587\u7531 deepseek-v4-flash \u6a21\u578b\u751f\u6210\uff0c\u501f\u52a9 opencode\uff08AI Agent \u6846\u67b6\uff09\u5b8c\u6210 HTML \u8c03\u8bd5\u3001\u622a\u56fe\u5f55\u5236\u3001\u7248\u672c\u8fed\u4ee3\u4e0e\u6587\u6863\u64b0\u5199\u3002\u5168\u8fc7\u7a0b\u4eba\u673a\u534f\u4f5c\uff1a\u4eba\u7c7b\u628a\u63a7\u9700\u6c42\u4e0e\u65b9\u5411\uff0cAI \u8d1f\u8d23\u4ee3\u7801\u5b9e\u73b0\u4e0e\u6587\u6863\u8f93\u51fa\u3002<\/p>\n<\/blockquote>\n<p><\/body><br \/>\n<\/html><\/p>\n","protected":false},"excerpt":{"rendered":"<p>blog_part2_technical.md HTML \u6f14\u793a\u6587\u7a3f\u914d\u7f6e\u624b\u518c\u2014\u2014\u4ece\u63a7\u4ef6\u5230\u7f29\u653e \u57fa\u4e8e opencode + deepseekv4 \u7684\u5b9e\u8df5\u603b\u7ed3\u3002\u9002\u7528\u4e8e\u7528 AI Agent \u751f\u6210 HTML \u6f14\u793a\u6587\u7a3f\u65f6\u7684\u63a7\u4ef6","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"emotion":"","emotion_color":"","title_style":"","license":"","footnotes":""},"categories":[1],"tags":[],"class_list":["post-109","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/www.tom-thu.cn\/index.php?rest_route=\/wp\/v2\/posts\/109","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.tom-thu.cn\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tom-thu.cn\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tom-thu.cn\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tom-thu.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=109"}],"version-history":[{"count":1,"href":"https:\/\/www.tom-thu.cn\/index.php?rest_route=\/wp\/v2\/posts\/109\/revisions"}],"predecessor-version":[{"id":110,"href":"https:\/\/www.tom-thu.cn\/index.php?rest_route=\/wp\/v2\/posts\/109\/revisions\/110"}],"wp:attachment":[{"href":"https:\/\/www.tom-thu.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=109"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tom-thu.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=109"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tom-thu.cn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=109"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}