p5-js 光速入門

作者:德育處主任

https://juejin.cn/post/7173451612654927908

本文的目標是一起有序的快速上手 p5.js ,會講解 p5.js 的基礎用法。

本文會涉及到的內容包括:

其中還會講解部分 p5.js 全局方法。

官方文檔很重要,但對於初學者來說可能會有點懵。因爲官方文檔主要講解 api 的用法,第一次接觸p5.js的工友可能不是那麼容易將各個知識點串聯起來。

本文在基於官方案例的基礎上,把我覺得入門必學的知識點過一遍,然後串起來搞一個小特效。

要快速學習一個庫,尤其是可視化方面的庫,最快速的方法是找到一個好教程,然後跟着敲代碼,建立自己的 “demo 倉庫” 。

學習本文內容,你需要有 JavaScript 基礎。

什麼是 p5.js

p5.js 簡介

引用官網的話:

p5.js 是個 JavaScript 創意編程程式庫,其專注在讓編程更易於使用及更加廣泛的包容藝術家、設計師、教育家、初學者以及任何人!p5.js 是個免費及開源的軟件因爲我們相信所有人都應該能自由使用軟件及用於學習軟件的工具。

p5.js 使用繪圖的比喻並有一副完整的繪畫功能。除此之外,您也不單限於您的繪圖畫布。您可以將您整個瀏覽器頁面當作您的繪圖,這包括了 HTML5 物件,如文字、輸入框、視頻、攝像頭及音頻。

簡單來說,p5.js 能讓 “切圖仔” 更容易做出具有藝術感的作品(很能整活)。

舉個例子,p5.js 很擅長實現下面這種效果。

p5.jsProcessing 往瀏覽器延伸的一個 canvas庫Processing 是使用 Java 編寫的,而 Java 對於從事藝術工作的工友來說上手是有點難度的。

瀏覽器暫時只接受 HTMLCSSJavaScript,如果能將 Processing 直接搬上瀏覽器運行的話,對於藝術家來說是大大的好事。於是,p5.js 應運而生!

p5.js 第一個測試版在 2014 年 8 月 發佈。

更多的故事可在 p5.js 官網中尋找,本文的目標是光速入門 p5.js

找到 p5.js

快速上手

本文的目標是和各位工友快速上手 p5.js,所以 CDN 的方式引入 p5.js,因爲這樣非常快!

接下來我們試試在畫布創建一個圓形吧~

環境搭建

CDN

<script src="https://cdn.jsdelivr.net/npm/p5@[p5_version]/lib/p5.js"></script>

[p5_version] 改成指定版本號即可,本文使用的版本是 1.5.0 ,所以我是這樣引入 1.5.0 版的 p5.js

<script src="https://cdn.jsdelivr.net/npm/p5@1.5.0/lib/p5.js"></script>

查看其他版本可以瀏覽:https://cdn.jsdelivr.net/npm/p5@1.5.0/

npm

安裝

npm i p5 --save

引入

import p5 from 'p5'

在畫布創建一個圓形

我使用的開發工具是 vs code,並裝了 Live Server 插件 [4]。這個插件可以幫我們快速啓動一個服務端運行當前頁面,並具備熱更新的能力。啓動完服務,在瀏覽器運行指定頁面後,你代碼的每一次保存,瀏覽器都會自動刷新。

02.png

<script src="https://cdn.jsdelivr.net/npm/p5@1.5.0/lib/p5.js"></script>
<script>
  function setup() {
    createCanvas(200, 200) // 創建一個 200 * 200 像素的畫布
    background(180, 180, 180) // 畫布背景色 background(r, g, b)
  }

  function draw() {
    circle(60, 60, 100) // 畫一個圓形
  }
</script>

上面的代碼用到幾個 “奇怪” 的方法,逐一講解一下。

暫時只需大概瞭解一下怎麼畫一個圓就行,詳細的後面會講到。

項目代碼結構

使用 p5.js ,你可以理解爲用這個工具創造一個 “有生命” 的世界。

setup()draw() 這兩個函數非常重要,在前端的世界裏,你可以把 setup()draw() 理解爲生命週期函數。

啓動函數 setup

使用 CDN 的方式開發時,引入 p5.js 後就會在全局創建一些函數和常量。

setup()p5.js 裏一個很重要的方法,你可以簡單的理解爲 setupp5.js 裏的一個生命週期函數。在該函數里可以做很多初始化工作,比如創建畫布並設置大小、畫布背景色等。

setup() 在每個頁面都只能出現一次,並且它不能在一開始執行後再次被調用。

更多說明可查看 setup() 說明文檔 [5]

繪圖 draw

draw()p5.js 裏另一個很重要的函數。

draw() 會在 setup() 之後執行,並且會重複的執行。如果想打斷 draw() 可以試用 noLoop() 方法。

draw() 每秒執行次數受到 frameRate() 影響,frameRate() 默認每秒 60 幀。如果需要修改幀率,可以直接傳入指定數值,比如 frameRate(20)

如果要做動畫,代碼可以寫在 draw() 裏。

更多說明可查看 draw() 說明文檔 [6]

2D 基礎圖形

p5.js 可以繪製 2D 和 3D 圖形,但在光速入門階段只會講解 2D 圖形的基礎用法。

先從最簡單的點線面開始學起~

點 point

點是 p5.js 的基礎元素之一,語法如下:

point(x, y, [z])

point() 接收 3 個參數,其中 xy 是必傳參;如果是在 2D 畫布裏,z 不需要傳。

點出現在畫布的中間

03.png

<script src="https://cdn.jsdelivr.net/npm/p5@1.5.0/lib/p5.js"></script>
<script>
  function setup() {
    createCanvas(200, 200)
    background(220, 220, 220)
  }

  function draw() {
    point(100, 100)
  }
</script>

上面的例子中,畫布的寬高是 200 像素,點在 100, 100 的位置,仔細看可以發現點出現在畫布的中心。

如果需要畫一個更大的點,可以通過 strokeWeight() 方法設置

04.png

<script src="https://cdn.jsdelivr.net/npm/p5@1.5.0/lib/p5.js"></script>
<script>
  function setup() {
    createCanvas(200, 200)
    background(220, 220, 220)
  }

  function draw() {
    point(100, 100)
    strokeWeight(10) // 更大的點
  }
</script>

其實 strokeWeight() 方法是用來設置描邊粗細的,用在 point 裏也完全沒問題。

更多說明可查看 point() 說明文檔 [7]

線段 line

要畫一根線段的語法:

line(x1, y1, [z1], x2, y2, [z2])

注意上面的參數順序,一定不能寫錯的。

其中 z1z2 在 2D 情況下是不需要傳的,所以語法變成這樣:

line(x1, y1, x2, y2)

使用 line() 方法會自動將起點和終點連接起來,形成一根線段。

05.png

<script src="https://cdn.jsdelivr.net/npm/p5@1.5.0/lib/p5.js"></script>
<script>
  function setup() {
    createCanvas(200, 200)
    background(220, 220, 220)
  }

  function draw() {
    line(60, 30, 130, 140)
  }
</script>

更多說明可查看 line() 說明文檔 [8]

三角形 triangle

三角形的語法是:

triangle(x1, y1, x2, y2, x3, y3)

和前面的 點 (point) 和 線段 (line) 不同,三角形 (triangle) 的所有參數都是必傳的。

三角形有 3 個點,每個點需要用 2 個座標 (x 和 y) 來描述,所以 triangle() 一共要傳入 6 個參數。

經過前面的 點 (point) 和 線段 (line) 練習,相信你看到三角形的參數名稱就已經知道什麼意思了。

確定了 3 個點的座標後,triangle() 會使用直線連接這 3 個點,形成一個三角形。

06.png

<script src="https://cdn.jsdelivr.net/npm/p5@1.5.0/lib/p5.js"></script>
<script>
  function setup() {
    createCanvas(200, 200)
    background(220, 220, 220)
  }

  function draw() {
    triangle(100, 30, 40, 140, 160, 140)
  }
</script>

更多說明可查看 triangle() 說明文檔 [9]

正方形 square

正方形是特殊的四邊形,也可以說是特殊的矩形。

所以先從正方形講起。

創建正方形用到的方法是 square(),語法如下所示:

square(x, y, s, [tl][tr][br][bl])

tltrbrbl 是用來設置正方形的圓角半徑,分別是 上左上右下右下左。如果不傳這幾個參數,正方形的角默認是 90°(直角)。

07.png

<script src="https://cdn.jsdelivr.net/npm/p5@1.5.0/lib/p5.js"></script>
<script>
  function setup() {
    createCanvas(200, 200)
    background(220, 220, 220)
  }

  function draw() {
    square(10, 10, 80)
  }
</script>

圓角半徑

圓角半徑參數遵循以下規則:

省略的角半徑參數設置爲參數列表中先前指定的半徑值的值。

意思是,如果只傳入 1 個半徑值,那麼後面 3 個圓角半徑的值會取左上的圓角半徑。

08.png

<script src="https://cdn.jsdelivr.net/npm/p5@1.5.0/lib/p5.js"></script>
<script>
  function setup() {
    createCanvas(200, 200)
    background(220, 220, 220)
  }

  function draw() {
    square(10, 10, 80, 10)
  }
</script>

如果是傳入 2 個圓角半徑,那第三和第四個圓角半徑的值會取第二個的值。

09.png

<script src="https://cdn.jsdelivr.net/npm/p5@1.5.0/lib/p5.js"></script>
<script>
  function setup() {
    createCanvas(200, 200)
    background(220, 220, 220)
  }

  function draw() {
    square(10, 10, 80, 10, 30)
  }
</script>

更多說明可查看 square() 說明文檔 [10]

矩形 rect

前面瞭解完 正方形 (quad) 如何創建後,學習 矩形 (rect) 會覺得非常簡單。

p5.js 提供了 rect() 方法繪製矩形,而且會根據參數的數量判斷繪製矩形還是繪製正方形。

語法如下:

rect(x, y, w, [h][tl][tr][br][bl])

如果只傳 3 個參數,繪製出來的是正方形(長和寬的值都使用第三個參數)

10.png

<script src="https://cdn.jsdelivr.net/npm/p5@1.5.0/lib/p5.js"></script>
<script>
  function setup() {
   createCanvas(300, 300)
   background(220, 220, 220)
  }

  function draw() {
    rect(10, 10, 60) // 矩形
  }
</script>

如果傳 4 個參數的話,就可以分別設置長和寬了,第 3 和第 4 個參數分別是 wy

11.png

<script src="https://cdn.jsdelivr.net/npm/p5@1.5.0/lib/p5.js"></script>
<script>
  function setup() {
   createCanvas(300, 300)
   background(220, 220, 220)
  }

  function draw() {
    rect(10, 10, 60, 100) // 矩形
  }
</script>

後面的 4 個參數 tltrbrbl 分別設置四個角的圓角半徑,不設置的話默認就是 90°。用法和正方形一樣的,自己動手試試看吧~

更多說明可查看 rect() 說明文檔 [11]

四邊形 quad

如果需要繪製四邊形,使用 quad() 即可。

四邊形有 4 個頂點,1 個定點用 2 個參數表示 xy 座標。

語法如下:

quad(x1, y1, x2, y2, x3, y3, x4, y4)

需要注意繪製四邊形時頂點的繪製順序

12.png

<script src="https://cdn.jsdelivr.net/npm/p5@1.5.0/lib/p5.js"></script>
<script>
  function setup() {
   createCanvas(300, 300)
   background(220, 220, 220)
  }

  function draw() {
    quad(80, 40, 180, 40, 140, 80, 40, 80) // 四邊形
  }
</script>

更多說明可查看 quad() 說明文檔 [12]

圓形 circle

圓形是 “特殊橢圓”,使用 circle() 方法可以創建圓形。

語法如下:

circle(x, y, d)

13.png

<script src="https://cdn.jsdelivr.net/npm/p5@1.5.0/lib/p5.js"></script>
<script>
  function setup() {
   createCanvas(300, 300)
   background(220, 220, 220)
  }

  function draw() {
    circle(80, 80, 100) // 圓形
  }
</script>

上面代碼的意思:圓心在 (80, 80) 的位置,直徑是 100。換算一下半徑就是 50 咯。

更多說明可查看 circle() 說明文檔 [13]

橢圓 ellipse

使用 ellipse() 可以創建橢圓,橢圓 (ellipse) 的創建方法和 矩形 (rect) 其實是有點像的。

ellipse() 方法會根據傳入的參數數量判斷創建圓形還是創建橢圓。

語法如下:

ellipse(x, y, w, [h])

如果只傳 3 個參數,h 會取 w 的值,所以畫出來的是正圓形。

如果傳 4 個參數,並且 wh 的值不一樣,那畫出來就是一個橢圓。

14.png

<script src="https://cdn.jsdelivr.net/npm/p5@1.5.0/lib/p5.js"></script>
<script>
  function setup() {
   createCanvas(300, 300)
   background(220, 220, 220)
  }

  function draw() {
    ellipse(80, 80, 100, 50) // 橢圓
  }
</script>

更多說明可查看 ellipse() 說明文檔 [14]

弧狀 arc

弧形 (arc) 是一個很好玩的方法,你可以用 arc() 畫圓形、橢圓、餅圖和弧線。

隨着功能的增加, arc() 所需的參數也會比圓形和橢圓更多。

先來看看語法:

arc(x, y, w, h, start, stop, [mode][detail])

我知道有很些工友對弧度制不太熟悉,其實也不需要擔心,p5.js 提供了 radians() 方法,可以將角度轉成弧度。

接下來我就用角度的方式去畫圖展示一下 arc() 是如何使用的。

我畫 4 個弧形,分別表示 90°、180° 、270° 和 360°。

15.png

<script src="https://cdn.jsdelivr.net/npm/p5@1.5.0/lib/p5.js"></script>
<script>
  function setup() {
   createCanvas(300, 300)
   background(220, 220, 220)
  }

  function draw() {
    // 左上角的圖形,0-90°(角度)
    arc(50, 50, 50, 50, radians(0), radians(90))

    // 右上角的圖形,0-180°(角度)
    arc(250, 50, 50, 50, radians(0), radians(180))

    // 左下角的圖形,0-270°(角度)
    arc(50, 250, 50, 50, radians(0), radians(270))

    // 右下角的圖形,0-360°(角度)
    arc(250, 250, 50, 50, radians(0), radians(360))
  }
</script>

從上面的代碼可以看出,0°(角度)是在圖形的正右方。

順便展示一下不同 mode 的效果

16.png

<script src="https://cdn.jsdelivr.net/npm/p5@1.5.0/lib/p5.js"></script>
<script>
  function setup() {
   createCanvas(300, 300)
   background(220, 220, 220)
  }

  function draw() {
    // 左上角的圖形,默認
    arc(50, 50, 50, 50, radians(0), radians(270))

    // 右上角的圖形,開放式半圓形(OPEN)
    arc(250, 50, 50, 50, radians(0), radians(270), OPEN)

    // 左下角的圖形,封閉式半圓形(CHORD)
    arc(50, 250, 50, 50, radians(0), radians(270), CHORD)

    // 右下角的圖形,封閉式餅形段(PIE)
    arc(250, 250, 50, 50, radians(0), radians(270), PIE)
  }
</script>

OPENCHORDPIE 這幾個常量都不需要我們定義的,p5.js 已經在全局定義好了。

更多說明可查看 arc() 說明文檔 [15]

其他圖形

除了前面講到的幾個基礎圖形,p5.js 還提供了貝塞爾曲線、球體、立方體、圓錐等圖形元素,甚至還能自定義多邊形。

但在光速入門階段我們只需掌握基礎的圖形,再加上自己的創意就可以做出很漂亮的作品。

文本

創建文本的方法叫 text()

語法如下:

text(str, x, y, [x2][y2])

17.png

<script src="https://cdn.jsdelivr.net/npm/p5@1.5.0/lib/p5.js"></script>
<script>
  function setup() {
   createCanvas(300, 300)
   background(220, 220, 220)
  }

  function draw() {
    text('雷猴', 10, 20)
  }
</script>

我們還可以傳入 x2y2 參數來控制內容的展示方式。

x2 會影響文本換行方式,y2 控制文本顯示的內容。

先說 x2,這個參數是控制文本在 x 軸方向的展示長度,x2 \- x 就可以得出這段文字在 x 軸方向可以展示的長度。

比如一個字符的寬度是 5pxx 設爲 10,x2 設爲 20,那麼一行就可以展示 2 個文字。

x2 並不能很好的控制文本長度,它只會判斷這行文本里有沒有空格,如果出現空格,且超出文本框寬度的內容就會換行。

y2 \- y 得出的長度就是 y 軸方向可展示的區域。超出這個區域的文本都不會展示出來了。

舉個例子

18.png

<script src="https://cdn.jsdelivr.net/npm/p5@1.5.0/lib/p5.js"></script>
<script>
  function setup() {
   createCanvas(300, 300)
   background(220, 220, 220)
  }

  function draw() {
    text(
      'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Doloremque et assumenda quibusdam quis, rerum incidunt animi nihil perspiciatis temporibus neque!',
      10,
      20,
      40,
      60
    )
  }
</script>

此時,在 x2y2 的限制下,文本已經無法完全展示出來了。

基礎樣式

p5.js 提供了幾個設置樣式的方法,我挑常用的幾個來講講。

顏色

p5.js 支持多種顏色值,比如 顏色關鍵字十六進制CSS顏色字符串RGBHSBHSL灰度

關鍵字 與 十六進制

顏色關鍵字十六進制CSS顏色字符串 就不多說了,合格的切圖仔都懂這個。

需要注意的是 RGBHSBHSL灰度

其中,RGBHSBHSL 都支持傳入第 4 個參數,這個參數表示透明通道。

RGB

RGB 的第 4 個參數取值範圍是 0 ~ 2550 表示完全透明,255 表示完全不透明。

如果不傳第 4 個參數,默認值是 255

我用 background 背景色來舉例。

20.png

<script src="https://cdn.jsdelivr.net/npm/p5@1.5.0/lib/p5.js"></script>
<script>
  function setup() {
    createCanvas(300, 300)
    background(152, 231, 162) // 設置綠色背景色
  }
</script>

如果此時在 background() 裏傳入第 4 個參數就可以改變背景色的不透明度。

比如

21.png

background(152, 231, 162, 100)

HSB 與 HSL

HSBHSL 都是顏色表示的一種方法。

HSBHSL用法 上差不多,但和 RGB 是有區別的。

  1. 使用 HSBHSL 前,要設置顏色模式,告訴 p5.js 要使用哪種顏色模式去渲染。而 RGB 就省略了這步。

  2. HSBHSL 第 1 個參數取值 0 ~ 360,第 2 和第 3 個參數取值是 0 ~ 100。而 RGB 前 3 個參數的取值都是 0 ~ 255

  3. 在透明度上,HSBHSL 在第 4 個參數的取值範圍是 0 ~ 1 ,而 RGB0 ~ 255

如果要使用 HSB ,就需要使用 colorMode(HSB) 設置一下;HSL 就用 colorMode(HSL) 設置一下。

還是用 background() 舉例

22.png

<script src="https://cdn.jsdelivr.net/npm/p5@1.5.0/lib/p5.js"></script>
<script>
  function setup() {
    createCanvas(300, 300)
    colorMode(HSB) // 設置 HSB 顏色模式
    background(360, 30, 80) // 設置背景色
    // background(360, 30, 80, 0.5) // 背景色,添加透明通道
  }
</script>

灰度

灰度模式的意思是隻有 “黑白灰” 三種顏色,而灰色是過渡顏色。

灰度模式是默認的顏色模式,不需要進行特殊設置。

灰度模式的取值範圍是 0 ~ 255。0 表示黑色,255 表示白色,中間的其他值表示不同程度的灰色。

使用 RGB 設置顏色,需要傳 3 ~ 4 個參數,而使用灰度模式只需傳 1 個參數。

還是拿 background() 舉例

23.png

<script src="https://cdn.jsdelivr.net/npm/p5@1.5.0/lib/p5.js"></script>
<script>
  function setup() {
    createCanvas(300, 300)
    background(128) // 設置背景色
  }
</script>

背景色 background()

前面一直使用背景色,相信大家已經對 background() 的用法非常熟悉了。

通常 background() 會在 2 個地方用到。

一個是寫在 setup() 裏,在初始化畫布時可以設置畫布背景色。

還可以寫在 draw() 裏,每次刷新畫布都可以設置畫布背景色。寫在 draw() 裏,畫布每次刷新都會重新設置一次背景色。某些情況下是很有用的,比如移動圖像時,如果背景色沒重新設置一次,那麼圖形移動後會產生 “殘留” 的現象。這個放在動畫章節說。

填充顏色 fill()

創建圖像後,圖像默認的填充色是白色。

要修改圖像填充色,使用 fill() 方法即可。

24.png

<script src="https://cdn.jsdelivr.net/npm/p5@1.5.0/lib/p5.js"></script>
<script>
  function setup() {
    createCanvas(300, 300)
    background(200)
  }
  function draw() {
    fill('#f2c0ca') // 設置填充色
    rect(30, 30, 100, 80)
    circle(220, 70, 80)
  }
</script>

需要注意的是,一旦設置了 fill() ,在它後面創建的圖形都會使用相同的填充色,正如上面的例子那樣。

如果希望後面的圖形使用別的顏色,可以再重新調用一遍 fill() 進行設置。

25.png

<script src="https://cdn.jsdelivr.net/npm/p5@1.5.0/lib/p5.js"></script>
<script>
  function setup() {
    createCanvas(300, 300)
    background(200)
  }
  function draw() {
    fill('#f2c0ca') // 設置填充色
    rect(30, 30, 100, 80)
    fill('yellow') // 重新設置填充色
    circle(220, 70, 80)
  }
</script>

無填充 noFill()

如果不想設置填充色,可以使用 noFill() 方法。

不填充的情況下,圖形內部將會設置成透明,會直接顯示在它下層的顏色,如果它下層沒有其他元素,則會直接顯示背景色。

26.png

<script src="https://cdn.jsdelivr.net/npm/p5@1.5.0/lib/p5.js"></script>
<script>
  function setup() {
    createCanvas(300, 300)
    background(200)
  }

  function draw() {
    noFill()
    rect(30, 30, 100, 80)
    circle(220, 70, 80)
  }
</script>

邊框顏色 stroke()

p5.js 創建出來的元素默認是有一個黑色邊框,如果想要修改邊框顏色,可以使用 stroke() 方法。

27.png

<script src="https://cdn.jsdelivr.net/npm/p5@1.5.0/lib/p5.js"></script>
<script>
  function setup() {
    createCanvas(300, 300)
    background(200)
  }

  function draw() {
    stroke('red') // 設置邊框顏色
    rect(30, 30, 100, 80)
    circle(220, 70, 80)
  }
</script>

fill() 一樣,在使用 stroke() 設置完顏色之後的圖形都會使用這個邊框顏色。如果要再次修改邊框顏色,只需再次使用 stroke() 即可。

無邊框 noStroke()

如果不希望圖形有邊框,可以使用 noStroke() 方法。

28.png

<script src="https://cdn.jsdelivr.net/npm/p5@1.5.0/lib/p5.js"></script>
<script>
  function setup() {
    createCanvas(300, 300)
    background(200)
  }

  function draw() {
    noStroke() // 無邊框
    rect(30, 30, 100, 80)
    circle(220, 70, 80)
  }
</script>

設置邊框粗細 strokeWeight()

使用 strokeWeight() 方法可以設置圖形邊框的粗細。

29.png

<script src="https://cdn.jsdelivr.net/npm/p5@1.5.0/lib/p5.js"></script>
<script>
  function setup() {
    createCanvas(300, 300)
    background(200)
  }

  function draw() {
    strokeWeight(10) // 設置邊框粗細
    rect(30, 30, 100, 80)
    circle(220, 70, 80)
  }
</script>

修改文字大小 textSize()

使用 textSize() 方法可以修改文字的字號

30.png

<script src="https://cdn.jsdelivr.net/npm/p5@1.5.0/lib/p5.js"></script>
<script>
  function setup() {
    createCanvas(300, 300)
    background(200)
  }

  function draw() {
    textSize(100)
    text('雷猴', 20, 100)
  }
</script>

關於文字的樣式,前面說到的 fill()stroke()strokeWeight() 方法都可以對文字的填充色、描邊等樣式進行設置。自己動手試試吧~

圖片

在打算將圖片加入到畫布之前,我們需要了解 preload() 函數。

preload() 函數也是 p5.js 的一個生命週期函數,它會在 setup() 前執行。

preload() 可以強制程序等待,直到 preload() 函數內的資源加載完成或者事件執行完再執行其他代碼。

所以一般會把圖片和視頻等資源加載寫在 preload() 裏。

瞭解完 preload() 後,我們就可以使用 loadImage() 方法加載圖片,使用 image() 方法渲染圖片。

注意:加載和渲染是分開 2 步操作的!

本例請來的演員是 摸魚的春哥 [16]

Snipaste_2022-12-03_09-15-36.png

<script src="https://cdn.jsdelivr.net/npm/p5@1.5.0/lib/p5.js"></script>
<script>
  let img = null

  function preload() {
    img = loadImage('https://p3-passport.byteimg.com/img/user-avatar/848d36b5efa8e055ab080bff4f27e669~180x180.awebp') // 加載圖片
  }

  function setup() {
    createCanvas(180, 180) // 創建畫布
  }

  function draw() {
    image(img, 0, 0) // 渲染圖片
  }
</script>

除了可以渲染 jpgpng 外,p5.js 還可以渲染動圖 gif。

<script src="https://cdn.jsdelivr.net/npm/p5@1.5.0/lib/p5.js"></script>
<script>
  let img = null

  function preload() {
    img = loadImage('https://p3-passport.byteimg.com/img/user-avatar/221976c6804d412aa876fdd5154129ae~180x180.awebp') // 加載 gif
  }

  function setup() {
    240, 150
  }

  function draw() {
    image(img, 0, 0) // 渲染圖片
  }
</script>

可以在 setup() 函數里使用 frameRate() 方法設置幀率,這可以影響 gif 的刷新率。

交互事件

p5.js 提供了很多鼠標和鍵盤的交互事件,入門階段我們挑 2 個來學就行。

交互事件通常寫在 draw() 函數里。

鼠標點擊 mouseIsPressed

本例使用 mouseIsPressed 判斷用戶是否點擊了鼠標,點擊鼠標時畫布背景是藍色,鬆開鼠標後畫布背景是橙色

<script src="https://cdn.jsdelivr.net/npm/p5@1.5.0/lib/p5.js"></script>
<script>
  function setup() {
    createCanvas(300, 300)
    background('orange')
  }

  function draw() {
    if (mouseIsPressed) { // 檢測鼠標是否按下
      background('skyblue')
    } else {
      background('orange')
    }
  }
</script>

draw() 函數在頁面運行時會一直執行,所以 mouseIsPressed 寫在 draw() 裏可以被捕捉到。如果用戶點擊鼠標,且被捕捉到 mouseIsPressed 時,mouseIsPressed 會返回 true

按住鍵盤 keyIsPressed

keyIsPressed 可以檢測用戶當前是否按住鍵盤,如果鍵盤被按下會返回 true ,否則返回 false

<script src="https://cdn.jsdelivr.net/npm/p5@1.5.0/lib/p5.js"></script>
<script>
  function setup() {
    createCanvas(300, 300)
    background('orange')
  }

  function draw() {
    if (mouseIsPressed) { // 檢測鍵盤是否按下
      background('skyblue')
    } else {
      background('orange')
    }
  }
</script>

動畫

動畫其實就是在修改元素屬性的同時不斷刷新畫布。

p5.js 裏做動畫效果其實很簡單,只需要在 draw() 裏修改元素屬性即可。

舉個例子:圓形圖案跟隨鼠標指針移動

<script src="https://cdn.jsdelivr.net/npm/p5@1.5.0/lib/p5.js"></script>
<script>
  function setup() {
    createCanvas(300, 300)
    background(100)
  }

  function draw() {
    background(100)
    circle(mouseX, mouseY, 40, 40)
  }
</script>

有沒有發現,上面的例子在 draw() 裏首先設置背景色,再創建一個新的圓。

如果沒重新設置背景色的話,上一幀的圓會保留下來。很多時候保留上一幀的數據會產生不錯的藝術作品。

試試把 draw() 裏的 background(100) 這句刪掉

36.png

<script src="https://cdn.jsdelivr.net/npm/p5@1.5.0/lib/p5.js"></script>
<script>
  function setup() {
    createCanvas(300, 300)
    background(100)
  }

  function draw() {
    circle(mouseX, mouseY, 40, 40)
  }
</script>

這個也是 p5.js 官網的例子 [17]

到此,相信各位工友已經對 p5.js 有一定的瞭解了。

參考資料

[1]

p5.js 官網: https://p5js.org/

[2]

p5.js github 地址: https://github.com/processing/p5.js

[3]

p5.js npm 地址: https://www.npmjs.com/package/p5

[4]

Live Server 插件: https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer

[5]

setup() 說明文檔: https://p5js.org/zh-Hans/reference/#/p5/setup

[6]

draw() 說明文檔: https://p5js.org/zh-Hans/reference/#/p5/draw

[7]

point() 說明文檔: https://p5js.org/zh-Hans/reference/#/p5/point

[8]

line() 說明文檔: https://p5js.org/zh-Hans/reference/#/p5/line

[9]

triangle() 說明文檔: https://p5js.org/zh-Hans/reference/#/p5/triangle

[10]

square() 說明文檔: https://p5js.org/zh-Hans/reference/#/p5/square

[11]

rect() 說明文檔: https://p5js.org/zh-Hans/reference/#/p5/rect

[12]

quad() 說明文檔: https://p5js.org/zh-Hans/reference/#/p5/quad

[13]

circle() 說明文檔: https://p5js.org/zh-Hans/reference/#/p5/circle

[14]

ellipse() 說明文檔: https://p5js.org/zh-Hans/reference/#/p5/ellipse

[15]

arc() 說明文檔: https://p5js.org/zh-Hans/reference/#/p5/arc

[16]

https://juejin.cn/user/1714893870865303: https://juejin.cn/user/1714893870865303

[17]

p5.js 官網的例子: https://p5js.org/zh-Hans/get-started/

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/1ptrBHaR54CHtQYsQFKl1w