From 17c56bc8b56e377475f293e87f7a08eba5e54591 Mon Sep 17 00:00:00 2001 From: jingrow Date: Wed, 3 Sep 2025 17:05:07 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B8=85=E9=99=A4Presentation=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E8=B0=83=E8=AF=95=E6=97=A5=E5=BF=97=E5=92=8C=E6=B3=A8?= =?UTF-8?q?=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/presentation/Presentation.jsx | 27 +- components/presentation/themes/jingrow.css | 378 ++++++++++++++++----- data/presentation/jingrow.md | 5 +- 3 files changed, 298 insertions(+), 112 deletions(-) diff --git a/components/presentation/Presentation.jsx b/components/presentation/Presentation.jsx index 671d47d..73e0e05 100644 --- a/components/presentation/Presentation.jsx +++ b/components/presentation/Presentation.jsx @@ -5,28 +5,20 @@ import Reveal from 'reveal.js'; import 'reveal.js/dist/reveal.css'; import { marked } from 'marked'; -// 简单的动态主题加载器 const loadTheme = async (themeName) => { if (!themeName) return; try { - // 1. 优先尝试加载自定义主题 await import(`./themes/${themeName}.css`); - console.log(`加载自定义主题: ${themeName}`); } catch (error) { try { - // 2. 尝试加载 Reveal.js 内置主题 await import(`reveal.js/dist/theme/${themeName}.css`); - console.log(`加载内置主题: ${themeName}`); } catch (error2) { - // 3. 如果都失败,使用默认主题 - console.warn(`主题 ${themeName} 未找到,使用默认主题`); await import('reveal.js/dist/theme/black.css'); } } }; -// Reveal.js配置 const REVEAL_CONFIG = { hash: true, transition: 'slide', @@ -65,7 +57,6 @@ const REVEAL_CONFIG = { plugins: [] }; -// 配置marked解析器(只配置一次) marked.setOptions({ breaks: true, gfm: true, @@ -79,32 +70,26 @@ export default function Presentation({ data }) { const [mounted, setMounted] = useState(false); const [error, setError] = useState(null); - // 客户端挂载检测 useEffect(() => { setMounted(true); }, []); - // 解析Markdown内容为幻灯片 const parseMarkdownToSlides = useCallback((data) => { if (!data) { return `

演示文稿

暂无内容

`; } try { - // 如果有 content 字段,直接使用 markdown 内容 if (data.content) { return parseContentSlides(data); } - // 如果没有 content 字段,返回默认内容 return `

${data.title || '演示文稿'}

暂无内容

`; } catch (err) { - console.error('解析幻灯片内容失败:', err); return `

解析错误

内容解析失败,请检查数据格式

`; } }, []); - // 解析content字段的幻灯片 const parseContentSlides = (data) => { const slideSeparators = /^---$/gm; const sections = data.content.split(slideSeparators); @@ -113,7 +98,6 @@ export default function Presentation({ data }) { const trimmedSection = section.trim(); if (!trimmedSection) return ''; - // 检查是否有背景设置 const backgroundMatch = trimmedSection.match(//); let backgroundAttr = ''; let contentWithoutBackground = trimmedSection; @@ -125,7 +109,6 @@ export default function Presentation({ data }) { const htmlContent = marked(contentWithoutBackground); - // 如果是第一个幻灯片且没有标题,添加标题 if (index === 0 && !htmlContent.includes('

') && data.title) { return `

${data.title}

${htmlContent}`; } @@ -134,25 +117,20 @@ export default function Presentation({ data }) { }).join(''); }; - // 初始化Reveal.js const initializeReveal = useCallback(async () => { if (!deckRef.current || !data) return; try { - // 清理之前的实例 if (revealRef.current) { revealRef.current.destroy(); } - // 动态加载主题 const themeName = data.theme || 'default'; await loadTheme(themeName); - // 创建新实例 revealRef.current = new Reveal(deckRef.current, REVEAL_CONFIG); revealRef.current.initialize(); - // 更新slides内容 const slides = parseMarkdownToSlides(data); const slidesContainer = deckRef.current.querySelector('.slides'); if (slidesContainer) { @@ -165,7 +143,6 @@ export default function Presentation({ data }) { } }, [data, parseMarkdownToSlides]); - // 数据变化时重新初始化 useEffect(() => { if (mounted && data) { initializeReveal(); @@ -178,7 +155,6 @@ export default function Presentation({ data }) { }; }, [mounted, data, initializeReveal]); - // 错误状态 if (error) { return (
@@ -196,11 +172,10 @@ export default function Presentation({ data }) { ); } - // 加载状态 if (!mounted) { return (
-
正在加载PPT...
+
正在加载内容...
); } diff --git a/components/presentation/themes/jingrow.css b/components/presentation/themes/jingrow.css index a7f602c..1299456 100644 --- a/components/presentation/themes/jingrow.css +++ b/components/presentation/themes/jingrow.css @@ -1,12 +1,12 @@ /* Jingrow 自定义主题 */ -@import url('https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600;700&display=swap'); +@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@400;500;600;700&family=Manrope:wght@400;500;600;700&display=swap'); .jingrow-icon { display: inline-block; width: 1.5em; height: 1.5em; vertical-align: middle; - margin-right: 0.5em; + margin-right: 0.2em; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' version='1.1' viewBox='0.00 0.00 128.00 128.00'%3E%3Cg stroke-width='2.00' fill='none' stroke-linecap='butt'%3E%3Cpath stroke='%238fe3b1' vector-effect='non-scaling-stroke' d='M 64.04 34.07 Q 64.93 34.07 65.55 34.69 Q 74.55 43.60 82.91 51.96 C 87.46 56.52 91.92 55.95 98.45 55.81 A 2.52 2.52 0.0 0 0 100.92 53.29 L 100.92 49.89 A 2.56 2.55 -1.5 0 0 98.23 47.34 C 95.84 47.46 91.15 47.62 89.22 45.67 Q 81.61 37.99 68.36 24.99 Q 66.43 23.09 64.04 23.09 Q 61.66 23.09 59.72 24.99 Q 46.47 37.98 38.85 45.66 C 36.92 47.61 32.23 47.45 29.84 47.32 A 2.56 2.55 1.5 0 0 27.15 49.87 L 27.15 53.27 A 2.52 2.52 0.0 0 0 29.62 55.79 C 36.15 55.94 40.61 56.51 45.16 51.95 Q 53.53 43.60 62.53 34.69 Q 63.15 34.07 64.04 34.07'%3E%3C/path%3E%3Cpath stroke='%238fe3b1' vector-effect='non-scaling-stroke' d='M 64.04 101.46 C 66.42 101.46 68.47 101.10 68.47 98.24 Q 68.49 75.28 68.49 72.56 A 0.61 0.61 0.0 0 1 69.10 71.95 L 89.64 71.95 A 2.50 2.50 0.0 0 0 92.14 69.45 L 92.14 65.73 A 2.28 2.28 0.0 0 0 89.86 63.45 L 69.10 63.45 A 0.61 0.61 0.0 0 1 68.49 62.84 L 68.49 50.37 A 3.05 3.03 2.1 0 0 65.67 47.34 Q 65.14 47.31 64.03 47.31 Q 62.93 47.31 62.40 47.34 A 3.05 3.03 -2.1 0 0 59.58 50.37 L 59.58 62.84 A 0.61 0.61 0.0 0 1 58.97 63.45 L 38.21 63.45 A 2.28 2.28 0.0 0 0 35.93 65.73 L 35.93 69.45 A 2.50 2.50 0.0 0 0 38.43 71.95 L 58.97 71.95 A 0.61 0.61 0.0 0 1 59.58 72.56 Q 59.58 75.28 59.60 98.24 C 59.60 101.10 61.65 101.46 64.04 101.46'%3E%3C/path%3E%3C/g%3E%3Cpath fill='%231fc76f' d='M 115.34 95.08 A 19.82 19.82 0.0 0 1 95.52 114.90 L 32.48 114.90 A 19.82 19.82 0.0 0 1 12.66 95.08 L 12.66 32.88 A 19.82 19.82 0.0 0 1 32.48 13.06 L 95.52 13.06 A 19.82 19.82 0.0 0 1 115.34 32.88 L 115.34 95.08 Z M 64.04 34.07 Q 64.93 34.07 65.55 34.69 Q 74.55 43.60 82.91 51.96 C 87.46 56.52 91.92 55.95 98.45 55.81 A 2.52 2.52 0.0 0 0 100.92 53.29 L 100.92 49.89 A 2.56 2.55 -1.5 0 0 98.23 47.34 C 95.84 47.46 91.15 47.62 89.22 45.67 Q 81.61 37.99 68.36 24.99 Q 66.43 23.09 64.04 23.09 Q 61.66 23.09 59.72 24.99 Q 46.47 37.98 38.85 45.66 C 36.92 47.61 32.23 47.45 29.84 47.32 A 2.56 2.55 1.5 0 0 27.15 49.87 L 27.15 53.27 A 2.52 2.52 0.0 0 0 29.62 55.79 C 36.15 55.94 40.61 56.51 45.16 51.95 Q 53.53 43.60 62.53 34.69 Q 63.15 34.07 64.04 34.07 Z M 64.04 101.46 C 66.42 101.46 68.47 101.10 68.47 98.24 Q 68.49 75.28 68.49 72.56 A 0.61 0.61 0.0 0 1 69.10 71.95 L 89.64 71.95 A 2.50 2.50 0.0 0 0 92.14 69.45 L 92.14 65.73 A 2.28 2.28 0.0 0 0 89.86 63.45 L 69.10 63.45 A 0.61 0.61 0.0 0 1 68.49 62.84 L 68.49 50.37 A 3.05 3.03 2.1 0 0 65.67 47.34 Q 65.14 47.31 64.03 47.31 Q 62.93 47.31 62.40 47.34 A 3.05 3.03 -2.1 0 0 59.58 50.37 L 59.58 62.84 A 0.61 0.61 0.0 0 1 58.97 63.45 L 38.21 63.45 A 2.28 2.28 0.0 0 0 35.93 65.73 L 35.93 69.45 A 2.50 2.50 0.0 0 0 38.43 71.95 L 58.97 71.95 A 0.61 0.61 0.0 0 1 59.58 72.56 Q 59.58 75.28 59.60 98.24 C 59.60 101.10 61.65 101.46 64.04 101.46 Z'%3E%3C/path%3E%3Cpath fill='%23fffef2' d='M 64.04 23.09 Q 66.43 23.09 68.36 24.99 Q 81.61 37.99 89.22 45.67 C 91.15 47.62 95.84 47.46 98.23 47.34 A 2.56 2.55 -1.5 0 1 100.92 49.89 L 100.92 53.29 A 2.52 2.52 0.0 0 1 98.45 55.81 C 91.92 55.95 87.46 56.52 82.91 51.96 Q 74.55 43.60 65.55 34.69 Q 64.93 34.07 64.04 34.07 Q 63.15 34.07 62.53 34.69 Q 53.53 43.60 45.16 51.95 C 40.61 56.51 36.15 55.94 29.62 55.79 A 2.52 2.52 0.0 0 1 27.15 53.27 L 27.15 49.87 A 2.56 2.55 1.5 0 1 29.84 47.32 C 32.23 47.45 36.92 47.61 38.85 45.66 Q 46.47 37.98 59.72 24.99 Q 61.66 23.09 64.04 23.09 Z'%3E%3C/path%3E%3Cpath fill='%23fffef2' d='M 64.03 47.31 Q 65.14 47.31 65.67 47.34 A 3.05 3.03 2.1 0 1 68.49 50.37 L 68.49 62.84 A 0.61 0.61 0.0 0 0 69.10 63.45 L 89.86 63.45 A 2.28 2.28 0.0 0 1 92.14 65.73 L 92.14 69.45 A 2.50 2.50 0.0 0 1 89.64 71.95 L 69.10 71.95 A 0.61 0.61 0.0 0 0 68.49 72.56 Q 68.49 75.28 68.47 98.24 C 68.47 101.10 66.42 101.46 64.04 101.46 C 61.65 101.46 59.60 101.10 59.60 98.24 Q 59.58 75.28 59.58 72.56 A 0.61 0.61 0.0 0 0 58.97 71.95 L 38.43 71.95 A 2.50 2.50 0.0 0 1 35.93 69.45 L 35.93 65.73 A 2.28 2.28 0.0 0 1 38.21 63.45 L 58.97 63.45 A 0.61 0.61 0.0 0 0 59.58 62.84 L 59.58 50.37 A 3.05 3.03 -2.1 0 1 62.40 47.34 Q 62.93 47.31 64.03 47.31 Z'%3E%3C/path%3E%3C/svg%3E"); background-repeat: no-repeat; background-size: contain; @@ -17,67 +17,247 @@ height: 2em; } -.reveal { - font-family: 'Manrope', sans-serif; - font-size: 24px; - color: #ffffff; + +section.has-dark-background, section.has-dark-background h1, section.has-dark-background h2, section.has-dark-background h3, section.has-dark-background h4, section.has-dark-background h5, section.has-dark-background h6 { + color: #fff; } +/********************************************* + * GLOBAL STYLES + *********************************************/ +:root { + --r-background-color: #fff; + --r-main-font: "Noto Sans SC", Manrope, Helvetica, sans-serif; + --r-main-font-size: 42px; + --r-main-color: #222; + --r-block-margin: 20px; + --r-heading-margin: 0 0 20px 0; + --r-heading-font: "Noto Sans SC", Manrope, Helvetica, sans-serif; + --r-heading-color: #222; + --r-heading-line-height: 1.2; + --r-heading-letter-spacing: normal; + --r-heading-text-transform: none; + --r-heading-text-shadow: none; + --r-heading-font-weight: 700; + --r-heading1-text-shadow: none; + --r-heading1-size: 2.5em; + --r-heading2-size: 1.6em; + --r-heading3-size: 1.3em; + --r-heading4-size: 1em; + --r-code-font: monospace; + --r-link-color: #2a76dd; + --r-link-color-dark: rgb(30.7720647773, 99.5566801619, 192.7779352227); + --r-link-color-hover: rgb(73.95, 138.55, 226.1); + --r-selection-background-color: rgb(95.25, 152.25, 229.5); + --r-selection-color: #fff; + --r-overlay-element-bg-color: 0, 0, 0; + --r-overlay-element-fg-color: 240, 240, 240; +} + +.reveal-viewport { + background: #fff; + background-color: var(--r-background-color); +} + +.reveal { + font-family: var(--r-main-font); + font-size: var(--r-main-font-size); + font-weight: normal; + color: var(--r-main-color); +} + +.reveal ::selection { + color: var(--r-selection-color); + background: var(--r-selection-background-color); + text-shadow: none; +} + +.reveal ::-moz-selection { + color: var(--r-selection-color); + background: var(--r-selection-background-color); + text-shadow: none; +} + +.reveal .slides section, +.reveal .slides section > section { + line-height: 1.3; + font-weight: inherit; +} + +/********************************************* + * HEADERS + *********************************************/ .reveal h1, .reveal h2, .reveal h3, .reveal h4, .reveal h5, .reveal h6 { - font-family: 'Manrope', sans-serif; - font-weight: 600; - color: #1fc76f; - text-transform: none; - text-shadow: none; - margin: 0 0 20px 0; + margin: var(--r-heading-margin); + color: var(--r-heading-color); + font-family: var(--r-heading-font); + font-weight: var(--r-heading-font-weight); + line-height: var(--r-heading-line-height); + letter-spacing: var(--r-heading-letter-spacing); + text-transform: var(--r-heading-text-transform); + text-shadow: var(--r-heading-text-shadow); + word-wrap: break-word; } .reveal h1 { - font-size: 3.5em; - color: #1fc76f; + font-size: var(--r-heading1-size); +} + +.reveal h1 { + display: flex; + align-items: center; + justify-content: center; } .reveal h2 { - font-size: 2.5em; - color: #8fe3b1; + font-size: var(--r-heading2-size); } .reveal h3 { - font-size: 1.8em; - color: #8fe3b1; + font-size: var(--r-heading3-size); } +.reveal h4 { + font-size: var(--r-heading4-size); +} + +.reveal h1 { + text-shadow: var(--r-heading1-text-shadow); +} + +/********************************************* + * OTHER + *********************************************/ .reveal p { - margin: 20px 0; - line-height: 1.6; + margin: var(--r-block-margin) 0; + line-height: 1.3; +} + +/* Remove trailing margins after titles */ +.reveal h1:last-child, +.reveal h2:last-child, +.reveal h3:last-child, +.reveal h4:last-child, +.reveal h5:last-child, +.reveal h6:last-child { + margin-bottom: 0; +} + +/* Ensure certain elements are never larger than the slide itself */ +.reveal img, +.reveal video, +.reveal iframe { + max-width: 95%; + max-height: 95%; +} + +.reveal strong, +.reveal b { + font-weight: bold; +} + +.reveal em { + font-style: italic; +} + +.reveal ol, +.reveal dl, +.reveal ul { + display: inline-block; + text-align: left; + margin: 0 0 0 1em; } -.reveal ul, .reveal ol { - display: block; - margin: 20px 0; - padding-left: 40px; + list-style-type: decimal; } -.reveal li { - margin: 10px 0; - line-height: 1.6; +.reveal ul { + list-style-type: disc; +} + +.reveal ul ul { + list-style-type: square; +} + +.reveal ul ul ul { + list-style-type: circle; +} + +.reveal ul ul, +.reveal ul ol, +.reveal ol ol, +.reveal ol ul { + display: block; + margin-left: 40px; +} + +.reveal dt { + font-weight: bold; +} + +.reveal dd { + margin-left: 40px; } .reveal blockquote { display: block; position: relative; width: 70%; - margin: 20px auto; - padding: 5px 20px; + margin: var(--r-block-margin) auto; + padding: 5px; font-style: italic; - background: rgba(31, 199, 111, 0.1); - border-left: 4px solid #1fc76f; + background: rgba(255, 255, 255, 0.05); + box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2); +} + +.reveal blockquote p:first-child, +.reveal blockquote p:last-child { + display: inline-block; +} + +.reveal q { + font-style: italic; +} + +.reveal pre { + display: block; + position: relative; + width: 90%; + margin: var(--r-block-margin) auto; + text-align: left; + font-size: 0.55em; + font-family: var(--r-code-font); + line-height: 1.2em; + word-wrap: break-word; + box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15); +} + +.reveal code { + font-family: var(--r-code-font); + text-transform: none; + tab-size: 2; +} + +.reveal pre code { + display: block; + padding: 5px; + overflow: auto; + max-height: 400px; + word-wrap: normal; +} + +.reveal .code-wrapper { + white-space: normal; +} + +.reveal .code-wrapper code { + white-space: pre; } .reveal table { @@ -88,80 +268,112 @@ .reveal table th { font-weight: bold; - color: #1fc76f; } .reveal table th, .reveal table td { text-align: left; padding: 0.2em 0.5em 0.2em 0.5em; - border-bottom: 1px solid #666; + border-bottom: 1px solid; +} + +.reveal table th[align=center], +.reveal table td[align=center] { + text-align: center; +} + +.reveal table th[align=right], +.reveal table td[align=right] { + text-align: right; +} + +.reveal table tbody tr:last-child th, +.reveal table tbody tr:last-child td { + border-bottom: none; +} + +.reveal sup { + vertical-align: super; + font-size: smaller; +} + +.reveal sub { + vertical-align: sub; + font-size: smaller; +} + +.reveal small { + display: inline-block; + font-size: 0.6em; + line-height: 1.2em; + vertical-align: top; +} + +.reveal small * { + vertical-align: top; } .reveal img { - margin: 15px 0px; - background: rgba(255, 255, 255, 0.12); - border: 4px solid #1fc76f; - box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); + margin: var(--r-block-margin) 0; } +/********************************************* + * LINKS + *********************************************/ .reveal a { - color: #8fe3b1; + color: var(--r-link-color); text-decoration: none; transition: color 0.15s ease; } .reveal a:hover { - color: #1fc76f; + color: var(--r-link-color-hover); text-shadow: none; border: none; } -.reveal pre { - display: block; - position: relative; - width: 90%; - margin: 15px auto; - text-align: left; - font-size: 0.55em; - font-family: 'Courier New', monospace; - line-height: 1.2em; - word-wrap: break-word; - box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3); -} - -.reveal code { - font-family: 'Courier New', monospace; - text-transform: none; - color: #1fc76f; - background: rgba(31, 199, 111, 0.1); - padding: 2px 4px; - border-radius: 3px; -} - -.reveal pre code { - display: block; - padding: 5px; - overflow: auto; - max-height: 400px; - word-wrap: normal; - background: #2d2d2d; - color: #f8f8f2; -} - -.reveal .slides section { - text-align: center; -} - -.reveal .slides section[data-background] { +.reveal .roll span:after { color: #fff; + background: var(--r-link-color-dark); } -.reveal .slides section[data-background] h1, -.reveal .slides section[data-background] h2, -.reveal .slides section[data-background] h3, -.reveal .slides section[data-background] h4, -.reveal .slides section[data-background] h5, -.reveal .slides section[data-background] h6 { - color: #fff; +/********************************************* + * Frame helper + *********************************************/ +.reveal .r-frame { + border: 4px solid var(--r-main-color); + box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); } + +.reveal a .r-frame { + transition: all 0.15s linear; +} + +.reveal a:hover .r-frame { + border-color: var(--r-link-color); + box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); +} + +/********************************************* + * NAVIGATION CONTROLS + *********************************************/ +.reveal .controls { + color: var(--r-link-color); +} + +/********************************************* + * PROGRESS BAR + *********************************************/ +.reveal .progress { + background: rgba(0, 0, 0, 0.2); + color: var(--r-link-color); +} + +/********************************************* + * PRINT BACKGROUND + *********************************************/ +@media print { + .backgrounds { + background-color: var(--r-background-color); + } +} \ No newline at end of file diff --git a/data/presentation/jingrow.md b/data/presentation/jingrow.md index 0c1d208..45ccfef 100644 --- a/data/presentation/jingrow.md +++ b/data/presentation/jingrow.md @@ -4,10 +4,9 @@ backgroundTransition: slide transition: slide --- -# Jingrow
一站式通用企业数字化平台 - +# Jingrow +## 一站式通用企业数字化平台 ### 下一代智能工作平台 - *让企业数字化变得简单而强大* ---