mcpField
A
ai-vibe-slides

ai-vibe-slides

github.com/unclecatvn文档处理148424 次安装2 周前更新
代码仓库

关于 ai-vibe-slides

用于生成完整幻灯片的技能,输出单个 HTML 或 React 文件,可在浏览器演示并支持打印或导出 PDF。它涵盖内容大纲、视觉方向、版式、导航及响应式和打印样式。

主要功能

  1. 01生成单文件 HTML 或 React 幻灯片
  2. 02按目标受众规划内容大纲
  3. 03选择统一的视觉风格
  4. 04支持键盘和点击导航
  5. 05设置打印与 PDF 样式

适用场景

  1. 01根据简短主题提示制作演示文稿
  2. 02制作融资路演或学术演示
  3. 03修改幻灯片内容与视觉样式
  4. 04在浏览器演示或导出文件

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/unclecatvn/agent-skills --skill ai-vibe-slides

安装后在 Claude Code 中输入/ai-vibe-slides确认已加载。

详细介绍

AI Vibe Slides — 精美 HTML 幻灯片,随时演示

目标

制作一个包含完整幻灯片的 HTML 或 React 文件,并支持:

  • 在浏览器中直接全屏演示
  • 使用方向键、空格键或鼠标点击切换幻灯片
  • 外观专业、精致且风格统一
  • 按需打印或导出为 PDF

灵感来自 banana-slides:包含 构思 → 大纲 → 完整幻灯片 的 3 步流程,但输出的是自包含的 HTML 文件,而不是全栈应用。


幻灯片制作流程

第 1 步:理解请求 → 构建大纲

用户提出请求后,先在脑中构建大纲(除非用户要求,否则无需展示):

  1. 确定主题和目标受众(学生、商务人士、技术演讲听众等)
  2. 将内容划分为逻辑清晰的部分:
    • 幻灯片 1:封面(标题 + 副标题 + 作者)
    • 幻灯片 2-3:介绍 / 背景
    • 中间部分:核心内容(每张幻灯片讲述一个关键观点)
    • 最后一张:结论 / 行动号召 / 致谢
  3. 每张幻灯片应包含:标题、2-5 个项目符号或可视化内容,以及一种布局类型

如果用户只提供一句简短描述(例如“创建关于 AI 医疗的幻灯片”),则自动扩展为结构合理的 8-12 张幻灯片。

第 2 步:选择设计方向

根据上下文,确定一个明确的设计方向:

上下文建议风格
初创公司路演幻灯片大胆、深色主题、渐变点缀、醒目的无衬线字体
学术 / 教育简洁、浅色、以图表为主、字体清晰易读
技术演讲 / 会议现代深色风格、代码风格排版、霓虹点缀
企业 / 报告简约、专业、海军蓝 / 白色、衬线标题
创意 / 营销色彩丰富、不对称布局、醒目排版
儿童 / 早期教育柔和色调、圆角、活泼图标、大号文字

通用规则:

  • 选择 2-3 种主色,并在整套幻灯片中保持一致
  • 1 种标题字体 + 1 种正文字体(使用 Google Fonts)
  • 文字精简、留白充足——每张幻灯片最多 5-6 行
  • 层次分明:大标题 → 中号正文 → 小号注释
第 3 步:生成 HTML/React 幻灯片

创建一个文件(.html 或 .jsx),包含所有内容:


HTML 幻灯片结构

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>{Presentation Title}</title>
    <link
      href="https://fonts.googleapis.com/css2?family={Font1}&family={Font2}&display=swap"
      rel="stylesheet"
    />
    <style>
      /* === RESET + BASE === */
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }

      /* === SLIDE CONTAINER === */
      .slide-deck {
        width: 100vw;
        height: 100vh;
        overflow: hidden;
        position: relative;
      }
      .slide {
        width: 100%;
        height: 100%;
        display: none;
        flex-direction: column;
        justify-content: center;
        padding: 60px 80px;
        position: absolute;
        top: 0;
        left: 0;
      }
      .slide.active {
        display: flex;
      }

      /* === TYPOGRAPHY === */
      h1 {
        font-family: "{Font1}", sans-serif;
        font-size: 3.2rem;
        margin-bottom: 1rem;
      }
      h2 {
        font-family: "{Font1}", sans-serif;
        font-size: 2.4rem;
        margin-bottom: 1.5rem;
      }
      p,
      li {
        font-family: "{Font2}", sans-serif;
        font-size: 1.4rem;
        line-height: 1.8;
      }

      /* === THEME COLORS === */
      :root {
        --bg-primary: #0f172a;
        --bg-slide: #1e293b;
        --text-primary: #f8fafc;
        --text-secondary: #94a3b8;
        --accent: #3b82f6;
        --accent-2: #8b5cf6;
      }

      /* === NAVIGATION UI === */
      .nav-hint {
        position: fixed;
        bottom: 20px;
        right: 30px;
        font-size: 0.8rem;
        color: var(--text-secondary);
        opacity: 0.5;
      }
      .slide-counter {
        position: fixed;
        bottom: 20px;
        left: 30px;
        font-size: 0.8rem;
        color: var(--text-secondary);
      }

      /* === TRANSITIONS === */
      .slide {
        animation: fadeIn 0.4s ease;
      }
      @keyframes fadeIn {
        from {
          opacity: 0;
          transform: translateY(10px);
        }
        to {
          opacity: 1;
          transform: translateY(0);
        }
      }

      /* === LAYOUT VARIANTS === */
      .slide.cover {
        justify-content: center;
        align-items: center;
        text-align: center;
      }
      .slide.two-column {
        flex-direction: row;
        gap: 60px;
        align-items: center;
      }
      .slide.two-column .col {
        flex: 1;
      }
      .slide.centered {
        align-items: center;
        text-align: center;
      }

      /* === VISUAL ELEMENTS === */
      .card {
        background: rgba(255, 255, 255, 0.05);
        border-radius: 12px;
        padding: 24px;
        margin: 8px 0;
      }
      .badge {
        display: inline-block;
        background: var(--accent);
        color: white;
        padding: 4px 14px;
        border-radius: 20px;
        font-size: 0.85rem;
      }
      .divider {
        width: 60px;
        height: 4px;
        background: var(--accent);
        border-radius: 2px;
        margin: 16px 0;
      }
      .icon-grid {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
        gap: 20px;
      }

      /* === PRINT / PDF EXPORT === */
      @media print {
        .slide {
          page-break-after: always;
          display: flex !important;
          position: relative;
        }
        .nav-hint,
        .slide-counter {
          display: none;
        }
      }
    </style>
  </head>
  <body>
    <div class="slide-deck" id="deck">
      
      <div
        class="slide cover active"
        style="background: linear-gradient(135deg, var(--bg-primary), #1a1a2e);"
      >
        <div class="badge">Topic</div>
        <h1 style="font-size: 3.8rem; margin-top: 20px;">Main Title</h1>
        <p
          style="color: var(--text-secondary); font-size: 1.3rem; margin-top: 12px;"
        >
          Short subtitle description
        </p>
        <div class="divider" style="margin: 20px auto;"></div>
        <p style="color: var(--text-secondary); font-size: 1rem;">
          Author — Date
        </p>
      </div>

      
      <div class="slide">
        <h2>Slide Title</h2>
        <div class="divider"></div>
        <ul>
          <li>Key point 1</li>
          <li>Key point 2</li>
          <li>Key point 3</li>
        </ul>
      </div>

      
    </div>

    <div class="slide-counter">
      <span id="current">1</span> / <span id="total"></span>
    </div>
    <div class="nav-hint">← → or click to navigate</div>

    <script>
      const slides = document.querySelectorAll(".slide");
      let currentSlide = 0;
      document.getElementById("total").textContent = slides.length;

      function showSlide(n) {
        slides[currentSlide].classList.remove("active");
        currentSlide = (n + slides.length) % slides.length;
        slides[currentSlide].classList.add("active");
        document.getElementById("current").textContent = currentSlide + 1;
      }

      document.addEventListener("keydown", (e) => {
        if (e.key === "ArrowRight" || e.key === " ")
          showSlide(currentSlide + 1);
        if (e.key === "ArrowLeft") showSlide(currentSlide - 1);
        if (e.key === "f") document.documentElement.requestFullscreen?.();
        if (e.key === "Escape") document.exitFullscreen?.();
      });

      document.querySelector(".slide-deck").addEventListener("click", (e) => {
        const x = e.clientX / window.innerWidth;
        x > 0.5 ? showSlide(currentSlide + 1) : showSlide(currentSlide - 1);
      });
    </script>
  </body>
</html>

幻灯片布局类型

每张幻灯片应采用最适合其内容的布局:

1. 封面
  • 居中、超大字号、渐变背景
  • 主题徽标 + 主标题 + 副标题 + 作者
2. 章节分隔页
  • 仅显示章节标题 + 编号,背景使用强调色
  • 用于分隔演示文稿的主要章节
3. 内容 + 项目符号
  • 左对齐标题 + 关键要点列表
  • 每个项目符号开头使用图标 / 表情符号,而不是普通圆点
4. 双栏
  • .two-column 布局:左侧为文字,右侧为可视化内容 / 列表 / 卡片
  • 适合用于对比、前后对照、文字 + 插图
5. 卡片网格
  • 2-3 列网格,每张卡片包含图标 + 标题 + 简短说明
  • 适合展示功能、优势、团队成员
6. 大数字 / 统计数据
  • 居中显示超大数字(font-size: 5rem+)+ 下方的小号标签
  • 适合展示数据点、KPI、影响力数据
7. 引言 / 强调内容
  • 大号文字、居中显示,并配以装饰性引号
  • 使用不同背景(浅色强调色)
8. 时间线 / 步骤
  • 使用水平或垂直的 flexbox 布局,并用圆点连接各步骤
  • 适合展示流程、路线图、历史
9. 致谢 / 行动号召
  • 居中、简洁,包含联系信息或行动号召

强制设计规则

  1. 16:9 宽高比:始终使用 width: 100vw; height: 100vh——每张幻灯片都铺满整个屏幕
  2. 精简文本:每张幻灯片最多 6 行。如果内容较长 → 拆分成多张幻灯片
  3. 大字号:标题 ≥ 2.4rem,正文 ≥ 1.3rem——确保在投影仪上清晰可读
  4. 高对比度:文本与背景之间必须有清晰的可读性。请进行视觉检查
  5. 保持一致:整个演示文稿使用相同的字体、配色方案和间距
  6. 禁止使用占位图片:切勿使用 <img src="placeholder">。请改用 CSS 图形、渐变、图标(emoji 或适用于 React 的 Lucide)或内联 SVG
  7. 轻微动画:幻灯片切换时仅使用 fadeIn。不要使用会分散注意力的复杂动画
  8. 响应式全屏:必须在各种屏幕尺寸下都能良好显示
  9. 适合打印:添加 @media print 规则,使每张幻灯片单独打印为一页

使用 React(.jsx)而非 HTML 时

如果创建 React 产物,请使用以下模式:

import { useState, useEffect, useCallback } from "react";

const slides = [
  { type: "cover", title: "...", subtitle: "..." },
  { type: "content", title: "...", points: ["...", "..."] },
  { type: "twoColumn", title: "...", left: "...", right: "..." },
  // ...
];

export default function SlideDeck() {
  const [current, setCurrent] = useState(0);

  const next = useCallback(
    () => setCurrent((c) => (c + 1) % slides.length),
    [],
  );
  const prev = useCallback(
    () => setCurrent((c) => (c - 1 + slides.length) % slides.length),
    [],
  );

  useEffect(() => {
    const handleKey = (e) => {
      if (e.key === "ArrowRight" || e.key === " ") next();
      if (e.key === "ArrowLeft") prev();
      if (e.key === "f") document.documentElement.requestFullscreen?.();
    };
    window.addEventListener("keydown", handleKey);
    return () => window.removeEventListener("keydown", handleKey);
  }, [next, prev]);

  const renderSlide = (slide) => {
    switch (slide.type) {
      case "cover":
        return /* cover layout */;
      case "content":
        return /* content layout */;
      case "twoColumn":
        return /* two-column layout */;
      // ...
    }
  };

  return (
    <div
      className="w-screen h-screen overflow-hidden relative"
      onClick={(e) => (e.clientX > window.innerWidth / 2 ? next() : prev())}
      style={{ fontFamily: "'Outfit', sans-serif" }}
    >
      {renderSlide(slides[current])}
      <div className="fixed bottom-5 left-8 text-sm opacity-40">
        {current + 1} / {slides.length}
      </div>
    </div>
  );
}

React 的优势:Tailwind CSS 工具类、Lucide 图标、更复杂的逻辑,以及用于图表的 recharts。


交付前检查清单

  • 幻灯片数量正确(封面 + 内容页 + 结束页)
  • 方向键 ← → 可用,点击可切换
  • 计数器显示正确的“X / N”
  • 按 F 可进入全屏
  • 所有文本都清晰可读且对比度充足
  • 没有损坏的图片或占位内容
  • Google Fonts 加载正常(或使用合适的备用字体)
  • 打印/PDF 导出正常(@media print)
  • 整个演示文稿风格一致
  • 每张幻灯片恰好呈现一个核心观点,避免文本过载

自然语言编辑

初次创建后,用户可以提出修改要求:

  • “切换为浅色主题” → 更新 CSS 变量
  • “添加 2 张关于案例研究的幻灯片” → 将幻灯片插入数组
  • “第 3 张幻灯片文字太多了,把它拆开” → 将内容重新分配到多张幻灯片
  • “将字体改为 Playfair Display” → 更新 Google Fonts 链接和 CSS
  • “在第 5 张幻灯片中添加图表” → 使用 CSS 图表或 recharts(React)

每次编辑时,保持未修改的幻灯片不变,仅更新用户要求修改的内容。

评论

支持 Markdown