p5.js 生产流水线
何时使用
当用户请求以下内容时使用:p5.js 草图、创意编程、生成艺术、交互式可视化、画布动画、基于浏览器的视觉艺术、数据可视化、着色器效果,或任何 p5.js 项目。
内含内容
使用 p5.js 进行交互式和生成式视觉艺术的生产流水线。创建基于浏览器的草图、生成艺术、数据可视化、交互式体验、3D 场景、音频反应式视觉和动态图形——导出为 HTML、PNG、GIF、MP4 或 SVG。涵盖:2D/3D 渲染、噪声和粒子系统、流场、着色器 (GLSL)、像素操作、动态排版、WebGL 场景、音频分析、鼠标/键盘交互以及无头高分辨率导出。
创意标准
这是在浏览器中渲染的视觉艺术。画布是媒介,算法是画笔。
在编写一行代码之前,先阐述创意概念。这件作品传达了了什么?是什么让观众停下滚动?它如何区别于代码教程示例?用户的提示只是一个起点——带着创意雄心去诠释它。
首次渲染的卓越性是无可商量的。 输出必须在首次加载时在视觉上引人注目。如果它看起来像 p5.js 教程练习、默认配置或“AI 生成的创意代码”,那就错了。在交付之前重新思考。
超越参考词汇表。 参考中的噪声函数、粒子系统、调色板以及着色器效果只是一个起始词汇表。对于每个项目,要组合、叠加和创造。该目录是一套颜料——由你来创作画作。
主动发挥创意。 如果用户要求“一个粒子系统”,那么交付一个具有涌现群集行为、拖尾鬼影、调色板深度雾以及会呼吸的背景噪声场的粒子系统。至少包含一个用户未要求但会欣赏的视觉细节。
密集、分层、深思熟虑。 每一帧都应值得观看。永远不要使用纯白色背景。始终要有构图层次。始终要有有意的色彩。始终要有只有在近距离观察时才会显现的微观细节。
内聚美学高于功能数量。 所有元素都必须服务于统一的视觉语言——共享的色温、一致的描边权重词汇、和谐的运动速度。一个具有十个无关效果的草图,不如一个只有三个但彼此协调的草图。
模式
| 模式 | 输入 | 输出 | 参考 |
|---|---|---|---|
| 生成艺术 | 种子 / 参数 | 程序化视觉构图(静态或动画) | references/visual-effects.md |
| 数据可视化 | 数据集 / API | 交互式图表、图形、自定义数据展示 | references/interaction.md |
| 交互式体验 | 无(由用户驱动) | 鼠标/键盘/触摸驱动的草图 | references/interaction.md |
| 动画 / 动态图形 | 时间线 / 故事板 | 定时序列、动态排版、转场 | references/animation.md |
| 3D 场景 | 概念描述 | WebGL 几何体、光照、相机、材质 | references/webgl-and-3d.md |
| 图像处理 | 图像文件 | 像素操作、滤镜、马赛克、点彩 | references/visual-effects.md § 像素操作 |
| 音频反应式 | 音频文件 / 麦克风 | 声音驱动的生成视觉 | references/interaction.md § 音频输入 |
技术栈
每个项目使用单个自包含的 HTML 文件。无需构建步骤。
| 层 | 工具 | 用途 |
|---|---|---|
| 核心 | p5.js 1.11.3 (CDN) | 画布渲染、数学、变换、事件处理 |
| 3D | p5.js WebGL 模式 | 3D 几何体、相机、光照、GLSL 着色器 |
| 音频 | p5.sound.js (CDN) | FFT 分析、振幅、麦克风输入、振荡器 |
| 导出 | 内置 saveCanvas() / saveGif() / saveFrames() | PNG、GIF、帧序列输出 |
| 捕获 | CCapture.js (可选) | 确定性帧率视频捕获 (WebM, GIF) |
| 无头 | Puppeteer + Node.js (可选) | 自动化高分辨率渲染,通过 ffmpeg 生成 MP4 |
| SVG | p5.js-svg 1.6.0 (可选) | 用于打印的矢量输出——需要 p5.js 1.x |
| 自然介质 | p5.brush (可选) | 水彩、炭笔、钢笔——需要 p5.js 2.x + WEBGL |
| 纹理 | p5.grain (可选) | 胶片颗粒、纹理叠加 |
| 字体 | Google Fonts / loadFont() | 通过 OTF/TTF/WOFF2 实现自定义排版 |
版本说明
p5.js 1.x (1.11.3) 是默认版本——稳定、文档齐全、库兼容性最广。除非项目需要 2.x 特性,否则请使用此版本。
p5.js 2.x (2.2+) 新增:async setup() 取代 preload()、OKLCH/OKLAB 颜色模式、splineVertex()、着色器 .modify() API、可变字体、textToContours()、指针事件。p5.brush 需要使用它。请参阅 references/core-api.md § p5.js 2.0。
流水线
每个项目都遵循相同的 6 阶段路径:
概念 → 设计 → 编码 → 预览 → 导出 → 验证
- 概念 — 阐述创意愿景:情绪、色彩世界、运动词汇、使其独特之处
- 设计 — 选择模式、画布尺寸、交互模型、颜色系统、导出格式。将概念映射到技术决策
- 编码 — 编写带有内联 p5.js 的单个 HTML 文件。结构:全局变量 →
preload()→setup()→draw()→ 辅助函数 → 类 → 事件处理 - 预览 — 在浏览器中打开,验证视觉质量。在目标分辨率下测试。检查性能
- 导出 — 捕获输出:使用
saveCanvas()导出 PNG,saveGif()导出 GIF,saveFrames()+ ffmpeg 导出 MP4,Puppeteer 用于无头批处理 - 验证 — 输出是否符合概念?在预期显示尺寸下是否视觉上引人注目?你会把它装裱起来吗?
创意指导
美学维度
| 维度 | 选项 | 参考 |
|---|---|---|
| 颜色系统 | HSB/HSL、RGB、命名调色板、程序化和谐、渐变插值 | references/color-systems.md |
| 噪声词汇 | Perlin 噪声、Simplex 噪声、分形 (八度)、域扭曲、旋度噪声 | references/visual-effects.md § 噪声 |
| 粒子系统 | 基于物理的、群集、拖尾绘制、吸引子驱动、流场跟随 | references/visual-effects.md § 粒子 |
| 形状语言 | 几何图元、自定义顶点、贝塞尔曲线、SVG 路径 | references/shapes-and-geometry.md |
| 运动风格 | 缓动、基于弹簧、噪声驱动、物理模拟、lerp、步进 | references/animation.md |
| 排版 | 系统字体、加载的 OTF、textToPoints() 粒子文本、动态 | references/typography.md |
| 着色器效果 | GLSL 片段/顶点、滤镜着色器、后处理、反馈循环 | references/webgl-and-3d.md § 着色器 |
| 构图 | 网格、径向、黄金比例、三分法、有机分散、平铺 | references/core-api.md § 构图 |
| 交互模型 | 鼠标跟随、点击生成、拖拽、键盘状态、滚动驱动、麦克风输入 | references/interaction.md |
| 混合模式 | BLEND、ADD、MULTIPLY、SCREEN、DIFFERENCE、EXCLUSION、OVERLAY | references/color-systems.md § 混合模式 |
| 分层 | 使用 createGraphics() 的离屏缓冲区、Alpha 合成、遮罩 | references/core-api.md § 离屏缓冲区 |
| 纹理 | Perlin 表面、点画、影线、半色调、像素排序 | references/visual-effects.md § 纹理生成 |
每个项目的变异规则
永远不要使用默认配置。对于每个项目:
- 自定义调色板 — 永远不要使用原始的
fill(255, 0, 0)。始终使用包含 3-7 种颜色的设计调色板 - 自定义描边权重词汇 — 细的强调 (0.5)、中等的结构 (1-2)、粗的强调 (3-5)
- 背景处理 — 永远不要使用简单的
background(0)或background(255)。始终使用有纹理的、渐变的或分层的背景 - 运动多样性 — 不同元素使用不同速度。主要元素 1x、次要元素 0.3x、环境元素 0.1x
- 至少一个发明元素 — 自定义粒子行为、新颖的噪声应用、独特的交互响应
项目特定的发明
对于每个项目,至少发明以下之一:
- 匹配情绪的自定义调色板(不是预设的)
- 新颖的噪声场组合(例如,旋度噪声+域扭曲+反馈)
- 独特的粒子行为(自定义力、自定义轨迹、自定义生成)
- 用户未请求但能提升作品的交互机制
- 创造视觉层次的构图技巧
参数设计哲学
参数应从算法中涌现,而不是来自通用菜单。自问:“这个系统的哪些属性应该是可调的?”
好的参数 暴露了算法的特征:
- 数量 — 有多少粒子、分支、细胞(控制密度)
- 尺度 — 噪声频率、元素大小、间距(控制纹理)
- 速率 — 速度、生长速率、衰减(控制能量)
- 阈值 — 行为何时变化?(控制戏剧性)
- 比率 — 比例、力之间的平衡(控制和谐)
坏的参数 是与算法无关的通用控件:
- 脱离上下文的“color1”、“color2”、“size”
- 不相关效果的切换开关
- 只改变外观而不改变行为的参数
每个参数都应改变算法思考的方式,而不仅仅是它看起来的样子。一个改变噪声八度的“湍流”参数是好的。一个只改变 ellipse() 半径的“粒子大小”滑块是肤浅的。
工作流
第一步:创意愿景
在编写任何代码之前,阐述:
- 情绪 / 氛围:观众应该感受到什么?沉思的?充满活力的?不安的?有趣的?
- 视觉故事:随时间(或交互)发生什么?构建?衰变?变换?振荡?
- 色彩世界:暖色/冷色?单色?互补色?主色调是什么?强调色是什么?
- 形状语言:有机曲线?锐利几何?点?线?混合?
- 运动词汇:缓慢漂移?爆发式迸发?呼吸般的脉冲?机械般的精确?
- 此作品的独特之处:让此草图与众不同的一个特点是什么?
将用户的提示映射到美学选择。“轻松的生成背景”与“故障数据可视化”所要求的一切都不同。
第二步:技术设计
- 模式 — 上表中 7 种模式中的哪一种
- 画布尺寸 — 横向 1920x1080、纵向 1080x1920、方形 1080x1080,或响应式
windowWidth/windowHeight - 渲染器 —
P2D(默认)或WEBGL(用于 3D、着色器、高级混合模式) - 帧率 — 60fps(交互式)、30fps(环境动画)或
noLoop()(静态生成) - 导出目标 — 浏览器显示、PNG 静态图、GIF 循环、MP4 视频、SVG 矢量图
- 交互模型 — 被动(无输入)、鼠标驱动、键盘驱动、音频反应式、滚动驱动
- 查看器 UI — 对于交互式生成艺术,从
templates/viewer.html开始,它提供种子导航、参数滑块和下载功能。对于简单的草图或视频导出,使用纯 HTML
第三步:编写草图代码
对于交互式生成艺术(种子探索、参数调整):从 templates/viewer.html 开始。先阅读模板,保留固定部分(种子导航、操作),替换算法和参数控件。这为用户提供了种子上一个/下一个/随机/跳转、带有实时更新的参数滑块以及 PNG 下载——所有功能都已连接好。
对于动画、视频导出或简单草图:使用纯 HTML:
单个 HTML 文件。结构:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>项目名称</title>
<script>p5.disableFriendlyErrors = true;</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.3/p5.min.js"></script>
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.3/addons/p5.sound.min.js"></script> -->
<!-- <script src="https://unpkg.com/[email protected]"></script> --> <!-- SVG 导出 -->
<!-- <script src="https://cdn.jsdelivr.net/npm/ccapture.js-npmfixed/build/CCapture.all.min.js"></script> --> <!-- 视频捕获 -->
<style>
html, body { margin: 0; padding: 0; overflow: hidden; }
canvas { display: block; }
</style>
</head>
<body>
<script>
// === 配置 ===
const CONFIG = {
seed: 42,
// ... 项目特定参数
};
// === 调色板 ===
const PALETTE = {
bg: '#0a0a0f',
primary: '#e8d5b7',
// ...
};
// === 全局状态 ===
let particles = [];
// === 预加载 (字体、图像、数据) ===
function preload() {
// font = loadFont('...');
}
// === 设置 ===
function setup() {
createCanvas(1920, 1080);
randomSeed(CONFIG.seed);
noiseSeed(CONFIG.seed);
colorMode(HSB, 360, 100, 100, 100);
// 初始化状态...
}
// === 绘制循环 ===
function draw() {
// 渲染帧...
}
// === 辅助函数 ===
// ...
// === 类 ===
class Particle {
// ...
}
// === 事件处理 ===
function mousePressed() { /* ... */ }
function keyPressed() { /* ... */ }
function windowResized() { resizeCanvas(windowWidth, windowHeight); }
</script>
</body>
</html>
关键实现模式:
- 种子随机性:始终使用
randomSeed()+noiseSeed()以实现可复现性 - 颜色模式:使用
colorMode(HSB, 360, 100, 100, 100)实现直观的颜色控制 - 状态分离:CONFIG 用于参数,PALETTE 用于颜色,全局变量用于可变状态
- 基于类的实体:将粒子、代理、形状作为类来实现,带有
update()+display()方法 - 离屏缓冲区:使用
createGraphics()实现分层合成、轨迹、遮罩
第四步:预览与迭代
- 直接在浏览器中打开 HTML 文件——基本草图无需服务器
- 对于从本地文件加载
loadImage()/loadFont():使用scripts/serve.sh或python3 -m http.server - 使用 Chrome DevTools 的性能选项卡来验证 60fps
- 在目标导出分辨率下测试,而不仅仅是窗口大小
- 调整参数,直到视觉效果与第一步中的概念相匹配