思索 p5.js 的最佳实践

思索 p5.js 的最佳实践

本文写于 2020 年 12 月 18 日

p5.js 是一个 JavaScript 库,用于为艺术家、设计师提供更容易上手的创意编程。

它有着完整的一套基于 Canvas 的作画功能,并且你可以把整个浏览器都当成你的“画布”——利用 p5.dom.js 可以很方便地与其他 HTML 元素进行交互;利用 p5.sound.js 可以很简单的对声音进行分析与处理。

官网推荐用法

在官网的例子中,推荐使用 <script> 标签引入的方法:

<html>
  <head>
    <!-- ...... -->
    <script src="path/to/your/p5.js"></script>
  </head>
  <body>
    <script>
      function setup() {
        createCanvas(300, 500);
      }

      function draw() {}
    </script>
  </body>
</html>

这样是让所有的变量、函数都暴露在全局之下,所以我们可以直接使用 setup, draw 函数进行操作。

但这对于新手来说,这样的做法存在一个致命问题:没有代码提示。并且也不符合我们现代 Web 开发的习惯——模块化

在动画复杂的情况下,代码会越来越多、越来越邋遢,直到成为一座“屎山”!!!

所以这让我不由得思考起了 p5.js 的最佳实践究竟该如何。

关于最佳实践的思考

p5.js 拥有多个生命周期函数:

  • 用于预加载数据的 preload 函数;
  • 在最开始执行,并且只执行一次的 setup 函数;
  • 一秒执行大概 20 多次的 draw 函数;
  • 鼠标左键点击时触发的 mousePressed 函数;
  • ……

p5 画图的根本其实就是在不同生命周期里对数据进行操作,然后将数据具体转化为图像

所以按照 MVC 的思想:view = render(data),我们应该拒绝在这些钩子函数中「直接」操作数据——将动画抽象成为独立的 Service(服务),操作数据交给 Service 自己的方法,我们只需要在 draw 函数中对 Service 内的数据进行绘制即可。

这样讲可能大家还不太明白,那么 talk is cheap, show me the code 吧!

例子

目标:制作一个漫天繁星。

第一步我们需要一个 Star 类。

class 星星 {
  x坐标 = 0;
  y坐标 = 0;

  透明度 = 0;

  随机放置星星() {
    // 随机 x y 坐标值
  }

  闪烁() {
    // 操作透明度
  }
}

然后再为所有的星星闪烁制作一个服务(服务其实就是一个 class)。

class 星星服务 {
  星星们 = [];

  get 星星的位置() {
    this.星星们.处理一下((星星) => {
      返回 {
        x: 星星的x坐标,
        y: y坐标,
        opacity: 透明度,
      }
    })
  }

  创建星星们() {
    重复 100 次:this.星星们.增加(new 星星());
  }
}
let 星星服务实例;

function preload() {
  星星服务实例 = new 星星服务class();
}

function setup() {
  星星服务实例.创建星星们();
}

function draw() {
  background(0);
  if (星星服务实例.星星们 的 长度 > 0) {
    星星服务实例.星星的位置.遍历((星星) => {
      fill(255, 星星.透明度);
      ellipse(星星.x, 星星.y, 半径, 半径);
    })
  }
}

目前动画比较简单,还看不出来该方案有什么优势。

但是一旦动画更加复杂,该方案对原来写法的解耦的优越性将会是毋庸置疑的。

我们仅仅需要的是在不同的生命周期函数中调用服务的方法,然后在 draw 函数中拿到数据后进行绘图!

模板代码(本节可不看)

需要:Node.js v14.1 及以上。

上官网下载并安装 Node.js 后,命令行输入 node -v 查看是否安装成功。再输入 npm -v 查看是否成功安装 npm。

不理解 npm 是什么的可以看这一篇:npm 是什么?

输入 npm config set registry https://registry.npm.taobao.org 将下载源更改为国内地址。

访问GitHub 仓库下载我事先准备好的模板代码,并进入目录,输入:npm install 安装依赖,npm run start 启动项目。

(完)

上一篇:P5 第二讲 矩阵01


下一篇:备战今年的“金三银四”,找遍全网收集的Java架构师P5-P8学习路线和笔记真香!