mcpField
I
instagram-carousel

instagram-carousel

github.com/marcolang营销与增长67824 次安装29 周前更新
代码仓库

关于 instagram-carousel

instagram-carousel 是一项生成 Instagram 轮播图 HTML 预览与导出素材的技能,面向制作社交媒体内容的创作者。它指导品牌风格、幻灯片序列和交互预览,并要求先审核预览获批后再导出单页 PNG。

主要功能

  1. 01生成可独立使用的轮播 HTML
  2. 02支持多种幻灯片序列
  3. 03按品牌色与字体设置视觉样式
  4. 04支持图片嵌入和滑动预览
  5. 05审核通过后导出单页 PNG

适用场景

  1. 01制作 Instagram 教程轮播
  2. 02设计产品功能介绍轮播
  3. 03制作清单或比较类内容
  4. 04将审核后的幻灯片导出为 PNG

安装

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

$npx skills add https://github.com/marcolang/marketing-skills --skill instagram-carousel

安装后在 Claude Code 中输入/instagram-carousel确认已加载。

附带文件.claude/settings.json

详细介绍

Instagram 轮播图生成器

生成完全自包含、可滑动的 HTML 轮播图,每张幻灯片都设计为可导出为单张 1080×1350px 的 Instagram PNG 图片。


步骤 1:收集品牌详情

生成前,询问用户以下信息(如果尚未提供):

  1. 品牌名称 — 显示在首张和末张幻灯片上
  2. Instagram 用户名 — 显示在 IG 帧标题中
  3. 品牌主色 — 十六进制代码,或由用户描述并让 Claude 选择
  4. Logo — SVG 路径、品牌首字母,或跳过
  5. 字体偏好 — 参见下方的排版表,或指定 Google Fonts
  6. 语气 — 专业、随意、活泼、大胆、极简等
  7. 图片 — 头像、截图、产品图片等
  8. 幻灯片语言 — 默认:葡萄牙语(巴西),除非另有指定
  9. 轮播图格式 — 标准格式(7 张幻灯片)或其他顺序(参见序列部分)

如果用户提供了网站 URL 或品牌素材,请据此提取配色和风格。

如果用户只说“给我做一个关于 X 的轮播图”,却没有提供品牌详情,请先询问,不要自行假设默认值。


处理用户提供的图片

本节从首次生成 HTML 时就适用,不只适用于导出期间。

用户提供图片文件路径时(例如 /home/user/gestante.png、/mnt/user-data/uploads/foto.jpg):

⚠️ 关键规则
  1. 绝不要使用相对路径(gestante.png)——除 HTML 所在的确切文件夹外,在其他所有浏览器环境中都会失效。
  2. 绝不要使用 background: url(filepath)——这会导致生成 1.5MB 以上的 base64 内联字符串,令浏览器解析器崩溃。
  3. 始终将图片嵌入为 base64 data: URI——在预览、导出和任何环境中都能正常工作。
  4. 始终通过 Python 生成 HTML(使用 Path.write_text())——Shell heredoc 会插入 $ 和反引号,破坏 base64 字符串。
分步说明:嵌入图片
# 1. Check the actual file format (extension may lie)
file /path/to/image.png
import base64
from pathlib import Path

# 2. Read and encode
img_path = Path("/path/to/image.png")
# Use "image/jpeg" if `file` command says JPEG, else "image/png"
mime = "image/jpeg"  # or "image/png"
b64 = base64.b64encode(img_path.read_bytes()).decode()
data_uri = f"data:{mime};base64,{b64}"

# 3. Inject into HTML template as a Python variable — never via shell
html = f"""
<div style="position:relative;width:100%;height:100%;">
  <img src="{data_uri}"
       style="position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:0;">
  <div style="position:absolute;inset:0;background:rgba(255,255,255,0.35);z-index:1;"></div>
  
</div>
"""

Path("/home/claude/carousel.html").write_text(html, encoding="utf-8")
将图片用作幻灯片背景(最常见的用法)

<img src="{data_uri}"
     style="position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:0;">

<div style="position:absolute;inset:0;background:rgba(255,255,255,0.35);z-index:1;"></div>

对于深色幻灯片,请改用 rgba(0,0,0,0.45) 作为叠加层。

应避免的常见图片错误
错误后果修复方法
<img src="gestante.png">图片损坏——相对路径仅在 HTML 和图片位于同一文件夹时有效始终使用 base64 data: URI
内联使用带有 1.5MB base64 的 background: url('data:...')浏览器解析器崩溃,1.3M token 上下文使用带有 object-fit:cover 的 <img> 标签
通过 Shell echo 或 heredoc 生成 HTMLbase64 中的 $ 和反引号会被插入,破坏字符串始终使用 Python Path.write_text()
认定 .png 扩展名就代表 PNG 格式文件可能实际是 JPEG;错误的 MIME 类型会导致渲染失败运行 file 命令检测实际格式

步骤 2:推导完整配色系统

根据用户提供的单一品牌主色,生成包含 6 个 token 的完整调色板:

BRAND_PRIMARY   = {user's color}                    // Main accent — progress bar, icons, tags
BRAND_LIGHT     = {primary lightened ~20%}           // Secondary accent — tags on dark, pills
BRAND_DARK      = {primary darkened ~30%}            // CTA text, gradient anchor
LIGHT_BG        = {warm or cool off-white}           // Light slide background (never pure #fff)
LIGHT_BORDER    = {slightly darker than LIGHT_BG}    // Dividers on light slides
DARK_BG         = {near-black with brand tint}       // Dark slide background

颜色推导规则:

  • LIGHT_BG:与主色协调的浅色灰白色(暖色 → 暖奶油色,冷色 → 冷灰白)
  • DARK_BG:带有细微品牌色调的近黑色(暖色 → #1A1918,冷色 → #0F172A)
  • LIGHT_BORDER:始终比 LIGHT_BG 深约一个色阶
  • 品牌渐变:linear-gradient(165deg, BRAND_DARK 0%, BRAND_PRIMARY 50%, BRAND_LIGHT 100%)

第 3 步:设置字体排版

根据用户的字体偏好,从 Google Fonts 中选择一种标题字体和一种正文字体。

风格标题字体正文字体
编辑风 / 高端Playfair DisplayDM Sans
现代 / 简洁Plus Jakarta Sans (700)Plus Jakarta Sans (400)
温暖 / 平易近人LoraNunito Sans
技术感 / 锐利Space GroteskSpace Grotesk
大胆 / 富有表现力FrauncesOutfit
经典 / 值得信赖Libre BaskervilleWork Sans
圆润 / 友好Bricolage GrotesqueBricolage Grotesque

字号比例(所有品牌统一固定):

  • 标题:28–34px,字重 600,字间距 -0.3 至 -0.5px,行高 1.1–1.15
  • 正文:14px,字重 400,行高 1.5–1.55
  • 标签 / 标记:10px,字重 600,字间距 2px,大写
  • 步骤编号:标题字体,26px,字重 300
  • 小字:11–12px

在所有幻灯片中,通过 CSS 类 .serif(标题字体)和 .sans(正文字体)应用这些样式。


幻灯片 1 — 吸睛开场规则

第一张幻灯片必须在 1 秒内吸引用户停下滚动。优先采用以下形式:

开场形式示例
有争议的观点"你用错 AI 了"
数字 + 优势"7 款能取代你的设计师的工具"
扎心的问题"为什么你的轮播帖一个收藏都没有?"
具体成果"这篇帖子在 3 天内带来了 4,200 名粉丝"
反转预期"设计投入越多 = 触达越少"

规则:

  • 标题绝不能以品牌名称开头
  • 尽可能在第 1 张幻灯片中展示视觉证据(截图、成果、真实数字)
  • 开场必须承诺提供后续幻灯片会兑现的价值

幻灯片序列

标准序列(7 张 — 默认)
#类型背景目的
1主视觉LIGHT_BG吸睛开场 — 醒目的陈述、Logo 组合、可选水印
2问题DARK_BG痛点 — 哪些地方出了问题、令人沮丧或已经过时
3解决方案品牌渐变答案 — 解决问题的方法,可选引用 / 提示词框
4功能LIGHT_BG你能获得什么 — 带图标的功能列表
5详情DARK_BG深入介绍 — 自定义选项、规格、差异化优势
6操作指南LIGHT_BG步骤 — 编号工作流或流程
7行动号召品牌渐变行动号召 — Logo、标语、CTA 按钮。不要添加箭头。进度条显示完整进度。
清单序列(5–10 张)
#类型背景
1主视觉LIGHT_BG
2–N条目 NLIGHT/DARK 交替
最后一张行动号召品牌渐变

适用于:"X 款工具"、"X 个错误"、"X 条建议"

教程序列(7 张)
#类型背景
1主视觉LIGHT_BG
2背景 / 原因DARK_BG
3–5步骤 1、2、3交替
6预期结果DARK_BG
7行动号召品牌渐变
对比序列(5 张)
#类型背景
1主视觉(说明对比内容)LIGHT_BG
2选项 ALIGHT_BG
3选项 BDARK_BG
4结论品牌渐变
5行动号召DARK_BG

所有序列的通用规则:

  • 以吸睛开场开始 — 第一张幻灯片必须吸引用户停下滚动
  • 以品牌渐变背景的行动号召结束 — 不要添加滑动箭头,进度条显示 100%
  • 交替使用浅色和深色背景,营造视觉节奏
  • 根据主题调整序列 — 并非每个轮播帖都需要包含所有幻灯片

幻灯片架构

格式
  • 宽高比:4:5(Instagram 轮播帖标准)
  • 每张幻灯片都是独立的 — 所有 UI 元素都直接嵌入图片
  • 交替使用 LIGHT_BG 和 DARK_BG 背景,营造视觉节奏
每张幻灯片都必须包含的元素
1. 进度条(每张幻灯片底部)

显示轮播中的位置,并随用户滑动逐渐填充。

  • 位置:绝对定位于底部,宽度占满,水平内边距为 28px,底部内边距为 20px
  • 轨道:高度为 3px,圆角
  • 填充宽度:((slideIndex + 1) / totalSlides) * 100%
  • 浅色幻灯片:轨道为 rgba(0,0,0,0.08),填充为 BRAND_PRIMARY,计数器为 rgba(0,0,0,0.3)
  • 深色幻灯片:轨道为 rgba(255,255,255,0.12),填充为 #fff,计数器为 rgba(255,255,255,0.4)
  • 进度条旁的计数标签:格式为“1/7”,字号为 11px,字重为 500
function progressBar(index, total, isLightSlide) {
  const pct = ((index + 1) / total) * 100;
  const trackColor = isLightSlide ? 'rgba(0,0,0,0.08)' : 'rgba(255,255,255,0.12)';
  const fillColor = isLightSlide ? BRAND_PRIMARY : '#fff'; // use actual BRAND_PRIMARY value
  const labelColor = isLightSlide ? 'rgba(0,0,0,0.3)' : 'rgba(255,255,255,0.4)';
  return `<div style="position:absolute;bottom:0;left:0;right:0;padding:16px 28px 20px;z-index:10;display:flex;align-items:center;gap:10px;">
    <div style="flex:1;height:3px;background:${trackColor};border-radius:2px;overflow:hidden;">
      <div style="height:100%;width:${pct}%;background:${fillColor};border-radius:2px;"></div>
    </div>
    <span style="font-size:11px;color:${labelColor};font-weight:500;">${index + 1}/${total}</span>
  </div>`;
}

⚠️ 重要: 渲染前务必将 BRAND_PRIMARY 替换为实际的十六进制值。HTML 输出中不得将其保留为变量名。

2. 滑动箭头(右侧边缘——除最后一张外的每张幻灯片)

低调的箭头符号,引导用户继续滑动。最后一张幻灯片上移除。

  • 位置:绝对定位于右侧,高度占满,宽度为 48px
  • 背景:从透明到淡色的渐变
  • 箭头:24×24 SVG,圆角描边
  • 浅色幻灯片:背景为 rgba(0,0,0,0.06),描边为 rgba(0,0,0,0.25)
  • 深色幻灯片:背景为 rgba(255,255,255,0.08),描边为 rgba(255,255,255,0.35)
function swipeArrow(isLightSlide) {
  const bg = isLightSlide ? 'rgba(0,0,0,0.06)' : 'rgba(255,255,255,0.08)';
  const stroke = isLightSlide ? 'rgba(0,0,0,0.25)' : 'rgba(255,255,255,0.35)';
  return `<div style="position:absolute;right:0;top:0;bottom:0;width:48px;z-index:9;display:flex;align-items:center;justify-content:center;background:linear-gradient(to right,transparent,${bg});">
    <svg width="24" height="24" viewBox="0 0 24 24" fill="none">
      <path d="M9 6l6 6-6 6" stroke="${stroke}" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
    </svg>
  </div>`;
}

可复用组件

删除线胶囊标签
<span style="font-size:11px;padding:5px 12px;border:1px solid rgba(255,255,255,0.1);border-radius:20px;color:#6B6560;text-decoration:line-through;">{Old tool}</span>
标签胶囊
<span style="font-size:11px;padding:5px 12px;background:rgba(255,255,255,0.06);border-radius:20px;color:{BRAND_LIGHT};">{Label}</span>
提示词 / 引言框
<div style="padding:16px;background:rgba(0,0,0,0.15);border-radius:12px;border:1px solid rgba(255,255,255,0.08);">
  <p class="sans" style="font-size:13px;color:rgba(255,255,255,0.5);margin-bottom:6px;">{Label}</p>
  <p class="serif" style="font-size:15px;color:#fff;font-style:italic;line-height:1.4;">"{Quote text}"</p>
</div>
特性列表
<div style="display:flex;align-items:flex-start;gap:14px;padding:10px 0;border-bottom:1px solid {LIGHT_BORDER};">
  <span style="color:{BRAND_PRIMARY};font-size:15px;width:18px;text-align:center;">{icon}</span>
  <div>
    <span class="sans" style="font-size:14px;font-weight:600;color:{DARK_BG};">{Label}</span>
    <span class="sans" style="font-size:12px;color:#8A8580;">{Description}</span>
  </div>
</div>
编号步骤
<div style="display:flex;align-items:flex-start;gap:16px;padding:14px 0;border-bottom:1px solid {LIGHT_BORDER};">
  <span class="serif" style="font-size:26px;font-weight:300;color:{BRAND_PRIMARY};min-width:34px;line-height:1;">01</span>
  <div>
    <span class="sans" style="font-size:14px;font-weight:600;color:{DARK_BG};">{Step title}</span>
    <span class="sans" style="font-size:12px;color:#8A8580;">{Step description}</span>
  </div>
</div>
色板
<div style="width:32px;height:32px;border-radius:8px;background:{color};border:1px solid rgba(255,255,255,0.08);"></div>
CTA 按钮(仅限最后一张幻灯片)
<div style="display:inline-flex;align-items:center;gap:8px;padding:12px 28px;background:{LIGHT_BG};color:{BRAND_DARK};font-family:'{BODY_FONT}',sans-serif;font-weight:600;font-size:14px;border-radius:28px;">
  {CTA text}
</div>
标签 / 类别标签
<span class="sans" style="display:inline-block;font-size:10px;font-weight:600;letter-spacing:2px;color:{color};margin-bottom:16px;">{TAG TEXT}</span>
  • 浅色幻灯片:BRAND_PRIMARY
  • 深色幻灯片:BRAND_LIGHT
  • 品牌渐变幻灯片:rgba(255,255,255,0.6)
Logo 组合(第一张和最后一张幻灯片)
  • 如果是 Logo 图标:直径 40px 的圆形(背景为 BRAND_PRIMARY)+ 居中的图标 + 旁边的品牌名称
  • 如果是首字母:直径 40px 的圆形,内含白色首字母
  • 品牌名称:字号为 13px,字重为 600,字母间距为 0.5px

布局规则

  • 内容内边距:标准值为 0 36px
  • 带进度条且内容底部对齐的幻灯片:使用 0 36px 52px,为进度条留出空间
  • 主视觉 / CTA 幻灯片: justify-content: center
  • 内容较多的幻灯片: justify-content: flex-end
  • 内容不得与进度条重叠——使用 padding-bottom: 52px

Instagram 画框(预览包装器)

在聊天中展示时,请使用 Instagram 风格的画框包装:

  • **页眉:**头像(BRAND_PRIMARY 圆形背景 + Logo)+ 用户名 + 副标题
  • **视口:**4:5 宽高比,可滑动 / 拖动的轨道,包含所有幻灯片
  • **圆点:**视口下方的小圆点指示器
  • **操作:**心形、评论、分享、收藏 SVG 图标
  • **说明文字:**用户名 + 简短描述 + “2 HOURS AGO” 时间戳

预览中需包含基于指针的滑动 / 拖动交互。幻灯片仍是可独立导出的图片。

重要:.ig-frame 的宽度必须正好为 420px。轮播视口尺寸为 420×525px。切勿更改此宽度——导出依赖此设置。


审核流程

务必遵循此流程。未经批准,绝不可直接导出。

  1. 先生成 HTML 预览——绝不可直接跳到导出
  2. 展示预览并询问:“导出前哪些幻灯片需要调整?”
  3. 仅修改用户指出的幻灯片——除非设计方向发生根本变化,否则不要重新生成整个轮播
  4. 只有在用户明确确认批准后(例如“可以导出”“已批准”“好的”)才能继续导出

将幻灯片导出为适用于 Instagram 的 PNG 图片

用户批准轮播预览后,将每张幻灯片单独导出为 1080×1350px PNG。

关键导出规则
  1. 使用 Python 生成 HTML——绝不可使用带变量插值的 shell 脚本。务必使用 Path.write_text() 或 open().write()。

  2. 将图片嵌入为 base64——所有用户上传的图片都必须进行 base64 编码,并作为 data:image/jpeg;base64,... URI。使用 file 命令检查实际文件格式——.png 扩展名的文件可能实际包含 JPEG 数据。

  3. 保持 420px 的布局宽度——使用 Playwright 的 device_scale_factor 将输出放大至 1080px,而不更改布局视口。

安装 Playwright(仅在需要时)

运行导出脚本前,先检查是否已安装,仅在缺少时安装:

python3 -c "import playwright" 2>/dev/null || pip3 install playwright
python3 -c "from playwright.sync_api import sync_playwright; sync_playwright().__enter__().chromium" 2>/dev/null || python3 -m playwright install chromium
导出脚本
import asyncio
from pathlib import Path
from playwright.async_api import async_playwright

INPUT_HTML = Path("/path/to/carousel.html")
OUTPUT_DIR = Path("/path/to/output/slides")
OUTPUT_DIR.mkdir(exist_ok=True)

TOTAL_SLIDES = 7  # Update to match your carousel

VIEW_W = 420
VIEW_H = 525
SCALE = 1080 / 420  # = 2.5714...

async def export_slides():
    async with async_playwright() as p:
        browser = await p.chromium.launch()
        page = await browser.new_page(
            viewport={"width": VIEW_W, "height": VIEW_H},
            device_scale_factor=SCALE,
        )

        html_content = INPUT_HTML.read_text(encoding="utf-8")
        await page.set_content(html_content, wait_until="networkidle")
        await page.wait_for_timeout(3000)  # Wait for Google Fonts to load

        # Hide IG frame chrome, show only the slide viewport
        await page.evaluate("""() => {
            document.querySelectorAll('.ig-header,.ig-dots,.ig-actions,.ig-caption')
                .forEach(el => el.style.display='none');

            const frame = document.querySelector('.ig-frame');
            frame.style.cssText = 'width:420px;height:525px;max-width:none;border-radius:0;box-shadow:none;overflow:hidden;margin:0;';

            const viewport = document.querySelector('.carousel-viewport');
            viewport.style.cssText = 'width:420px;height:525px;aspect-ratio:unset;overflow:hidden;cursor:default;';

            document.body.style.cssText = 'padding:0;margin:0;display:block;overflow:hidden;';
        }""")
        await page.wait_for_timeout(500)

        for i in range(TOTAL_SLIDES):
            await page.evaluate("""(idx) => {
                const track = document.querySelector('.carousel-track');
                track.style.transition = 'none';
                track.style.transform = 'translateX(' + (-idx * 420) + 'px)';
            }""", i)
            await page.wait_for_timeout(400)

            await page.screenshot(
                path=str(OUTPUT_DIR / f"slide_{i+1}.png"),
                clip={"x": 0, "y": 0, "width": VIEW_W, "height": VIEW_H}
            )
            print(f"Exported slide {i+1}/{TOTAL_SLIDES}")

        await browser.close()

asyncio.run(export_slides())
原理说明
  • device_scale_factor=2.5714 以高 DPI 渲染——一个 420px 的元素在输出中会变成 1080px。布局仍保持 420px。
  • clip 仅截取轮播视口,不包含浏览器边框。
  • wait_for_timeout(3000) 为 Google Fonts 留出加载时间。
  • track.style.transition = 'none' 禁用滑动动画,让幻灯片立即切换。
应避免的常见导出错误
错误问题修复方法
将视口设为 1080×1350布局会重新排版——字体变得很小,间距也会错乱保持视口为 420×525,使用 device_scale_factor
使用 Shell 脚本生成 HTML$ 符号和反引号会被插值始终使用 Python 生成 HTML
未等待字体加载标题会以系统备用字体渲染页面加载后调用 wait_for_timeout(3000)
未隐藏 IG 边框元素导出内容会包含页眉、圆点和说明文字隐藏 .ig-header,.ig-dots,.ig-actions,.ig-caption
更改 .ig-frame 的宽度整体布局会发生偏移始终保持宽度为精确的 420px
在 CSS 中将 BRAND_PRIMARY 保留为变量名颜色会显示为无效或不可见始终将实际的十六进制值插入 HTML

设计原则

  1. 每张幻灯片都可直接导出——箭头和进度条都是幻灯片图像的一部分
  2. 明暗交替——在滑动浏览时营造视觉节奏
  3. 标题与正文的字体搭配——标题使用展示字体以增强冲击力,正文使用易读字体
  4. 源自品牌的配色方案——所有颜色都源于一种主色,保持整体协调
  5. 渐进式呈现——进度条逐渐填充,箭头引导用户继续浏览
  6. 最后一张幻灯片特别设计——不显示箭头,进度条填满,并提供明确的 CTA
  7. 组件保持一致——所有幻灯片使用相同的标签样式、列表样式和间距
  8. 内容留白避开界面元素——正文不会与进度条或箭头重叠
  9. 开篇先抓住注意力——第 1 张幻灯片旨在让用户停下滑动,而不是介绍品牌
  10. 快速迭代——展示预览,针对具体幻灯片进行修复,不要从头重做

评论

支持 Markdown