mcpField
P
play-store-screenshots

play-store-screenshots

github.com/mobile-dev-ci营销与增长20175 次安装31 周前更新
代码仓库

关于 play-store-screenshots

play-store-screenshots 是用于制作 Google Play 商店宣传手机截图和特色图片的技能。它引导整理功能卖点、选择素材并确认视觉设置,再生成可配置的 HTML 生成器。

主要功能

  1. 01制作手机截图和特色图片
  2. 02引导梳理功能与素材
  3. 03从截图提取视觉设置
  4. 04通过 config.js 配置输出
  5. 05支持 text-top 和 full-bleed 布局

适用场景

  1. 01准备 Play 商店商品页宣传图片
  2. 02将应用截图制作为商店素材
  3. 03生成多语言截图素材

安装

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

$npx skills add https://github.com/mobile-dev-ci/play-store-screenshots --skill play-store-screenshots

安装后在 Claude Code 中输入/play-store-screenshots确认已加载。

附带文件example-config.js

详细介绍

Play 商店截图生成器

概览与核心理念

这项技能使用 Next.js 和 html-to-image 生成以广告宣传为导向的 Google Play 商店截图。核心原则:截图是广告,不是文档。 每张幻灯片都传达一个结果、一种感受或一种解决方案,而不是带用户浏览界面。

与 Apple App Store 不同,Play 商店还需要一张宣传图(1024×500px)——这是一张横幅图片,会醒目地显示在应用的商店详情页上。这项技能将其视为与手机截图同等重要的素材。


需求确认阶段

目标是在尽可能快地开始生成的同时,避免错误假设浪费用户的时间。做法是:询问必须了解的信息,推断可以推断的信息,始终展示你的判断,并在继续前确认。


步骤 1 — 先询问,再查看

查看任何文件前,先提出一个无法推断的问题:

“你的 3–6 项主要功能是什么?请简要说明每项功能为用户解决了什么问题。”

这是一个营销决策——任何文件或截图都无法回答这个问题。用户最了解自己应用的价值主张。

如果用户只提供功能名称,却没有说明解决的问题(例如“离线模式、深色主题、收藏夹”),请追问:

“对于每项功能——如果没有这项功能,用户会觉得哪里不方便?”

在获得这些信息前,不要进入步骤 2。


步骤 2 — 扫描并查找素材

了解功能后,扫描当前目录中的素材。查找以下内容:

  • 截图:当前文件夹或 screenshots/ 子文件夹中的 .png / .jpg 文件
  • 应用图标:先检查 Android 的标准路径:
    app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
    app/src/main/res/mipmap-xxhdpi/ic_launcher.png
    
    如果不是 Android 项目,则查找任何名为 icon*.png、logo*.png 或 app-icon.* 的文件

如果找到所需的文件——列出文件并询问:

“我找到了这些截图:[列表]。我会使用这些截图。这样对吗?”

如果找到了多个候选文件,无法判断哪个合适——展示这些文件并询问:

“我找到了多个 PNG 文件。哪些是要使用的应用截图?”

如果什么也没找到——直接询问:

“我在此目录中没有找到任何截图。你的 Android 应用截图保存在哪里?”

有歧义时,绝不要默默猜测。选错一个文件就会让整次运行白费。


步骤 3 — 根据截图推断视觉设置

拿到截图后,进行视觉分析并推断以下内容。编写任何代码前,先用一个简短的确认区块展示你的判断:

Here's what I picked up from your screenshots — let me know if anything looks off:

  App name:    Aarti Mandir
  Primary:     #C9822A  (toolbar orange)
  Background:  #FFF8F0  (warm cream)
  Text:        #2D1A00  (dark brown)
  Accent:      #C9822A
  Theme:       editorial  (warm/earthy tones)
  Font:        Inter  (default — let me know if you use a specific font)
  Frame:       white  (light app)
  Slides:      5

只有在用户确认或更正后才能继续。在这里花 10 秒确认,可以避免因颜色错误而重新生成所有内容。

如何推断各项值:

值推断方法
应用名称从截图中读取(工具栏、启动画面、图标标签)
主色界面中的主导颜色——工具栏、页眉、选中标签页、填充按钮
背景色屏幕大部分内容后方的颜色
文字颜色根据背景推断——深色背景 → #FFFFFF,浅色背景 → #111111
强调色CTA 按钮、高亮内容、开关、选中状态
次要色渐变的搭配颜色——将主色的色相偏移 15–20 度,或使用界面中可见的次要颜色
主题深色背景 → dark-bold · 浅色/白色背景 → clean-light · 暖色/大地色背景 → editorial · 品牌色铺满背景 → vibrant
字体默认使用 Inter,除非应用截图显示了明显独特的字体
边框颜色深色应用(深色工具栏 + 背景)→ black · 浅色应用 → white
幻灯片数量默认 5

如果确实无法从截图中判断某个值——请询问,不要猜测。

“我无法从截图中清楚辨认你的主品牌色。你的主要品牌色的十六进制颜色值是什么?”


步骤 4 — 确认,然后构建

用户确认步骤 3 中的摘要后,继续生成 config.js 和 index.html。除非出现意外情况,否则不要再提问。

默认值(除非用户主动提及,否则绝不询问):

  • tablet.enabled:false
  • locales:["en"]
  • featureGraphic.style:"gradient"
  • featureGraphic.subtext:"Available on Google Play"

需要询问什么,以及需要推断什么
输入处理方式
功能和用户问题务必询问——无法推断
截图路径扫描 → 如果找到则确认;如果未找到或不明确则询问
应用图标路径扫描标准路径 → 如果找到则确认;如果没有则询问
应用名称从截图中读取 → 在摘要中确认
品牌颜色目视提取 → 在摘要中确认;如果不明确则询问
主题根据背景颜色推断 → 在摘要中确认
字体默认使用 Inter → 在摘要中确认;如果应用使用了独特字体则注明
设备边框颜色根据应用的整体风格推断 → 在摘要中确认
幻灯片数量默认 5 张 → 在摘要中说明,用户可以更改
平板 / 语言区域 / 横向布局默认关闭/en/纵向 → 绝不询问,仅在用户主动提及时启用

项目架构

此技能会在一个新文件夹中生成两个文件。无需框架、无需 npm install,也无需构建步骤。

play-store-screenshots/
├── index.html      ← rendering engine, export logic, overview mode (don't edit)
├── config.js       ← ALL customization: copy, colors, slides (edit this)
└── screenshots/    ← user's raw Android app screenshots + app icon
    ├── app-icon.png
    ├── screen1.png
    └── screen2.png

AI 会填写 config.js。index.html 会读取其中的内容并渲染所有内容。

使用方法:通过一行命令启动本地服务来提供该文件夹(加载本地图片时必需),在 Chrome 中打开,然后点击 Export All。

# Pick any one of these — whatever is available:
python3 -m http.server 8080
npx serve .

然后打开 http://localhost:8080。

关于导出文件的说明: 点击 "Export All" 会触发浏览器下载——文件会保存到系统的下载文件夹。上传到 Play Console 前,请先在那里重命名并整理文件。

是否应该将此项目提交到 git?

不应该。截图生成器是一个一次性工具——获得 PNG 后,该项目就完成了它的任务。唯一值得长期保留的文件是:

  • 导出的 PNG(上传到 Play Console)
  • 如果之后想重新生成或调整,则保留 config.js

可以在任意临时文件夹中操作。不要将其添加到应用的代码仓库中。


config.js 参考

config.js 是 AI 唯一需要编写的文件。它是纯 JavaScript——无需 TypeScript、无需导入,也无需构建步骤。

此技能目录中的 example-config.js 提供了一个虚构应用的完整可用示例——可以复制它作为起点。

const config = {
  app: {
    name: "Your App",
    icon: "screenshots/app-icon.png",
  },

  brand: {
    primary: "#6366F1",       // dominant brand color
    secondary: "#4F46E5",     // gradient partner / secondary brand color
    background: "#FFFFFF",    // canvas background
    surface: "#F4F4F8",       // card / panel backgrounds
    text: "#111111",          // headline color
    textMuted: "#666666",     // caption / label color
    accent: "#F59E0B",        // highlight, call-to-action color
  },

  // "clean-light" | "dark-bold" | "vibrant" | "editorial"
  theme: "clean-light",

  device: {
    color: "black",           // "black" | "white" | "silver"
  },

  slides: [
    {
      id: "hero",
      layout: "text-top",
      screenshot: "screenshots/screen1.png",
      label: "INTRODUCING",
      headline: "Your app name.\nYour outcome.",
      // Leave subtext empty on hero — let the visual breathe
    },
    {
      id: "feature-one",
      layout: "text-top",
      screenshot: "screenshots/screen2.png",
      label: "FEATURE NAME",
      headline: "Short benefit\nstatement here.",
      subtext: "One supporting sentence, maximum.",
    },
    // Add 2–8 slides total — all use layout: "text-top"
  ],

  featureGraphic: {
    headline: "The app headline goes here",
    subtext: "Available on Google Play",
    // "gradient" | "solid" | "screenshot-backed"
    style: "gradient",
    // Only used when style is "screenshot-backed"
    screenshot: "screenshots/screen1.png",
  },

  // Optional: set enabled: true and add tablet screenshots to activate
  tablet: {
    enabled: false,
    sizes: ["10-inch"],       // "7-inch" | "10-inch" | both
  },

  // Add locale codes to generate localized sets: "de", "fr", "ar", "he", etc.
  locales: ["en"],
};
多语言文案

当 locales 包含多个条目时,将字符串值改为语言区域映射:

slides: [
  {
    id: "hero",
    layout: "text-top",
    screenshot: { en: "screenshots/en/screen1.png", de: "screenshots/de/screen1.png" },
    label: { en: "INTRODUCING", de: "NEU" },
    headline: { en: "Your app.\nYour way.", de: "Deine App.\nDein Weg." },
  },
]

幻灯片布局

统一布局,始终如一。

每张手机截图都采用相同的构图:文字在上方,大尺寸手机在下方。这不是限制,而是竖版 Play Store 截图的正确模式。这种方式行之有效。

┌─────────────────────┐
│   App Name          │  ← small, top padding ~6% of canvas height
│                     │
│   LABEL             │  ← all-caps label
│   Big headline      │  ← largest text on the slide
│   here.             │
│   Subtext sentence. │  ← optional, smaller
│                     │
│  ┌───────────────┐  │
│  │               │  │
│  │  [screenshot] │  │  ← phone, large, centered
│  │               │  │
│  │               │  │  ← bottom of phone crops off canvas (intentional)
└──┴───────────────┴──┘

标准手机尺寸——使用以下精确数值:

属性数值
手机宽度PHONE_W * 0.82(≈885px)
手机高度phoneWidth * 2.15(≈1903px — 高于画布)
手机左侧位置(PHONE_W - phoneWidth) / 2(居中)
手机顶部位置PHONE_H * 0.34(距顶部约 653px)
底部裁切手机约 25% 的高度超出画布——这是有意为之,可增加纵深感

手机底部超出画布边缘是有意且理想的效果——它能在视觉上稳固手机,并消除整部手机都显示出来时出现的尴尬留白。

文字块定位:

文字容器高度为 height: PHONE_H * 0.32,并设置 overflow: hidden。内容在容器内垂直居中。手机从 PHONE_H * 0.34 处开始,文字块底部与手机顶部之间留有约 2% 的缓冲间隙,避免标签或最后一行标题碰到设备边框。

元素位置
应用名称 / 品牌top: PHONE_H * 0.06,居中
标签top: PHONE_H * 0.13,居中
标题标签下方,居中,font-size: PHONE_W * 0.09
补充文字标题下方,居中,font-size: PHONE_W * 0.038

所有文字都应位于画布高度顶部 32% 的范围内(容器会通过 overflow: hidden 限制内容)。如果文字溢出,请缩短标题,不要将手机下移。


feature-graphic (仅用于功能宣传图,不用于手机截图)

横向画布(1024×500px)。不使用设备模型。有两种构图方式:

  • **图标靠左:**应用图标(180×180)置于左侧三分之一处,标题和补充文字置于右侧三分之二处
  • **图标居中:**应用图标在顶部居中,标题置于其下方,补充文字再置于标题下方

背景使用选定的 featureGraphic.style 填充整个画布。


支持的布局

模板仅实现两种布局:

  • text-top — 大多数截图使用此布局(如上所述)
  • full-bleed — 全屏截图叠加渐变;文字悬浮在顶部

其他任何 layout 值都会显示红色错误框。请勿使用 layout: "text-bottom"、layout: "split-screen"、layout: "hero-left" 或 layout: "hero-right" 创建截图,这些布局尚未实现。

full-bleed 布局

截图填满整个画布(width:100%; height:100%; object-fit:cover)。深色渐变从顶部向下渐隐(高度约占 35%),覆盖在截图上方。标签和标题以白色文字悬浮在顶部渐变上。不使用设备模型。

此布局仅用于一张截图——当应用截图本身具有很强的视觉吸引力时,效果最佳。切勿用于显示密集 UI(列表、设置)的截图。避免连续使用多张 full-bleed 截图。

┌─────────────────────┐
│   LABEL             │  ← white text over gradient
│   Big headline      │
│   here.             │
│▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓│  ← gradient fade
│                     │
│  [screenshot fills  │
│   entire canvas]    │
│                     │
└─────────────────────┘

Android 设备模型图(仅 CSS)

Android 手机边框使用**纯 CSS 实现,无需 PNG 资源。**这样可以避免脆弱的 PNG 偏移耦合问题,即必须让精确的像素值与特定图像文件匹配。

组件:<AndroidPhoneMockup>

属性:screenshot(字符串路径)、color("black" | "white" | "silver")、width(像素数值)、height(像素数值)

渲染结构和关键比例(所有值均根据组件的 width / height 计算):

┌──────────────────────┐  outer frame (corner radius: width*0.12)
│          ●           │  punch-hole camera: width*0.028 diameter, centered, top height*0.018
│  ┌────────────────┐  │  screen: left/right inset width*0.030, top/bottom inset height*0.025
│  │                │  │
│  │  [screenshot]  │  │
│  │                │  │
│  └────────────────┘  │
│        ───────       │  home indicator: width*0.30 wide, height*0.003 tall, bottom height*0.015
└──────────────────────┘
属性值
外框圆角半径width * 0.12
边框厚度width * 0.008
屏幕左右内边距width * 0.030
屏幕顶部内边距height * 0.025
屏幕底部内边距height * 0.028
摄像头直径width * 0.028
摄像头中心距顶部height * 0.018
主屏幕指示条宽度width * 0.30
主屏幕指示条高度height * 0.003
主屏幕指示条距底部height * 0.014

根据 color 属性设置边框颜色:

  • "black" → 边框 #1C1C1E,轮廓 #3A3A3C,屏幕背景 #000000
  • "white" → 边框 #F2F2F7,轮廓 #D1D1D6,屏幕背景 #FFFFFF
  • "silver" → 边框 #8E8E93,轮廓 #636366,屏幕背景 #111111

**重要:**手机边框或轮廓切勿使用品牌色。边框必须始终使用上述中性色之一。使用品牌色(例如应用的强调橙色或紫色)作为边框颜色会显得不专业,并分散用户对屏幕内容的注意力。边框应在视觉上退居其次,而非与 UI 争夺注意力。

边框还应添加柔和的投影,使其从背景中微微浮起:

box-shadow: 0 24px 80px rgba(0, 0, 0, 0.18), 0 8px 24px rgba(0, 0, 0, 0.10);

根据主题调整不透明度:浅色背景使用较淡的阴影,深色背景使用较浓的阴影。

侧边按键(可选细节,可提升真实感):

  • 电源键:右侧,距顶部 38% 处,高度为总高度的 8%,宽度为宽度的 0.6%
  • 音量加/减键:左侧,分别位于距顶部 32% 和 42% 处,尺寸相同

高级设计元素

基础截图与高级感设计之间的区别完全在于装饰层——背景处理、标签设计,以及手机背后微妙的景深效果。这些效果都可通过纯 CSS 应用于幻灯片画布。

背景处理

切勿将纯色平铺用作幻灯片背景。至少叠加两个元素:

  1. 基础渐变——使用品牌色的对角或径向多段渐变
  2. 装饰光球——放置在文字和手机背后的 2–3 个大型强模糊圆形
/* Example: dark theme with purple brand */
.slide {
  background: linear-gradient(160deg, #080613 0%, #120B22 60%, #060410 100%);
  position: relative;
  overflow: hidden;
}

/* Blurred decorative orb */
.orb {
  position: absolute;
  border-radius: 50%;
  filter: blur(140px);
  pointer-events: none;
  z-index: 1;
}

/* Top orb — sits behind the text block */
.orb-top {
  width: 700px; height: 700px;
  top: -120px; left: 50%;
  transform: translateX(-50%);
  background: radial-gradient(circle, #7C3AED 0%, transparent 70%);
  opacity: 0.28;
}

/* Bottom orb — sits behind the phone */
.orb-bottom {
  width: 900px; height: 900px;
  top: 500px; left: 50%;
  transform: translateX(-50%);
  background: radial-gradient(circle, #4338CA 0%, transparent 70%);
  opacity: 0.20;
}

根据主题调整光球的不透明度:

  • 深色主题:0.25–0.40
  • 浅色主题:0.08–0.15(非常柔和的染色效果,几乎不可见)
胶囊徽标样式的标签

标签必须是带背景的胶囊形徽标,而非纯文本。仅此一项改动,就能让幻灯片看起来像经过设计,而不是简单拼凑出来的。

/* All values below are illustrative — scale relative to W as shown in comments */
.label-pill {
  display: inline-flex;
  align-items: center;
  padding: 12px 32px;     /* W*0.011 W*0.030 */
  border-radius: 100px;
  font-size: 28px;        /* W * 0.026 */
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  margin-bottom: 32px;    /* W * 0.030 */
}

/* Dark theme — glass/translucent variant */
.label-pill-glass {
  background: rgba(255, 255, 255, 0.10);
  color: rgba(255, 255, 255, 0.80);
  border: 1.5px solid rgba(255, 255, 255, 0.14);
}

/* Dark theme — colored variant (hero slide or high-emphasis labels) */
.label-pill-accent {
  background: rgba(124, 58, 237, 0.18);   /* use brand primary at ~18% */
  color: #C4B5FD;                          /* lighter tint of primary */
  border: 1.5px solid rgba(124, 58, 237, 0.32);
}

/* Light theme */
.label-pill-light {
  background: rgba(201, 130, 42, 0.12);   /* brand primary at ~12% */
  color: #92600E;                          /* darker shade for contrast */
  border: 1.5px solid rgba(201, 130, 42, 0.25);
}
标题排版

使用紧凑的字间距和微妙的文字阴影,营造景深效果:

/* font-size must be set via inline style using the proportional system — not hardcoded */
.headline {
  /* font-size: W * 0.090  (set inline, not in CSS class) */
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: -0.02em;
}

/* Dark theme only */
.slide-dark .headline {
  text-shadow: 0 4px 40px rgba(0, 0, 0, 0.40);
}
标题中的应用图标

在标签上方显示应用图标(约 80px,圆角)。无需添加杂乱元素,即可在每张幻灯片中凸显品牌标识。

.app-icon {
  width: 80px; height: 80px;
  border-radius: 18px;
  object-fit: cover;
  box-shadow: 0 8px 28px rgba(0, 0, 0, 0.30);
  margin-bottom: 20px;
}
手机环境光晕(仅限深色主题)

在背景与手机之间添加径向光晕,让设备看起来像是融入光线之中,而非简单地贴在背景上:

.phone-glow {
  position: absolute;
  width: 900px; height: 900px;
  border-radius: 50%;
  background: radial-gradient(circle, var(--brand-primary) 0%, transparent 65%);
  filter: blur(80px);
  opacity: 0.18;
  top: 400px;
  left: 50%;
  transform: translateX(-50%);
  pointer-events: none;
  z-index: 4;   /* above background orbs, below phone */
}

浅色背景上不要添加光晕——看起来会像一块浑浊的污渍。

噪点纹理叠加层(可选,高级质感)

微妙的 SVG 噪点纹理可让渐变显得不那么平滑,更有印刷质感。保持很低的不透明度:

.slide::after {
  content: '';
  position: absolute;
  inset: 0;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  opacity: 0.04;
  mix-blend-mode: overlay;
  pointer-events: none;
  z-index: 100;
}

导出规格

手机竖屏(主要规格——始终必需)

1080 × 1920px

所有内容均按此分辨率设计和导出。Play Store 接受宽高比介于 1:2 和 2:1 之间的任意尺寸;1080×1920 适用于所有手机。

手机横屏(可选)

1920 × 1080px

适用于游戏和以横屏 UI 为主的应用。如果用户的应用主要以横屏方向使用,请提供此规格。

平板(可选)
屏幕尺寸
7 英寸1200 × 1920px
10 英寸1600 × 2560px
特色图片(Play Store 要求)

1024 × 500px

这是显示在 Play Store 列表顶部的横向横幅。它不是手机截图——没有设备边框。所有应用都必须提供。

常量
// Phone portrait (primary)
const PHONE_W = 1080;
const PHONE_H = 1920;

// Phone landscape (optional)
const PHONE_LAND_W = 1920;
const PHONE_LAND_H = 1080;

// Tablet 7-inch (optional)
const TAB7_W = 1200;
const TAB7_H = 1920;

// Tablet 10-inch (optional)
const TAB10_W = 1600;
const TAB10_H = 2560;

// Feature graphic (required)
const FG_W = 1024;
const FG_H = 500;

文案策略与信息传达

每张幻灯片包含三个文本元素:标签、标题和可选的副文案。每个元素的作用都不同。三者都做到位,这张幻灯片就能在一秒内打动用户。


步骤 1:将功能描述转化为文案

当用户描述某项功能时,不要只是复述给他们听。改为询问:

“如果没有这项功能,什么情况会让人感到焦虑或沮丧?”

这种焦虑就是你的标题。功能只是解决方案。

示例:

  • 用户说:“离线模式——没有网络也能使用应用”
  • 焦虑:需要使用应用时,身处没有信号的地方
  • 标题:"没信号?\n没问题。" 或 "每一次祈祷。\n始终相伴。"
  • 不要写:"支持离线使用" 或 "离线支持"

示例:

  • 用户说:“可以调整字体大小”
  • 焦虑:小字看起来费劲,尤其是对年长用户而言
  • 标题:"字体更大。\n文字更清晰。" 或 "按你的方式阅读。"
  • 不要写:"可调节字体大小" 或 "无障碍功能"

示例:

  • 用户说:“收藏/为祈祷内容添加书签”
  • 焦虑:要翻遍所有内容,才能找到最常用的那一篇
  • 标题:"你的祈祷。\n始终在手边。" 或 "珍爱之物,\n随时珍藏。"
  • 不要写:"收藏系统" 或 "为内容添加书签"

步骤 2:撰写标题

标题是幻灯片上字号最大的文字。即使缩略图大小,也必须在一秒内传达清楚。

以下六种公式都很有效。选择最符合功能情感角度的一种:

公式 1:解决痛点

点明问题,并暗示解决方案。简短有力。

"没信号?\n没问题。" "别再搜索。\n直接找到。" "又忘了?\n再也不会。"

公式 2:归属感(所有格+结果)

营造个人拥有的感觉,更显亲近。

"你的祈祷。\n始终在手边。" "你的节奏。\n你的进步。" "你的数据。\n你做主。"

公式 3:描绘瞬间(呈现确切时刻)

描述用户受益的具体时刻,让体验更真切。

"每一次祈祷。\n触手可及。" "每天中午前。\n轻松完成。" "打开应用。\n即刻平静。"

公式 4:简单对比(暗示前后变化)

两行短句。第一行制造张力,第二行化解。

"字体更大。\n文字更清晰。" "轻点一下。\n即刻访问。" "减少干扰。\n更加专注。"

公式 5:发出邀请(主动动词+回报)

以动词开头,充满活力,直截了当。

"珍爱之物,\n随时珍藏。" "找到任何内容。\n就在此刻。" "切换语言。\n随时随地。"

公式 6:明确宣言(自信地表达身份)

大胆说出应用的定位。最适合主视觉幻灯片。

"每一次祈祷。\n触手可及。" "全心投入。\n专注当下。" "简化你的\n每日虔修。"


步骤 3:撰写标签

标签是标题上方的小号全大写文字。它的作用是引导读者——提前告诉他们接下来会看到哪类益处,让标题更有冲击力。

规则:

  • 1–3 个词,全部大写
  • 标明益处类别,而非功能名称
  • 应能引发读者对下方标题的好奇
功能不佳标签优质标签
离线模式OFFLINE MODE100% OFFLINE
字体大小设置ACCESSIBILITYREAD COMFORTABLY
收藏BOOKMARKSFAVOURITES
双语LANGUAGESBILINGUAL
深色模式DARK MODEEASIER ON EYES
每日提醒NOTIFICATIONSDAILY REMINDER

第 4 步:撰写补充文案

补充文案是标题下方的一句辅助说明。它是可选的——如果标题本身已经足够有力,就留空(尤其是首屏幻灯片)。

使用补充文案时:

  • 补充一个标题刻意留白的具体细节
  • 写得自然亲切,不要像企业宣传文案
  • 最多 8–10 个词
  • 不要换种说法重复标题
标题不好的补充文案好的补充文案
"每一次祈祷。\n触手可及。""在一个地方轻松访问所有祈祷""Aarti • Chalisa • Mantra——尽在一处"
"没有信号?\n也没问题。""这款应用无需联网也能使用""每一次祈祷,随时可用。"
"字体更大。\n文字更清晰。""你可以调整字体大小,提升易读性""调整字体大小,适合自己。"
"收藏你\n喜爱的内容。""将你喜欢的祈祷保存为书签""快速访问你最常用的祈祷。"

适用于所有内容的规则

每张幻灯片只讲一个想法。 如果你发现自己写了“以及”,那就该拆成两张幻灯片,而不是一张。

每行 3–5 个词。 有意安排换行——换行是设计的一部分,不是意外折行。

尽量用短词。 1–2 个音节。测试一下:10 岁的孩子能立刻看懂吗?

多用动词,少用名词。 “收藏你喜爱的内容”胜过“收藏管理”。“查找任何内容”胜过“搜索功能”。

绝不要使用这些词: 无缝、强大、高级、稳健、直观、创新、全面、精简、杠杆、利用。它们毫无意义。


完整的“不佳 → 更好”参考
功能描述不好的标题好的标题
"带优先级的任务管理""高级任务管理""中午前完成。\n每天如此。"
"跨设备同步""跨设备同步""你的手机。\n你的平板。\n同一份清单。"
"分析仪表盘""强大的分析功能""看看哪些\n真的有效。"
"推送通知""实时通知""别错过\n重要时刻。"
"主屏幕小组件""可自定义的小组件""你的信息。\n就在眼前。"
"离线模式""支持离线使用""没有信号?\n也没问题。"
"字体大小控制""无障碍功能""字体更大。\n文字更清晰。"
"收藏喜爱的内容""书签系统""你的祈祷。\n始终相伴。"
"深色模式""支持深色模式""让你的\n眼睛更轻松。"
"切换语言""双语支持""Hindi 还是 English。\n由你选择。"

宣传图标题

规则相同,但可以稍长——由于横向画布空间更大,最多 8 个词。应以一行文字传达应用的核心承诺。无需换行。

"改变你祈祷方式的应用" ✓ "每一份虔心。尽在一款精美应用。" ✓ "陪伴你的日常祈祷" ✓


技术实现

设置

新建一个文件夹,并在其中创建两个文件:

mkdir play-store-screenshots
cd play-store-screenshots
mkdir screenshots
# Copy the user's app screenshots and icon into ./screenshots/

然后创建 config.js(由 AI 填写)和 index.html(由 AI 生成)。设置就这么简单——无需包管理器,也无需安装。

index.html 结构

<head> 通过 CDN 加载所有内容——无需本地依赖:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700;800;900&display=swap" rel="stylesheet">
  
  <script src="https://unpkg.com/[email protected]/dist/html-to-image.js"></script>
  
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js"></script>
  
  <script src="config.js"></script>
</head>
<body>
  
  <div id="topbar">...</div>

  
  <div id="slide-grid">
    
    
  </div>

  
  <div id="export-canvases" style="position:fixed;left:-9999px;top:0;z-index:-1">...</div>

  <script>
    // All rendering and export logic here
  </script>
</body>
</html>

核心原则:所有幻灯片始终在网格中可见。没有“每次只显示一张”的模式,也没有切换开关。 网格就是界面——你可以一眼检查所有幻灯片,然后再导出。

字体排版

通过上方的 <link> 标签加载字体。推荐默认字体:Inter、Plus Jakarta Sans、DM Sans。如果用户指定了偏好字体,请与之保持一致。

所有字号都应根据画布宽度缩放——在幻灯片渲染中,绝不要硬编码 px 值:

// Typography scale — derive from canvas width W
function typography(W) {
  return {
    label:      W * 0.028,   // all-caps category label
    headline:   W * 0.090,   // standard headline (1–2 lines)
    headlineLg: W * 0.100,   // hero slide headline (larger)
    subtext:    W * 0.038,   // supporting sentence
    caption:    W * 0.030,   // small secondary text
  };
}

这样无论以何种分辨率导出,文字都能正确呈现,无需修改。

渲染标题换行

关键:config.js 中的标题使用 \n 换行(例如 "Every prayer.\nAt your fingertips.")。切勿依赖 white-space: pre-line 来渲染这些换行——它只对实际换行符有效,不适用于配置值中可能出现的两个字面字符 \n。插入 innerHTML 前,务必使用辅助函数进行转换:

const nl2br = (text) => text.replace(/\\n|\n/g, '<br>');

在将这些值插入 HTML 的所有位置,都使用 nl2br(slide.headline) 和 nl2br(slide.subtext)。

主题系统

四个命名主题,均为普通 JS 对象。通过 config.theme 键选择主题:

const THEMES = {
  "clean-light": {
    bg: "#FFFFFF",
    fg: "#111111",
    accent: config.brand.primary,
    muted: "#888888",
    surface: "#F4F4F8",
  },
  "dark-bold": {
    bg: "#0A0A0A",
    fg: "#FFFFFF",
    accent: config.brand.accent,
    muted: "#999999",
    surface: "#1A1A1A",
  },
  "vibrant": {
    bg: config.brand.primary,
    fg: "#FFFFFF",
    accent: config.brand.accent,
    muted: "rgba(255,255,255,0.7)",
    surface: config.brand.secondary,
  },
  "editorial": {
    bg: "#F8F5F0",
    fg: "#1A1A1A",
    accent: config.brand.primary,
    muted: "#7A7A7A",
    surface: "#EDE9E3",
  },
};

const theme = THEMES[config.theme];
幻灯片网格缩放

缩放每张手机幻灯片,使其能舒适地适应视口高度。计算一个统一的缩放比例,并应用到所有幻灯片包装元素:

const TOPBAR_H = 52;  // height of the top controls bar in px

const SCALE = Math.min(
  (window.innerHeight - TOPBAR_H - 64) / PHONE_H,          // fit vertically
  (window.innerWidth - 80) / (PHONE_W * config.slides.length + 20 * (config.slides.length - 1))
);

document.querySelectorAll(".slide-wrap").forEach(wrap => {
  wrap.style.width  = `${PHONE_W * SCALE}px`;
  wrap.style.height = `${PHONE_H * SCALE}px`;
});
document.querySelectorAll(".slide").forEach(slide => {
  slide.style.transform      = `scale(${SCALE})`;
  slide.style.transformOrigin = "top left";
});

功能图也会在同一行渲染。按比例缩放,使其高度在视觉上与手机幻灯片相匹配:

const fgScale = (PHONE_H * SCALE) / FG_H;
fgWrap.style.width  = `${FG_W * fgScale}px`;
fgWrap.style.height = `${FG_H * fgScale}px`;
fgEl.style.transform      = `scale(${fgScale})`;
fgEl.style.transformOrigin = "top left";

屏幕外的导出画布始终保持完整分辨率,切勿缩放。


功能图实现

功能图是独立组件,不是手机幻灯片。它在自己的 1024×500px 画布上渲染。

关键:强制使用精确的画布尺寸

必须通过 CSS 显式设置画布元素的尺寸,切勿让浏览器根据内容确定尺寸:

#feature-graphic-canvas {
  width: 1024px;
  height: 500px;
  position: relative;
  overflow: hidden;
  /* Never set width/height from JS or let it auto-size */
}

在网格预览中,使用 CSS transform: scale(...) 调整其视觉尺寸,但底层 DOM 元素必须保持精确的 1024×500。如果画布尺寸不正确,导出的 PNG 尺寸就会出错。

三种样式(通过配置中的 featureGraphic.style 设置)
gradient

整个画布使用从 brand.primary 到 brand.secondary 的对角渐变。叠加 2–3 个模糊光球以增加层次感(使用与手机幻灯片相同的技巧)。应用图标位于左侧三分之一处(垂直居中,180×180px)。标题位于中心偏右处,副文本位于下方。

┌──────────────────────────────────────────────────────────┐
│  ░░░░░░░░░░░░░░░░  gradient bg + subtle orbs  ░░░░░░░░░  │
│                                                           │
│   ┌──────┐   App Name                                     │
│   │ ICON │                                                │
│   │      │   Big headline here                            │
│   └──────┘   Available on Google Play                     │
│                                                           │
└──────────────────────────────────────────────────────────┘

适用场景:大多数应用。简洁、专业,适用于任何品牌颜色。

solid

使用 brand.background 平铺填充,添加一条细水平强调线(brand.primary)和居中的大型应用图标。标题和副文本居中显示在下方。

适用场景:实用工具类应用、效率工具,以及品牌形象简洁或极简的应用。

screenshot-backed

应用截图占据画布右侧 55%(裁剪,object-fit cover)。左侧 45% 是纯色 brand.primary 面板。两侧之间以渐变羽化过渡。标题和图标位于纯色面板上。

适用场景:视觉内容丰富的应用(摄影、设计、社交),展示 UI 本身就是卖点。

高级功能图构图

对功能图应用相同的装饰光球技巧:

.fg-orb {
  position: absolute;
  border-radius: 50%;
  filter: blur(80px);
  pointer-events: none;
}
/* Large orb upper-left, behind icon */
.fg-orb-1 {
  width: 300px; height: 300px;
  top: -60px; left: -40px;
  background: radial-gradient(circle, var(--brand-secondary) 0%, transparent 70%);
  opacity: 0.40;
}
/* Smaller orb lower-right */
.fg-orb-2 {
  width: 200px; height: 200px;
  bottom: -40px; right: 80px;
  background: radial-gradient(circle, var(--brand-primary) 0%, transparent 70%);
  opacity: 0.30;
}
功能图排版(按 FG_W = 1024 缩放)
const FGT = {
  headline: FG_W * 0.060,   // ~61px — confident, reads at small sizes
  subtext:  FG_W * 0.026,   // ~27px
  appName:  FG_W * 0.030,   // ~31px — shown above the headline
};

导出机制

使用 html-to-image(相比 html2canvas,它对 CSS 渐变、滤镜和 clip-path 的支持更好)。使用 JSZip + FileSaver.js 将所有导出文件打包为一个 ZIP 下载。

关键:双重调用模式

这是确保字体和图像正确渲染所必需的。第一次调用会预加载延迟加载的资源;第二次调用会生成干净的输出。跳过第一次调用会导致文本模糊或图像缺失。

下面的 captureSlide 辅助函数实现了此模式,并由 exportAll 调用:

// Moves the element on-screen momentarily (required by html-to-image),
// captures twice for clean output, then returns the data URL.
async function captureSlide(element) {
  element.style.left     = "0px";
  element.style.top      = "0px";
  element.style.position = "fixed";
  element.style.zIndex   = "9999";

  // First call: warms up fonts and images — result discarded
  await htmlToImage.toPng(element, { pixelRatio: 1 });

  // Second call: clean, correct output
  const dataUrl = await htmlToImage.toPng(element, { pixelRatio: 1 });

  // Restore to off-screen position
  element.style.left     = "-9999px";
  element.style.top      = "0px";
  element.style.position = "fixed";
  element.style.zIndex   = "-1";

  await new Promise((r) => setTimeout(r, 200));
  return dataUrl;
}
文件名规范

使用零填充数字前缀,确保文件系统和上传到 Play Store 时按字母顺序排序正确:

exports/phone/en/
├── 01-hero-1080x1920.png
├── 02-feature-one-1080x1920.png
├── 03-feature-two-1080x1920.png
├── 04-trust-1080x1920.png
└── 05-cta-1080x1920.png

exports/feature-graphic/
└── feature-graphic-1024x500.png
批量导出为 ZIP

所有幻灯片会收集到一个 ZIP 文件中,并通过一次点击下载。不单独下载各个文件。

// Capture helper — double-call pattern for clean font and image rendering
async function captureSlide(element) {
  element.style.left     = "0px";
  element.style.top      = "0px";
  element.style.position = "fixed";
  element.style.zIndex   = "9999";

  // First call: warms up lazy-loaded fonts and images — result discarded
  await htmlToImage.toPng(element, { pixelRatio: 1 });
  // Second call: clean, correct output
  const dataUrl = await htmlToImage.toPng(element, { pixelRatio: 1 });

  element.style.left     = "-9999px";
  element.style.top      = "0px";
  element.style.position = "fixed";
  element.style.zIndex   = "-1";

  await new Promise((r) => setTimeout(r, 200));
  return dataUrl;
}

async function exportAll() {
  const zip = new JSZip();
  const phoneFolder = zip.folder("phone");
  const fgFolder    = zip.folder("feature-graphic");

  for (const locale of config.locales) {
    const localeFolder = phoneFolder.folder(locale);

    // Phone slides
    for (let i = 0; i < config.slides.length; i++) {
      const el = document.getElementById(`canvas-${locale}-${config.slides[i].id}`);
      if (!el) continue;
      const name = `${String(i + 1).padStart(2, "0")}-${config.slides[i].id}-${PHONE_W}x${PHONE_H}.png`;
      const dataUrl = await captureSlide(el);
      localeFolder.file(name, dataUrl.split(",")[1], { base64: true });
    }

    // Feature graphic
    const fg = document.getElementById(`canvas-${locale}-feature-graphic`);
    if (fg) {
      const dataUrl = await captureSlide(fg);
      fgFolder.file(`feature-graphic-${FG_W}x${FG_H}.png`, dataUrl.split(",")[1], { base64: true });
    }

    // Tablet slides (if enabled)
    if (config.tablet && config.tablet.enabled) {
      for (const size of config.tablet.sizes) {
        const W = size === "10-inch" ? TAB10_W : TAB7_W;
        const H = size === "10-inch" ? TAB10_H : TAB7_H;
        const tabFolder = zip.folder(`tablet-${size}/${locale}`);
        for (let i = 0; i < config.slides.length; i++) {
          const el = document.getElementById(`canvas-tablet-${size}-${locale}-${config.slides[i].id}`);
          if (!el) continue;
          const name = `${String(i + 1).padStart(2, "0")}-${config.slides[i].id}-${W}x${H}.png`;
          const dataUrl = await captureSlide(el);
          tabFolder.file(name, dataUrl.split(",")[1], { base64: true });
        }
      }
    }
  }

  // Generate and trigger download of the ZIP
  const appSlug = config.app.name.replace(/\s+/g, "-").toLowerCase();
  const blob = await zip.generateAsync({ type: "blob" });
  saveAs(blob, `${appSlug}-play-store-screenshots.zip`);
}

点击一次即可生成 focusflow-play-store-screenshots.zip,其中包含按类型和语言区域整理的所有幻灯片。解压后即可上传到 Play Console。

多语言与 RTL 支持

截图会按语言区域整理到 exports/phone/ 下的文件夹中:

exports/phone/
├── en/
├── de/
└── ar/     ← RTL locale — layouts are mirrored

RTL 检测与布局镜像:

const RTL_LOCALES = new Set(["ar", "he", "fa", "ur"]);
const isRtl = RTL_LOCALES.has(selectedLocale);

// Apply dir attribute to each slide container element:
// slideEl.setAttribute("dir", isRtl ? "rtl" : "ltr");
//
// CSS flexbox respects dir automatically — text and layout mirror
// without needing manual position overrides.

当 config.locales 包含多个条目时,会在控件栏中构建一个语言区域 <select>。更改选项后,使用所选语言重新渲染所有预览幻灯片。


QA 检查清单

导出最终资源前,请检查以下所有项目。

内容

  • 每张幻灯片只传达一个观点——不要使用带有“和”的复合主张
  • 每个标题都能通过一臂距离下的一秒测试
  • 各幻灯片之间没有重复的功能
  • 整套内容具有叙事脉络:吸引注意 → 证明 → 建立信任 → CTA(或类似结构)
  • 副文本(如有)提供了新信息,而不是重复内容

视觉

  • 所有幻灯片均使用 layout: "text-top"(或至多一张使用 "full-bleed")——不使用其他布局值
  • 文本不会与手机边框重叠(若标题可能溢出,请保持简短)
  • 功能图片在 50% 缩放时仍清晰可读(即其在 Play 商店搜索结果中的显示效果)

Play 商店合规性

  • 至少导出 2 张手机截图
  • 每种设备类型最多导出 8 张手机截图
  • 功能图片的尺寸必须恰好为 1024 × 500px
  • 所有截图均为 JPEG 或 24 位 PNG——最终导出文件中不得包含 Alpha 通道/透明度
  • 所有文件均小于 8MB
  • 不得出现 iOS 风格的 UI 元素——包括灵动岛、iPhone 刘海形状、iOS 主屏幕指示条、iOS 状态栏样式
  • 任何位置都不得出现 Apple 品牌标识、App Store 徽章或 iOS 系统图标
  • 所有资源的背景均完全不透明

导出质量

  • 所有文本在完整分辨率下都清晰锐利(无模糊伪影)
  • 模拟图中的截图没有拉伸或变形——保持原始纵横比
  • 使用了双重调用导出模式(跳过此步骤会导致字体模糊)
  • 文件名使用零填充(01-、02-,而非 1-、2-)

导出后:上传到 Play Console

  1. 前往 Google Play Console → 您的应用 → 商店展示 → 主要商店详情
  2. 在手机截图下,按顺序上传 exports/phone/en/ 中的文件
  3. 在功能图片下,上传 feature-graphic-1024x500.png
  4. 如果生成了平板截图,请将其上传到对应的平板部分
  5. 保存并提交审核

Play 商店会即时处理上传内容——提交版本前无需等待资源审核。

评论

支持 Markdown