p5js
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinesep5.js Production Pipeline
p5.js 生产工作流
When to use
适用场景
Use when users request: p5.js sketches, creative coding, generative art, interactive visualizations, canvas animations, browser-based visual art, data viz, shader effects, or any p5.js project.
当用户需求包含以下内容时使用:p5.js创意编程作品、创意编码、生成艺术、交互可视化、画布动画、基于浏览器的视觉艺术、数据可视化、着色器效果,或任何p5.js相关项目。
What's inside
内容概述
Production pipeline for interactive and generative visual art using p5.js. Creates browser-based sketches, generative art, data visualizations, interactive experiences, 3D scenes, audio-reactive visuals, and motion graphics — exported as HTML, PNG, GIF, MP4, or SVG. Covers: 2D/3D rendering, noise and particle systems, flow fields, shaders (GLSL), pixel manipulation, kinetic typography, WebGL scenes, audio analysis, mouse/keyboard interaction, and headless high-res export.
基于p5.js的交互与生成视觉艺术生产工作流。可创建基于浏览器的创意编程作品、生成艺术、数据可视化、交互体验、3D场景、音频响应式视觉效果和动态图形,并导出为HTML、PNG、GIF、MP4或SVG格式。涵盖:2D/3D渲染、噪声与粒子系统、流场、着色器(GLSL)、像素操作、动态排版、WebGL场景、音频分析、鼠标/键盘交互,以及无界面高分辨率导出。
Creative Standard
创意标准
This is visual art rendered in the browser. The canvas is the medium; the algorithm is the brush.
Before writing a single line of code, articulate the creative concept. What does this piece communicate? What makes the viewer stop scrolling? What separates this from a code tutorial example? The user's prompt is a starting point — interpret it with creative ambition.
First-render excellence is non-negotiable. The output must be visually striking on first load. If it looks like a p5.js tutorial exercise, a default configuration, or "AI-generated creative coding," it is wrong. Rethink before shipping.
Go beyond the reference vocabulary. The noise functions, particle systems, color palettes, and shader effects in the references are a starting vocabulary. For every project, combine, layer, and invent. The catalog is a palette of paints — you write the painting.
Be proactively creative. If the user asks for "a particle system," deliver a particle system with emergent flocking behavior, trailing ghost echoes, palette-shifted depth fog, and a background noise field that breathes. Include at least one visual detail the user didn't ask for but will appreciate.
Dense, layered, considered. Every frame should reward viewing. Never flat white backgrounds. Always compositional hierarchy. Always intentional color. Always micro-detail that only appears on close inspection.
Cohesive aesthetic over feature count. All elements must serve a unified visual language — shared color temperature, consistent stroke weight vocabulary, harmonious motion speeds. A sketch with ten unrelated effects is worse than one with three that belong together.
这是在浏览器中渲染的视觉艺术。画布是创作媒介,算法是画笔。
在编写任何代码之前,先明确创意概念。这件作品要传达什么?什么能让观众停下滑动的手指?它和代码教程示例的区别在哪里?用户的提示只是起点——要用创意野心去诠释它。
首次渲染效果必须出色,这是硬性要求。 输出内容在首次加载时必须具有视觉冲击力。如果它看起来像p5.js教程练习、默认配置或“AI生成的创意编码”,那就是错误的。交付前重新构思。
超越参考词汇的局限。 参考资料中的噪声函数、粒子系统、调色板和着色器效果只是基础词汇。每个项目都要进行组合、分层和创新。参考目录是颜料盘——而你要创作完整的画作。
主动发挥创意。 如果用户要求“一个粒子系统”,就要交付一个具备涌现集群行为、拖尾虚影、调色板偏移深度雾效,以及可呼吸背景噪声场的粒子系统。至少要加入一个用户没要求但会欣赏的视觉细节。
内容密集、层次丰富、构思严谨。 每一帧都值得细细观赏。永远不要用纯白背景。始终要有构图层次。始终要有精心设计的色彩。始终要有只有近距离观察才能发现的微细节。
审美统一性优先于功能数量。 所有元素都必须服务于统一的视觉语言——统一的色温、一致的描边粗细体系、协调的运动速度。一个包含十个无关效果的作品,不如一个包含三个和谐效果的作品。
Modes
模式
| Mode | Input | Output | Reference |
|---|---|---|---|
| Generative art | Seed / parameters | Procedural visual composition (still or animated) | |
| Data visualization | Dataset / API | Interactive charts, graphs, custom data displays | |
| Interactive experience | None (user drives) | Mouse/keyboard/touch-driven sketch | |
| Animation / motion graphics | Timeline / storyboard | Timed sequences, kinetic typography, transitions | |
| 3D scene | Concept description | WebGL geometry, lighting, camera, materials | |
| Image processing | Image file(s) | Pixel manipulation, filters, mosaic, pointillism | |
| Audio-reactive | Audio file / mic | Sound-driven generative visuals | |
| 模式 | 输入 | 输出 | 参考资料 |
|---|---|---|---|
| 生成艺术 | 随机种子 / 参数 | 程序化视觉构图(静态或动态) | |
| 数据可视化 | 数据集 / API | 交互式图表、图形、自定义数据展示 | |
| 交互体验 | 无(由用户驱动) | 鼠标/键盘/触摸驱动的创意编程作品 | |
| 动画 / 动态图形 | 时间线 / 分镜脚本 | 定时序列、动态排版、转场效果 | |
| 3D场景 | 概念描述 | WebGL几何结构、光照、相机、材质 | |
| 图像处理 | 图像文件 | 像素操作、滤镜、马赛克、点画法 | |
| 音频响应式 | 音频文件 / 麦克风 | 声音驱动的生成视觉效果 | |
Stack
技术栈
Single self-contained HTML file per project. No build step required.
| Layer | Tool | Purpose |
|---|---|---|
| Core | p5.js 1.11.3 (CDN) | Canvas rendering, math, transforms, event handling |
| 3D | p5.js WebGL mode | 3D geometry, camera, lighting, GLSL shaders |
| Audio | p5.sound.js (CDN) | FFT analysis, amplitude, mic input, oscillators |
| Export | Built-in | PNG, GIF, frame sequence output |
| Capture | CCapture.js (optional) | Deterministic framerate video capture (WebM, GIF) |
| Headless | Puppeteer + Node.js (optional) | Automated high-res rendering, MP4 via ffmpeg |
| SVG | p5.js-svg 1.6.0 (optional) | Vector output for print — requires p5.js 1.x |
| Natural media | p5.brush (optional) | Watercolor, charcoal, pen — requires p5.js 2.x + WEBGL |
| Texture | p5.grain (optional) | Film grain, texture overlays |
| Fonts | Google Fonts / | Custom typography via OTF/TTF/WOFF2 |
每个项目对应一个独立的HTML文件,无需构建步骤。
| 层级 | 工具 | 用途 |
|---|---|---|
| 核心 | p5.js 1.11.3(CDN) | 画布渲染、数学计算、变换处理、事件处理 |
| 3D | p5.js WebGL模式 | 3D几何结构、相机、光照、GLSL着色器 |
| 音频 | p5.sound.js(CDN) | FFT分析、振幅检测、麦克风输入、振荡器 |
| 导出 | 内置 | 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 / | 通过OTF/TTF/WOFF2实现自定义排版 |
Version Note
版本说明
p5.js 1.x (1.11.3) is the default — stable, well-documented, broadest library compatibility. Use this unless a project requires 2.x features.
p5.js 2.x (2.2+) adds: replacing , OKLCH/OKLAB color modes, , shader API, variable fonts, , pointer events. Required for p5.brush. See § p5.js 2.0.
async setup()preload()splineVertex().modify()textToContours()references/core-api.mdp5.js 1.x(1.11.3)是默认版本——稳定、文档完善、库兼容性最广。除非项目需要2.x版本的功能,否则使用此版本。
p5.js 2.x(2.2+)新增功能:替代、OKLCH/OKLAB颜色模式、、着色器 API、可变字体、、指针事件。使用p5.brush时必须选择此版本。详见 § p5.js 2.0。
async setup()preload()splineVertex().modify()textToContours()references/core-api.mdPipeline
工作流
Every project follows the same 6-stage path:
CONCEPT → DESIGN → CODE → PREVIEW → EXPORT → VERIFY- CONCEPT — Articulate the creative vision: mood, color world, motion vocabulary, what makes this unique
- DESIGN — Choose mode, canvas size, interaction model, color system, export format. Map concept to technical decisions
- CODE — Write single HTML file with inline p5.js. Structure: globals → →
preload()→setup()→ helpers → classes → event handlersdraw() - PREVIEW — Open in browser, verify visual quality. Test at target resolution. Check performance
- EXPORT — Capture output: for PNG,
saveCanvas()for GIF,saveGif()+ ffmpeg for MP4, Puppeteer for headless batchsaveFrames() - VERIFY — Does the output match the concept? Is it visually striking at the intended display size? Would you frame it?
每个项目都遵循相同的6阶段流程:
概念构思 → 设计规划 → 代码实现 → 预览调试 → 导出输出 → 质量验证- 概念构思 — 明确创意愿景:氛围、色彩体系、运动风格,以及作品的独特之处
- 设计规划 — 选择模式、画布尺寸、交互模型、色彩系统、导出格式。将概念转化为技术决策
- 代码实现 — 编写包含内嵌p5.js的独立HTML文件。结构:全局变量 → →
preload()→setup()→ 辅助函数 → 类 → 事件处理函数draw() - 预览调试 — 在浏览器中打开,验证视觉质量。在目标分辨率下测试,检查性能
- 导出输出 — 捕获输出内容:生成PNG,
saveCanvas()生成GIF,saveGif()+ ffmpeg生成MP4,Puppeteer用于无界面批量渲染saveFrames() - 质量验证 — 输出内容是否符合概念?在预期显示尺寸下是否具有视觉冲击力?你愿意把它装裱起来吗?
Creative Direction
创意指导
Aesthetic Dimensions
审美维度
| Dimension | Options | Reference |
|---|---|---|
| Color system | HSB/HSL, RGB, named palettes, procedural harmony, gradient interpolation | |
| Noise vocabulary | Perlin noise, simplex, fractal (octaved), domain warping, curl noise | |
| Particle systems | Physics-based, flocking, trail-drawing, attractor-driven, flow-field following | |
| Shape language | Geometric primitives, custom vertices, bezier curves, SVG paths | |
| Motion style | Eased, spring-based, noise-driven, physics sim, lerped, stepped | |
| Typography | System fonts, loaded OTF, | |
| Shader effects | GLSL fragment/vertex, filter shaders, post-processing, feedback loops | |
| Composition | Grid, radial, golden ratio, rule of thirds, organic scatter, tiled | |
| Interaction model | Mouse follow, click spawn, drag, keyboard state, scroll-driven, mic input | |
| Blend modes | | |
| Layering | | |
| Texture | Perlin surface, stippling, hatching, halftone, pixel sorting | |
| 维度 | 选项 | 参考资料 |
|---|---|---|
| 色彩系统 | HSB/HSL、RGB、预设调色板、程序化色彩和谐、渐变插值 | |
| 噪声词汇 | Perlin噪声、单纯形噪声、分形噪声(多八度)、域扭曲、卷曲噪声 | |
| 粒子系统 | 基于物理、集群行为、拖尾绘制、吸引子驱动、流场跟随 | |
| 形状语言 | 几何基本图形、自定义顶点、贝塞尔曲线、SVG路径 | |
| 运动风格 | 缓动、弹簧物理、噪声驱动、物理模拟、线性插值、步进式 | |
| 排版 | 系统字体、加载的OTF字体、 | |
| 着色器效果 | GLSL片段/顶点着色器、滤镜着色器、后期处理、反馈循环 | |
| 构图 | 网格、放射状、黄金比例、三分法、有机散布、平铺 | |
| 交互模型 | 鼠标跟随、点击生成、拖拽、键盘状态、滚动驱动、麦克风输入 | |
| 混合模式 | | |
| 分层 | | |
| 纹理 | Perlin表面、点画、影线、半色调、像素排序 | |
Per-Project Variation Rules
项目差异化规则
Never use default configurations. For every project:
- Custom color palette — never raw . Always a designed palette with 3-7 colors
fill(255, 0, 0) - Custom stroke weight vocabulary — thin accents (0.5), medium structure (1-2), bold emphasis (3-5)
- Background treatment — never plain or
background(0). Always textured, gradient, or layeredbackground(255) - Motion variety — different speeds for different elements. Primary at 1x, secondary at 0.3x, ambient at 0.1x
- At least one invented element — a custom particle behavior, a novel noise application, a unique interaction response
永远不要使用默认配置。每个项目都要:
- 自定义调色板 — 绝不直接使用这类原始值。始终使用包含3-7种颜色的设计调色板
fill(255, 0, 0) - 自定义描边粗细体系 — 细线条强调(0.5)、中等结构线(1-2)、粗线条突出(3-5)
- 背景处理 — 绝不使用单纯的或
background(0)。始终使用纹理、渐变或分层背景background(255) - 运动多样性 — 不同元素使用不同速度。主元素1x速度,次要元素0.3x,环境元素0.1x
- 至少一个独创元素 — 自定义粒子行为、新颖的噪声应用、独特的交互响应
Project-Specific Invention
项目专属创新
For every project, invent at least one of:
- A custom color palette matching the mood (not a preset)
- A novel noise field combination (e.g., curl noise + domain warp + feedback)
- A unique particle behavior (custom forces, custom trails, custom spawning)
- An interaction mechanic the user didn't request but that elevates the piece
- A compositional technique that creates visual hierarchy
每个项目都要至少实现以下一项创新:
- 符合氛围的自定义调色板(非预设)
- 新颖的噪声场组合(例如:卷曲噪声 + 域扭曲 + 反馈)
- 独特的粒子行为(自定义作用力、自定义拖尾、自定义生成逻辑)
- 用户未要求但能提升作品质感的交互机制
- 能创建视觉层次的构图技巧
Parameter Design Philosophy
参数设计理念
Parameters should emerge from the algorithm, not from a generic menu. Ask: "What properties of this system should be tunable?"
Good parameters expose the algorithm's character:
- Quantities — how many particles, branches, cells (controls density)
- Scales — noise frequency, element size, spacing (controls texture)
- Rates — speed, growth rate, decay (controls energy)
- Thresholds — when does behavior change? (controls drama)
- Ratios — proportions, balance between forces (controls harmony)
Bad parameters are generic controls unrelated to the algorithm:
- "color1", "color2", "size" — meaningless without context
- Toggle switches for unrelated effects
- Parameters that only change cosmetics, not behavior
Every parameter should change how the algorithm thinks, not just how it looks. A "turbulence" parameter that changes noise octaves is good. A "particle size" slider that only changes radius is shallow.
ellipse()参数应源于算法本身,而非通用菜单。要问:“这个系统的哪些属性应该是可调的?”
优质参数能展现算法的特性:
- 数量 — 粒子、分支、单元格的数量(控制密度)
- 比例 — 噪声频率、元素尺寸、间距(控制纹理)
- 速率 — 速度、生长速率、衰减速率(控制能量)
- 阈值 — 行为何时发生变化?(控制戏剧性)
- 比率 — 比例、作用力之间的平衡(控制和谐度)
劣质参数是与算法无关的通用控制项:
- "color1"、"color2"、"size" — 脱离上下文毫无意义
- 用于无关效果的切换开关
- 仅改变外观而非行为的参数
每个参数都应改变算法的“运行逻辑”,而不仅仅是“视觉表现”。一个能改变噪声八度的“湍流”参数是优质的。一个仅改变半径的“粒子大小”滑块则是肤浅的。
ellipse()Workflow
工作流程
Step 1: Creative Vision
步骤1:创意愿景
Before any code, articulate:
- Mood / atmosphere: What should the viewer feel? Contemplative? Energized? Unsettled? Playful?
- Visual story: What happens over time (or on interaction)? Build? Decay? Transform? Oscillate?
- Color world: Warm/cool? Monochrome? Complementary? What's the dominant hue? The accent?
- Shape language: Organic curves? Sharp geometry? Dots? Lines? Mixed?
- Motion vocabulary: Slow drift? Explosive burst? Breathing pulse? Mechanical precision?
- What makes THIS different: What is the one thing that makes this sketch unique?
Map the user's prompt to aesthetic choices. "Relaxing generative background" demands different everything from "glitch data visualization."
编写代码前,先明确:
- 氛围/情绪:观众应该有什么感受?沉思?兴奋?不安?愉悦?
- 视觉叙事:随着时间推移(或交互)会发生什么?构建?衰减?变形?振荡?
- 色彩体系:暖色调/冷色调?单色?互补色?主色调是什么?强调色是什么?
- 形状语言:有机曲线?锐利几何?圆点?线条?混合风格?
- 运动风格:缓慢漂移?爆发式?呼吸式脉动?机械精度?
- 独特之处:这件创意编程作品的独特卖点是什么?
将用户的提示映射到审美选择。“放松的生成式背景”与“故障风格数据可视化”的所有设计都截然不同。
Step 2: Technical Design
步骤2:技术设计
- Mode — which of the 7 modes from the table above
- Canvas size — landscape 1920x1080, portrait 1080x1920, square 1080x1080, or responsive
windowWidth/windowHeight - Renderer — (default) or
P2D(for 3D, shaders, advanced blend modes)WEBGL - Frame rate — 60fps (interactive), 30fps (ambient animation), or (static generative)
noLoop() - Export target — browser display, PNG still, GIF loop, MP4 video, SVG vector
- Interaction model — passive (no input), mouse-driven, keyboard-driven, audio-reactive, scroll-driven
- Viewer UI — for interactive generative art, start from which provides seed navigation, parameter sliders, and download. For simple sketches or video export, use bare HTML
templates/viewer.html
- 模式 — 选择上述7种模式中的一种
- 画布尺寸 — 横版1920x1080、竖版1080x1920、正方形1080x1080,或响应式
windowWidth/windowHeight - 渲染器 — (默认)或
P2D(用于3D、着色器、高级混合模式)WEBGL - 帧率 — 60fps(交互场景)、30fps(氛围动画),或(静态生成艺术)
noLoop() - 导出目标 — 浏览器展示、PNG静态图、GIF循环动画、MP4视频、SVG矢量图
- 交互模型 — 被动(无输入)、鼠标驱动、键盘驱动、音频响应式、滚动驱动
- 查看器UI — 对于交互式生成艺术,从开始,该模板提供种子导航、参数滑块和下载功能。对于简单作品或视频导出,使用纯HTML
templates/viewer.html
Step 3: Code the Sketch
步骤3:编写创意编程作品代码
For interactive generative art (seed exploration, parameter tuning): start from . Read the template first, keep the fixed sections (seed nav, actions), replace the algorithm and parameter controls. This gives the user seed prev/next/random/jump, parameter sliders with live update, and PNG download — all wired up.
templates/viewer.htmlFor animations, video export, or simple sketches: use bare HTML:
Single HTML file. Structure:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Project Name</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/p5.js-svg@1.6.0"></script> --> <!-- SVG export -->
<!-- <script src="https://cdn.jsdelivr.net/npm/ccapture.js-npmfixed/build/CCapture.all.min.js"></script> --> <!-- video capture -->
<style>
html, body { margin: 0; padding: 0; overflow: hidden; }
canvas { display: block; }
</style>
</head>
<body>
<script>
// === Configuration ===
const CONFIG = {
seed: 42,
// ... project-specific params
};
// === Color Palette ===
const PALETTE = {
bg: '#0a0a0f',
primary: '#e8d5b7',
// ...
};
// === Global State ===
let particles = [];
// === Preload (fonts, images, data) ===
function preload() {
// font = loadFont('...');
}
// === Setup ===
function setup() {
createCanvas(1920, 1080);
randomSeed(CONFIG.seed);
noiseSeed(CONFIG.seed);
colorMode(HSB, 360, 100, 100, 100);
// Initialize state...
}
// === Draw Loop ===
function draw() {
// Render frame...
}
// === Helper Functions ===
// ...
// === Classes ===
class Particle {
// ...
}
// === Event Handlers ===
function mousePressed() { /* ... */ }
function keyPressed() { /* ... */ }
function windowResized() { resizeCanvas(windowWidth, windowHeight); }
</script>
</body>
</html>Key implementation patterns:
- Seeded randomness: Always +
randomSeed()for reproducibilitynoiseSeed() - Color mode: Use for intuitive color control
colorMode(HSB, 360, 100, 100, 100) - State separation: CONFIG for parameters, PALETTE for colors, globals for mutable state
- Class-based entities: Particles, agents, shapes as classes with +
update()methodsdisplay() - Offscreen buffers: for layered composition, trails, masks
createGraphics()
对于交互式生成艺术(种子探索、参数调优):从开始。先阅读模板,保留固定部分(种子导航、操作按钮),替换算法和参数控件。这样用户就能使用种子上一个/下一个/随机/跳转功能、实时更新的参数滑块,以及PNG下载功能——所有功能都已配置完成。
templates/viewer.html对于动画、视频导出或简单作品:使用纯HTML:
单个HTML文件。结构如下:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Project Name</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/p5.js-svg@1.6.0"></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()
Step 4: Preview & Iterate
步骤4:预览与迭代
- Open HTML file directly in browser — no server needed for basic sketches
- For /
loadImage()from local files: useloadFont()orscripts/serve.shpython3 -m http.server - Chrome DevTools Performance tab to verify 60fps
- Test at target export resolution, not just the window size
- Adjust parameters until the visual matches the concept from Step 1
- 直接在浏览器中打开HTML文件——基础作品无需服务器
- 若要从本地文件加载/
loadImage():使用loadFont()或scripts/serve.shpython3 -m http.server - 使用Chrome DevTools性能面板验证是否达到60fps
- 在目标导出分辨率下测试,而非仅窗口大小
- 调整参数直到视觉效果符合步骤1的概念
Step 5: Export
步骤5:导出
| Format | Method | Command |
|---|---|---|
| PNG | | Press 's' to save |
| High-res PNG | Puppeteer headless capture | |
| GIF | | Press 'g' to save |
| Frame sequence | | Then |
| MP4 | Puppeteer frame capture + ffmpeg | |
| SVG | | |
| 格式 | 方法 | 命令 |
|---|---|---|
| PNG | 在 | 按's'键保存 |
| 高分辨率PNG | Puppeteer无界面捕获 | |
| GIF | | 按'g'键保存 |
| 帧序列 | | 然后执行 |
| MP4 | Puppeteer帧捕获 + ffmpeg | |
| SVG | 使用p5.js-svg时调用 | |
Step 6: Quality Verification
步骤6:质量验证
- Does it match the vision? Compare output to the creative concept. If it looks generic, go back to Step 1
- Resolution check: Is it sharp at the target display size? No aliasing artifacts?
- Performance check: Does it hold 60fps in browser? (30fps minimum for animations)
- Color check: Do the colors work together? Test on both light and dark monitors
- Edge cases: What happens at canvas edges? On resize? After running for 10 minutes?
- 是否符合愿景? 将输出内容与创意概念对比。如果看起来很通用,回到步骤1重新构思
- 分辨率检查:在目标显示尺寸下是否清晰?有无锯齿 artifacts?
- 性能检查:在浏览器中能否保持60fps?(动画最低要求30fps)
- 色彩检查:颜色搭配是否和谐?在亮色和暗色显示器上都测试
- 边缘情况:画布边缘会发生什么?窗口调整大小时呢?运行10分钟后呢?
Critical Implementation Notes
关键实现注意事项
Performance — Disable FES First
性能 — 首先禁用FES
The Friendly Error System (FES) adds up to 10x overhead. Disable it in every production sketch:
javascript
p5.disableFriendlyErrors = true; // BEFORE setup()
function setup() {
pixelDensity(1); // prevent 2x-4x overdraw on retina
createCanvas(1920, 1080);
}In hot loops (particles, pixel ops), use instead of p5 wrappers — measurably faster:
Math.*javascript
// In draw() or update() hot paths:
let a = Math.sin(t); // not sin(t)
let r = Math.sqrt(dx*dx+dy*dy); // not dist() — or better: skip sqrt, compare magSq
let v = Math.random(); // not random() — when seed not needed
let m = Math.min(a, b); // not min(a, b)Never inside . Never manipulate DOM in . See § Performance.
console.log()draw()draw()references/troubleshooting.md友好错误系统(FES)会增加高达10倍的性能开销。在所有生产级作品中禁用它:
javascript
p5.disableFriendlyErrors = true; // 在setup()之前
function setup() {
pixelDensity(1); // 避免视网膜屏幕上2x-4x的过度绘制
createCanvas(1920, 1080);
}在热点循环(粒子、像素操作)中,使用而非p5包装函数——速度明显更快:
Math.*javascript
// 在draw()或update()热点路径中:
let a = Math.sin(t); // 不用sin(t)
let r = Math.sqrt(dx*dx+dy*dy); // 不用dist() — 或者更好:跳过开方,比较magSq
let v = Math.random(); // 不需要种子时不用random()
let m = Math.min(a, b); // 不用min(a, b)绝不在中使用。绝不在中操作DOM。详见 § 性能。
draw()console.log()draw()references/troubleshooting.mdSeeded Randomness — Always
种子化随机 — 始终启用
Every generative sketch must be reproducible. Same seed, same output.
javascript
function setup() {
randomSeed(CONFIG.seed);
noiseSeed(CONFIG.seed);
// All random() and noise() calls now deterministic
}Never use for generative content — only for performance-critical non-visual code. Always for visual elements. If you need a random seed: .
Math.random()random()CONFIG.seed = floor(random(99999))每个生成式作品都必须可复现。相同种子,相同输出。
javascript
function setup() {
randomSeed(CONFIG.seed);
noiseSeed(CONFIG.seed);
// 所有random()和noise()调用现在都是确定性的
}绝不要在生成式内容中使用——仅在性能关键的非视觉代码中使用。视觉元素始终使用。如果需要随机种子:。
Math.random()random()CONFIG.seed = floor(random(99999))Generative Art Platform Support (fxhash / Art Blocks)
生成艺术平台支持(fxhash / Art Blocks)
For generative art platforms, replace p5's PRNG with the platform's deterministic random:
javascript
// fxhash convention
const SEED = $fx.hash; // unique per mint
const rng = $fx.rand; // deterministic PRNG
$fx.features({ palette: 'warm', complexity: 'high' });
// In setup():
randomSeed(SEED); // for p5's noise()
noiseSeed(SEED);
// Replace random() with rng() for platform determinism
let x = rng() * width; // instead of random(width)See § Platform Export.
references/export-pipeline.md对于生成艺术平台,将p5的伪随机数生成器替换为平台的确定性随机数生成器:
javascript
// fxhash约定
const SEED = $fx.hash; // 每个铸币唯一
const rng = $fx.rand; // 确定性伪随机数生成器
$fx.features({ palette: 'warm', complexity: 'high' });
// 在setup()中:
randomSeed(SEED); // 用于p5的noise()
noiseSeed(SEED);
// 用rng()替代random()以实现平台确定性
let x = rng() * width; // 不用random(width)详见 § 平台导出。
references/export-pipeline.mdColor Mode — Use HSB
颜色模式 — 使用HSB
HSB (Hue, Saturation, Brightness) is dramatically easier to work with than RGB for generative art:
javascript
colorMode(HSB, 360, 100, 100, 100);
// Now: fill(hue, sat, bri, alpha)
// Rotate hue: fill((baseHue + offset) % 360, 80, 90)
// Desaturate: fill(hue, sat * 0.3, bri)
// Darken: fill(hue, sat, bri * 0.5)Never hardcode raw RGB values. Define a palette object, derive variations procedurally. See .
references/color-systems.mdHSB(色相、饱和度、亮度)在生成艺术中比RGB容易操作得多:
javascript
colorMode(HSB, 360, 100, 100, 100);
// 现在:fill(色相, 饱和度, 亮度, 透明度)
// 旋转色相:fill((baseHue + offset) % 360, 80, 90)
// 降低饱和度:fill(色相, 饱和度 * 0.3, 亮度)
// 调暗:fill(色相, 饱和度, 亮度 * 0.5)绝不要硬编码原始RGB值。定义调色板对象,通过程序生成变体。详见。
references/color-systems.mdNoise — Multi-Octave, Not Raw
噪声 — 使用多八度,而非原始噪声
Raw looks like smooth blobs. Layer octaves for natural texture:
noise(x, y)javascript
function fbm(x, y, octaves = 4) {
let val = 0, amp = 1, freq = 1, sum = 0;
for (let i = 0; i < octaves; i++) {
val += noise(x * freq, y * freq) * amp;
sum += amp;
amp *= 0.5;
freq *= 2;
}
return val / sum;
}For flowing organic forms, use domain warping: feed noise output back as noise input coordinates. See .
references/visual-effects.md原始看起来像平滑的 blob。叠加多八度噪声以获得自然纹理:
noise(x, y)javascript
function fbm(x, y, octaves = 4) {
let val = 0, amp = 1, freq = 1, sum = 0;
for (let i = 0; i < octaves; i++) {
val += noise(x * freq, y * freq) * amp;
sum += amp;
amp *= 0.5;
freq *= 2;
}
return val / sum;
}对于流畅的有机形态,使用域扭曲:将噪声输出作为噪声输入坐标。详见。
references/visual-effects.mdcreateGraphics() for Layers — Not Optional
使用createGraphics()分层 — 非可选
Flat single-pass rendering looks flat. Use offscreen buffers for composition:
javascript
let bgLayer, fgLayer, trailLayer;
function setup() {
createCanvas(1920, 1080);
bgLayer = createGraphics(width, height);
fgLayer = createGraphics(width, height);
trailLayer = createGraphics(width, height);
}
function draw() {
renderBackground(bgLayer);
renderTrails(trailLayer); // persistent, fading
renderForeground(fgLayer); // cleared each frame
image(bgLayer, 0, 0);
image(trailLayer, 0, 0);
image(fgLayer, 0, 0);
}单层单次渲染看起来很平淡。使用离屏缓冲区进行构图:
javascript
let bgLayer, fgLayer, trailLayer;
function setup() {
createCanvas(1920, 1080);
bgLayer = createGraphics(width, height);
fgLayer = createGraphics(width, height);
trailLayer = createGraphics(width, height);
}
function draw() {
renderBackground(bgLayer);
renderTrails(trailLayer); // 持久化、渐隐的拖尾
renderForeground(fgLayer); // 每帧清空
image(bgLayer, 0, 0);
image(trailLayer, 0, 0);
image(fgLayer, 0, 0);
}Performance — Vectorize Where Possible
性能 — 尽可能向量化
p5.js draw calls are expensive. For thousands of particles:
javascript
// SLOW: individual shapes
for (let p of particles) {
ellipse(p.x, p.y, p.size);
}
// FAST: single shape with beginShape()
beginShape(POINTS);
for (let p of particles) {
vertex(p.x, p.y);
}
endShape();
// FASTEST: pixel buffer for massive counts
loadPixels();
for (let p of particles) {
let idx = 4 * (floor(p.y) * width + floor(p.x));
pixels[idx] = r; pixels[idx+1] = g; pixels[idx+2] = b; pixels[idx+3] = 255;
}
updatePixels();See § Performance.
references/troubleshooting.mdp5.js的绘制调用开销很大。对于数千个粒子:
javascript
// 慢:单个形状绘制
for (let p of particles) {
ellipse(p.x, p.y, p.size);
}
// 快:使用beginShape()绘制单个形状
beginShape(POINTS);
for (let p of particles) {
vertex(p.x, p.y);
}
endShape();
// 最快:使用像素缓冲区处理大量粒子
loadPixels();
for (let p of particles) {
let idx = 4 * (floor(p.y) * width + floor(p.x));
pixels[idx] = r; pixels[idx+1] = g; pixels[idx+2] = b; pixels[idx+3] = 255;
}
updatePixels();详见 § 性能。
references/troubleshooting.mdInstance Mode for Multiple Sketches
多作品使用实例模式
Global mode pollutes . For production, use instance mode:
windowjavascript
const sketch = (p) => {
p.setup = function() {
p.createCanvas(800, 800);
};
p.draw = function() {
p.background(0);
p.ellipse(p.mouseX, p.mouseY, 50);
};
};
new p5(sketch, 'canvas-container');Required when embedding multiple sketches on one page or integrating with frameworks.
全局模式会污染对象。生产环境中使用实例模式:
windowjavascript
const sketch = (p) => {
p.setup = function() {
p.createCanvas(800, 800);
};
p.draw = function() {
p.background(0);
p.ellipse(p.mouseX, p.mouseY, 50);
};
};
new p5(sketch, 'canvas-container');在同一页面嵌入多个作品或与框架集成时必须使用此模式。
WebGL Mode Gotchas
WebGL模式注意事项
- — origin is center, not top-left
createCanvas(w, h, WEBGL) - Y-axis is inverted (positive Y goes up in WEBGL, down in P2D)
- to get P2D-like coordinates
translate(-width/2, -height/2) - /
push()around every transform — matrix stack overflows silentlypop() - before
texture()/rect()— not afterplane() - Custom shaders: — test on multiple browsers
createShader(vert, frag)
- — 原点在中心,而非左上角
createCanvas(w, h, WEBGL) - Y轴方向反转(WEBGL中Y轴正方向向上,P2D中向下)
- 使用实现类似P2D的坐标系统
translate(-width/2, -height/2) - 每次变换前后使用/
push()— 矩阵栈溢出不会有提示pop() - 在/
rect()之前调用plane()— 不要在之后调用texture() - 自定义着色器:— 在多个浏览器上测试
createShader(vert, frag)
Export — Key Bindings Convention
导出 — 按键绑定约定
Every sketch should include these in :
keyPressed()javascript
function keyPressed() {
if (key === 's' || key === 'S') saveCanvas('output', 'png');
if (key === 'g' || key === 'G') saveGif('output', 5);
if (key === 'r' || key === 'R') { randomSeed(millis()); noiseSeed(millis()); }
if (key === ' ') CONFIG.paused = !CONFIG.paused;
}每个作品都应在中包含以下绑定:
keyPressed()javascript
function keyPressed() {
if (key === 's' || key === 'S') saveCanvas('output', 'png');
if (key === 'g' || key === 'G') saveGif('output', 5);
if (key === 'r' || key === 'R') { randomSeed(millis()); noiseSeed(millis()); }
if (key === ' ') CONFIG.paused = !CONFIG.paused;
}Headless Video Export — Use noLoop()
无界面视频导出 — 使用noLoop()
For headless rendering via Puppeteer, the sketch must use in setup. Without it, p5's draw loop runs freely while screenshots are slow — the sketch races ahead and you get skipped/duplicate frames.
noLoop()javascript
function setup() {
createCanvas(1920, 1080);
pixelDensity(1);
noLoop(); // capture script controls frame advance
window._p5Ready = true; // signal readiness to capture script
}The bundled detects and calls once per capture for exact 1:1 frame correspondence. See § Deterministic Capture.
scripts/export-frames.js_p5Readyredraw()references/export-pipeline.mdFor multi-scene videos, use the per-clip architecture: one HTML per scene, render independently, stitch with . See § Per-Clip Architecture.
ffmpeg -f concatreferences/export-pipeline.md通过Puppeteer进行无界面渲染时,作品必须在setup中使用。否则,p5的绘制循环会自由运行,而截图速度较慢——作品会超前运行,导致帧丢失或重复。
noLoop()javascript
function setup() {
createCanvas(1920, 1080);
pixelDensity(1);
noLoop(); // 捕获脚本控制帧推进
window._p5Ready = true; // 向捕获脚本发送就绪信号
}附带的会检测,并在每次捕获时调用,确保帧完全一一对应。详见 § 确定性捕获。
scripts/export-frames.js_p5Readyredraw()references/export-pipeline.md对于多场景视频,使用分段架构:每个场景对应一个HTML文件,独立渲染,然后用拼接。详见 § 分段架构。
ffmpeg -f concatreferences/export-pipeline.mdAgent Workflow
代理工作流
When building p5.js sketches:
- Write the HTML file — single self-contained file, all code inline
- Open in browser — (macOS) or
open sketch.html(Linux)xdg-open sketch.html - Local assets (fonts, images) require a server: in the project directory, then open
python3 -m http.server 8080http://localhost:8080/sketch.html - Export PNG/GIF — add shortcuts as shown above, tell the user which key to press
keyPressed() - Headless export — for automated frame capture (sketch must use
node scripts/export-frames.js sketch.html --frames 300+noLoop())_p5Ready - MP4 rendering —
bash scripts/render.sh sketch.html output.mp4 --duration 30 - Iterative refinement — edit the HTML file, user refreshes browser to see changes
- Load references on demand — use to load specific reference files as needed during implementation
skill_view(name="p5js", file_path="references/...")
构建p5.js作品时:
- 编写HTML文件 — 单个独立文件,所有代码内嵌
- 在浏览器中打开 — (macOS)或
open sketch.html(Linux)xdg-open sketch.html - 本地资源(字体、图像)需要服务器:在项目目录中运行,然后打开
python3 -m http.server 8080http://localhost:8080/sketch.html - 导出PNG/GIF — 添加如上所示的快捷键,告知用户按哪个键
keyPressed() - 无界面导出 — 用于自动化帧捕获(作品必须使用
node scripts/export-frames.js sketch.html --frames 300+noLoop())_p5Ready - MP4渲染 —
bash scripts/render.sh sketch.html output.mp4 --duration 30 - 迭代优化 — 编辑HTML文件,用户刷新浏览器查看更改
- 按需加载参考资料 — 使用在实现过程中按需加载特定参考文件
skill_view(name="p5js", file_path="references/...")
Performance Targets
性能目标
| Metric | Target |
|---|---|
| Frame rate (interactive) | 60fps sustained |
| Frame rate (animated export) | 30fps minimum |
| Particle count (P2D shapes) | 5,000-10,000 at 60fps |
| Particle count (pixel buffer) | 50,000-100,000 at 60fps |
| Canvas resolution | Up to 3840x2160 (export), 1920x1080 (interactive) |
| File size (HTML) | < 100KB (excluding CDN libraries) |
| Load time | < 2s to first frame |
| 指标 | 目标 |
|---|---|
| 帧率(交互场景) | 持续60fps |
| 帧率(动画导出) | 最低30fps |
| 粒子数量(P2D形状) | 5000-10000个,保持60fps |
| 粒子数量(像素缓冲区) | 50000-100000个,保持60fps |
| 画布分辨率 | 最高3840x2160(导出),1920x1080(交互) |
| 文件大小(HTML) | < 100KB(不包含CDN库) |
| 加载时间 | 首帧加载<2秒 |
References
参考资料
| File | Contents |
|---|---|
| Canvas setup, coordinate system, draw loop, |
| 2D primitives, |
| Noise (Perlin, fractal, domain warp, curl), flow fields, particle systems (physics, flocking, trails), pixel manipulation, texture generation (stipple, hatch, halftone), feedback loops, reaction-diffusion |
| Frame-based animation, easing functions, |
| |
| |
| WEBGL renderer, 3D primitives, camera, lighting, materials, custom geometry, GLSL shaders ( |
| Mouse events, keyboard state, touch input, DOM elements, |
| |
| Performance profiling, per-pixel budgets, common mistakes, browser compatibility, WebGL debugging, font loading issues, pixel density traps, memory leaks, CORS |
| Interactive viewer template: seed navigation (prev/next/random/jump), parameter sliders, download PNG, responsive canvas. Start from this for explorable generative art |
| 文件 | 内容 |
|---|---|
| 画布设置、坐标系统、绘制循环、 |
| 2D基本图形、 |
| 噪声(Perlin、分形、域扭曲、卷曲)、流场、粒子系统(物理、集群、拖尾)、像素操作、纹理生成(点画、影线、半色调)、反馈循环、反应扩散 |
| 基于帧的动画、缓动函数、 |
| |
| |
| WEBGL渲染器、3D基本图形、相机、光照、材质、自定义几何结构、GLSL着色器( |
| 鼠标事件、键盘状态、触摸输入、DOM元素、 |
| |
| 性能分析、每像素预算、常见错误、浏览器兼容性、WebGL调试、字体加载问题、像素密度陷阱、内存泄漏、CORS |
| 交互式查看器模板:种子导航(上一个/下一个/随机/跳转)、参数滑块、PNG下载、响应式画布。用于可探索的生成艺术 |
Creative Divergence (use only when user requests experimental/creative/unique output)
创意发散(仅当用户要求实验性/创意性/独特输出时使用)
If the user asks for creative, experimental, surprising, or unconventional output, select the strategy that best fits and reason through its steps BEFORE generating code.
- Conceptual Blending — when the user names two things to combine or wants hybrid aesthetics
- SCAMPER — when the user wants a twist on a known generative art pattern
- Distance Association — when the user gives a single concept and wants exploration ("make something about time")
如果用户要求创意、实验性、令人惊喜或非常规的输出,选择最适合的策略,并在生成代码前仔细思考步骤。
- 概念融合 — 当用户要求结合两种事物或需要混合美学风格时
- SCAMPER改造 — 当用户要求对已知生成艺术模式进行创新时
- 远距离联想 — 当用户给出单一概念并要求拓展时(例如“创作关于时间的作品”)
Conceptual Blending
概念融合
- Name two distinct visual systems (e.g., particle physics + handwriting)
- Map correspondences (particles = ink drops, forces = pen pressure, fields = letterforms)
- Blend selectively — keep mappings that produce interesting emergent visuals
- Code the blend as a unified system, not two systems side-by-side
- 确定两个不同的视觉系统(例如:粒子物理 + 手写体)
- 建立对应关系(粒子 = 墨滴、作用力 = 笔压、场 = 字形)
- 选择性融合——保留能产生有趣涌现视觉效果的对应关系
- 将融合实现为统一系统,而非两个独立系统的简单拼接
SCAMPER Transformation
SCAMPER改造
Take a known generative pattern (flow field, particle system, L-system, cellular automata) and systematically transform it:
- Substitute: replace circles with text characters, lines with gradients
- Combine: merge two patterns (flow field + voronoi)
- Adapt: apply a 2D pattern to a 3D projection
- Modify: exaggerate scale, warp the coordinate space
- Purpose: use a physics sim for typography, a sorting algorithm for color
- Eliminate: remove the grid, remove color, remove symmetry
- Reverse: run the simulation backward, invert the parameter space
选取一个已知的生成模式(流场、粒子系统、L系统、元胞自动机)并进行系统性改造:
- 替换:将圆形替换为文字字符,将线条替换为渐变
- 组合:合并两种模式(流场 + 沃罗诺伊图)
- 适配:将2D模式应用于3D投影
- 修改:夸张比例、扭曲坐标空间
- 转用:将物理模拟用于排版,将排序算法用于色彩
- 消除:移除网格、移除色彩、移除对称性
- 反转:反向运行模拟、反转参数空间
Distance Association
远距离联想
- Anchor on the user's concept (e.g., "loneliness")
- Generate associations at three distances:
- Close (obvious): empty room, single figure, silence
- Medium (interesting): one fish in a school swimming the wrong way, a phone with no notifications, the gap between subway cars
- Far (abstract): prime numbers, asymptotic curves, the color of 3am
- Develop the medium-distance associations — they're specific enough to visualize but unexpected enough to be interesting
- 锚定用户的概念(例如“孤独”)
- 生成三个层级的联想:
- 近距离(显而易见):空房间、单个身影、寂静
- 中距离(有趣):鱼群中逆向游动的一条鱼、没有通知的手机、地铁车厢之间的缝隙
- 远距离(抽象):质数、渐近曲线、凌晨3点的颜色
- 基于中距离联想进行创作——它们足够具体可可视化,同时又足够出人意料