p5.js 新手入门:环境搭建与第一个动态图形

作者:代码拾荒

时间:2026-11-02

浏览:87

面向初学者的 p5.js 实战入门指南,详细讲解 Web 编辑器与本地代码工程的搭建步骤,深入解析 setup 与 draw 生命周期及画布坐标系,并带你一步步实现第一个交互式动态图形。

文章目录
分类:创意编程 / 前端开发 技术栈:JavaScript / HTML5 Canvas / p5.js 阅读时长:约 8 分钟
p5.js 新手入门:环境搭建与第一个动态图形
图 0:p5.js 动态创意编程核心全貌(双生命周期驱动粒子动态位移)
想要在网页中绘制动态几何、数据可视化或交互式动画,许多开发者首先会接触到 HTML5 的原生 Canvas API。然而在原生 Canvas 中,哪怕只是画一个圆并让它随帧平移,都需要手动获取渲染上下文(2D Context)、处理设备像素比、手写 requestAnimationFrame 递归循环。p5.js 将底层复杂绘制与动画时序抽象为清晰的执行逻辑,开发者只需关注画面元素本身。本文将带你从零完成开发环境搭建,透彻理解 p5.js 的画布坐标与生命周期机制,并完整编写出一个具备平滑位移与边缘碰撞反弹的交互式动态图形。

一、开发环境准备:Web 编辑器与本地工程化

编写 p5.js 程序通常有两种途径:官方在线 Web 编辑器与本地代码工程。对于完全刚接触图形编程的场景,在线编辑器能够做到打开浏览器即写即测;而若需要将代码集成至真实前端项目或进行长期维护,本地开发则是标准实践。

方式一:官方在线 Web 编辑器(零配置)

访问 p5.js 官方在线编辑器网站(editor.p5js.org),页面左侧是 JavaScript 代码编辑区,右侧是实时渲染画布。系统默认已经为你生成了最基础的代码模板:

function setup() {
  createCanvas(400, 400);
}

function draw() {
  background(220);
}

点击左上角的“运行(Play)”按钮,右侧便会生成一块 400×400 像素的灰色画布。这种方式免去了所有依赖安装环节,适合快速验证算法或做小实验。

方式二:搭建本地前端工程(推荐实践)

在本地计算机上新建一个文件夹,例如命名为 my-p5-project。在该目录下创建两个基础文件:index.html 和 sketch.js。

1. 编写宿主页面 index.html

在 index.html 中,通过 CDN 引入 p5.js 官方构建脚本,随后引入自己的逻辑脚本 sketch.js。注意脚本的引入顺序不能颠倒:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>My First p5.js Project</title>
  <style>
    body {
      margin: 0;
      padding: 0;
      display: flex;
      justify-content: center;
      align-items: center;
      min-height: 100vh;
      background-color: #111;
    }
  </style>
</head>
<body>
  <!-- 步骤一:引入 p5.js 核心库 -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.9.4/p5.min.js"></script>
  <!-- 步骤二:引入我们编写的动画逻辑 -->
  <script src="sketch.js"></script>
</body>
</html>

2. 编写逻辑脚本 sketch.js

在同级目录下的 sketch.js 文件中写入最简结构:

function setup() {
  createCanvas(600, 400);
}

function draw() {
  background(30);
}
执行环境提醒
不要直接在操作系统的文件管理器中双击 index.html(即 file:/// 协议),这会导致部分浏览器在后续加载字体、图片或音频资源时触发安全拦截报错。建议在 VS Code 中安装 Live Server 插件,右键选择 “Open with Live Server”,通过本地 HTTP 服务(http://127.0.0.1:5500)运行。
p5.js 新手入门:环境搭建与第一个动态图形
图 1:p5.js 本地开发工程的文件依赖关系与运行时加载顺序

二、p5.js 运行本质:画布坐标与双生命周期

很多初学者写出静态画面很容易,但一涉及“让物体动起来”就容易出现重叠、闪烁或位移失效的问题。理解 p5.js 的两个核心要素是编写动态图形的前提:屏幕坐标系 与 双生命周期机制。

1. 屏幕坐标系的轴向规则

传统的初等数学笛卡尔坐标系中,原点位于左下角或中心,Y 轴向上为正方向。而在网页 Canvas 与 p5.js 中,坐标系规则如下:

  • 原点 (0, 0) 严格锚定在画布的左上角。
  • 水平 X 轴:从左往右递增,最大宽度为系统变量 width。
  • 垂直 Y 轴:从上往下递增,最大高度为系统变量 height。

这意味着,如果要让一个图形“向下坠落”,其 Y 坐标应当不断增加;反之向上升起时,Y 坐标应当不断减小。

2. setup() 与 draw() 的协同生命周期

p5.js 的运行核心依赖两个内置函数,它们的分工极其明确:

生命周期函数 执行频次与时机 核心职能 典型调用 API
setup() 仅在程序启动时执行 1 次 创建画布环境、定义初始帧率、初始化全局变量 createCanvas(), frameRate()
draw() 在 setup 之后以约 60 FPS 高频循环执行 逐帧计算图形新位置、擦除旧帧、重绘几何形体 background(), circle(), rect()
初学者极易忽视的关键细节:背景擦除
如果在 draw() 函数中移除了 background(30) 这一行,上一帧绘制的圆形并不会自动消失。随着物体位移,所有历史位置的像素将全部留在画布上,形成一条连续涂抹的“拖尾条带”。动态动画的本质并不是物理世界中物体的连续平移,而是“擦除上一帧 → 计算新位置 → 绘制新画面”在 1 秒内重复 60 次所带来的视觉暂留效应。
p5.js 新手入门:环境搭建与第一个动态图形
图 2:p5.js 屏幕坐标系方向定义与 setup-draw 双生命周期管线

三、实战构建:第一个动态反弹图形

掌握了生命周期与坐标规则后,我们通过分步推导的方式,实现一个带有物理反弹与鼠标动态交互的彩色动效球体。

第 1 步:绘制静态几何圆形

在 p5.js 中,绘制一个圆只需要使用 circle(x, y, d) 函数,其中三个参数分别代表圆心 X 坐标、圆心 Y 坐标和直径大小。配合 fill() 设置填充色,配合 noStroke() 移除边框描边:

function setup() {
  createCanvas(600, 400);
}

function draw() {
  background(20, 35, 55);
  
  noStroke();
  fill(119, 185, 174); // 柔和浅青色
  circle(300, 200, 40);  // 画布中心静态圆
}

第 2 步:提取状态变量并建立逐帧位移

为了让圆形动起来,圆心的 X 与 Y 不能再写死为常数,而必须提取为全局变量。我们在每次 draw() 执行时,为 X 和 Y 分别累加一个位移增量(即速度 vx 与 vy):

// 全局状态定义
let x = 100;
let y = 100;
let vx = 4; // 水平每帧移动 4 像素
let vy = 3; // 垂直每帧移动 3 像素
let radius = 20;

function setup() {
  createCanvas(600, 400);
}

function draw() {
  background(20, 35, 55);

  // 1. 累加坐标产生运动
  x += vx;
  y += vy;

  // 2. 在新位置绘制圆形
  noStroke();
  fill(119, 185, 174);
  circle(x, y, radius * 2);
}

此时运行代码,你会看到小球向右下方匀速飞行。但几秒钟后,小球就会飞出画布边缘,消失在视野之外。我们需要引入边界反弹检测。

第 3 步:加入边界碰撞反弹算法

反弹在物理数学中的本质是对应方向的速度取相反数。当小球碰到右侧边缘时,水平速度 vx 从 +4 变成 -4,小球就会向左折返。

值得注意的是,圆形的定位基准点是圆心。为了避免半个球体穿透边界才触发反弹,必须把球体半径 radius 计入判断条件:

  • 左右边界判断:if (x + radius >= width || x - radius <= 0) { vx = -vx; }
  • 上下边界判断:if (y + radius >= height || y - radius <= 0) { vy = -vy; }
p5.js 新手入门:环境搭建与第一个动态图形
图 3:逐帧位移叠加与圆心半径边界碰撞检测算法原理

第 4 步:注入动态交互与完整代码

为了让图形更具趣味性,我们利用 p5.js 内置的 mouseX、mouseY 和 mouseIsPressed,实现当鼠标在画布上移动时,绘制一条引力引导线;当点击鼠标时,小球瞬时随机变换配色。以下为完整、可直接在 sketch.js 运行的代码:

/**
 * p5.js 第一个动态图形:物理反弹小球与鼠标交互
 * 文件名:sketch.js
 */

// 小球运动与尺寸状态
let ballX = 150;
let ballY = 120;
let speedX = 4.5;
let speedY = 3.2;
const ballRadius = 22;

// 动态外观配色
let ballColor = { r: 119, g: 185, b: 174 };

function setup() {
  // 初始化画布尺寸为 640 x 400
  createCanvas(640, 400);
  frameRate(60);
}

function draw() {
  // 1. 擦除上一帧画面(保持深蓝底色)
  background(20, 37, 55);

  // 2. 更新位置状态
  ballX += speedX;
  ballY += speedY;

  // 3. 水平方向左右边界检测
  if (ballX + ballRadius >= width || ballX - ballRadius <= 0) {
    speedX = -speedX; // 水平速度取反
  }

  // 4. 垂直方向上下边界检测
  if (ballY + ballRadius >= height || ballY - ballRadius <= 0) {
    speedY = -speedY; // 垂直速度取反
  }

  // 5. 交互:从小球向当前鼠标指针绘制虚线指示引力
  stroke(131, 173, 208, 120);
  strokeWeight(1.5);
  line(ballX, ballY, mouseX, mouseY);

  // 6. 渲染主体小球
  noStroke();
  fill(ballColor.r, ballColor.g, ballColor.b);
  circle(ballX, ballY, ballRadius * 2);

  // 7. 渲染中心高光点增强立体感
  fill(255, 255, 255, 180);
  circle(ballX - 6, ballY - 6, 8);
}

// 鼠标点击事件:瞬时随机更换主体颜色
function mousePressed() {
  ballColor = {
    r: floor(random(100, 255)),
    g: floor(random(150, 255)),
    b: floor(random(180, 255))
  };
}

四、新手避坑排查与核心要点总结

在初次动手运行以上代码时,若遇到画面不符合预期的情况,可以对照以下四个最常见的初学者问题进行快速自查:

1. 变量作用域定义错误:坐标写在 draw() 内部

初学者容易把 let ballX = 150 写在 draw() 函数内部。因为 draw() 每秒反复执行 60 次,每次都会把 ballX 重新赋值为 150,哪怕后面写了 ballX += speedX,下一帧又会被重置。因此,需要随时间持续累积的状态变量必须声明在全局作用域。

2. 在 setup() 之前使用 width 或 height 产生 NaN

很多新手试图在文件顶部写 let ballX = width / 2;。然而,在 setup() 中的 createCanvas() 执行完毕之前,p5.js 的 width 和 height 变量尚未完成初始化,此时它们的值为 0 或 undefined,会导致计算得到 NaN 从而使图形完全无法渲染。如果需要依据画布尺寸初始化坐标,应当在 setup() 函数体内对变量进行赋值。

p5.js 新手入门:环境搭建与第一个动态图形
图 4:新手排查自检卡片与创意编程多阶段进阶路径图

五、结语与进阶延伸

通过本篇指南,我们完成了本地 p5.js 工程的标准配置,厘清了左上角屏幕坐标系与数学坐标系的差异,并通过 setup() 的单次初始化与 draw() 的高频重绘,构建了第一个具备速度向量与边界反弹的动态图形。

完成这个小球案例只是进入创意编程的大门。在掌握了基本位移逻辑后,你可以在此基础上进一步扩展:尝试使用数组批量管理数十个小球,为它们加上基于距离的相互排斥力;或者引入三角函数 sin() 与 cos() 让图形产生如波浪般的有机振荡。图形编程的魅力正在于,用最质朴的数学与代码逻辑,在屏幕上赋予几何体灵动的生命力。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章