p5.js 光速入門

本文簡介

點(diǎn)贊 + 關(guān)注 + 收藏 = 學(xué)會了


本文的目標(biāo)是和各位工友一起有序的快速上手 p5.js ,會講解 p5.js 的基礎(chǔ)用法。

本文會涉及到的內(nèi)容包括:

  • 項(xiàng)目搭建
  • p5.js 基礎(chǔ)2D圖形
  • 文字
  • 圖形樣式設(shè)置
  • 圖片
  • 事件(交互相關(guān)的)
  • 基礎(chǔ)動畫

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

本文不涉及3d部分(放到下一篇吧)。


官方文檔很重要,但對于初學(xué)者來說可能會有點(diǎn)懵。因?yàn)楣俜轿臋n主要講解api的用法,第一次接觸p5.js的工友可能不是那么容易將各個知識點(diǎn)串聯(lián)起來。

本文在基于官方案例的基礎(chǔ)上,把我覺得入門必學(xué)的知識點(diǎn)過一遍,然后串起來搞一個小特效。

要快速學(xué)習(xí)一個庫,尤其是可視化方面的庫,最快速的方法是找到一個好教程,然后跟著敲代碼,建立自己的 “demo倉庫” 。


學(xué)習(xí)本文內(nèi)容,你需要有 JavaScript 基礎(chǔ)。



什么是p5.js

p5.js 簡介

引用官網(wǎng)的話:

p5.js 是個 JavaScript 創(chuàng)意編程程式庫,其專注在讓編程更易于使用及更加廣泛的包容藝術(shù)家、設(shè)計(jì)師、教育家、初學(xué)者以及任何人!p5.js 是個免費(fèi)及開源的軟件因?yàn)槲覀兿嘈潘腥硕紤?yīng)該能自由使用軟件及用于學(xué)習(xí)軟件的工具。

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


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

舉個例子,p5.js 很擅長實(shí)現(xiàn)下圖效果。

file


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

瀏覽器暫時只接受 HTML、CSSJavaScript,如果能將 Processing 直接搬上瀏覽器運(yùn)行的話,對于藝術(shù)家來說是大大的好事。于是,p5.js 應(yīng)運(yùn)而生!

p5.js 第一個測試版在 2014年8月 發(fā)布。

更多的故事可在 p5.js 官網(wǎng) 中尋找,本文的目標(biāo)是光速入門 p5.js 。


找到 p5.js



快速上手

本文的目標(biāo)是和各位工友快速上手 p5.js,所以 CDN 的方式引入 p5.js,因?yàn)檫@樣非常快!

接下來我們試試在畫布創(chuàng)建一個圓形吧~


環(huán)境搭建

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'


在畫布創(chuàng)建一個圓形

我使用的開發(fā)工具是 vs code,并裝了 Live Server 插件。這個插件可以幫我們快速啟動一個服務(wù)端運(yùn)行當(dāng)前頁面,并具備熱更新的能力。啟動完服務(wù),在瀏覽器運(yùn)行指定頁面后,你代碼的每一次保存,瀏覽器都會自動刷新。


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

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


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

  • setup(): 可以理解為 p5.js 的一個生命周期,創(chuàng)建畫布的方法通常寫在 setup() 里。
  • draw(): 同樣可以理解為 p5.js 的一個生命周期,在這函數(shù)里的代碼會以 60幀每秒 的速度執(zhí)行。
  • createCanvas(): 創(chuàng)建畫布的方法,這個方法是 p5.js 在全局創(chuàng)建的,傳入畫布的寬高后,p5.js 會自動在頁面的最后插入一個 canvas 元素。
  • background(): 設(shè)置背景色,可以分別傳入 r、g、b ,該方法也是 p5.js 在全局創(chuàng)建的。
  • circle(): 創(chuàng)建圓形的方法,3個參數(shù)分別代表:圓心x坐標(biāo)、圓心y坐標(biāo)、直徑。


暫時只需大概了解一下怎么畫一個圓就行,詳細(xì)的后面會講到。



項(xiàng)目代碼結(jié)構(gòu)

使用 p5.js ,你可以理解為用這個工具創(chuàng)造一個“有生命”的世界。

  • 創(chuàng)造世界的工作是放在 setup() 函數(shù)里的。

  • “有聲明” 的意思是這個世界有生物,生物無時無刻都在活動。而活動的過程是放在 draw() 函數(shù)里。

setup()draw() 這兩個函數(shù)非常重要,在前端的世界里,你可以把 setup()draw() 理解為生命周期函數(shù)。


啟動函數(shù) setup

使用 CDN 的方式開發(fā)時,引入 p5.js 后就會在全局創(chuàng)建一些函數(shù)和常量。

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

setup() 在每個頁面都只能出現(xiàn)一次,并且它不能在一開始執(zhí)行后再次被調(diào)用。


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


繪圖 draw

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

draw() 會在 setup() 之后執(zhí)行,并且會重復(fù)的執(zhí)行。如果想打斷 draw() 可以試用 noLoop() 方法。

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


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


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



2D基礎(chǔ)圖形

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

先從最簡單的點(diǎn)線面開始學(xué)起~


點(diǎn) point

點(diǎn)是 p5.js 的基礎(chǔ)元素之一,語法如下:

point(x, y, [z])

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

  • x 表示點(diǎn)在 x 軸的坐標(biāo)
  • y 表示點(diǎn)在 y軸的坐標(biāo)


點(diǎn)出現(xiàn)在畫布的中間

file
<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像素,點(diǎn)在 100, 100 的位置,仔細(xì)看可以發(fā)現(xiàn)點(diǎn)出現(xiàn)在畫布的中心。


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

file
<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) // 更大的點(diǎn)
  }
</script>

其實(shí) strokeWeight() 方法是用來設(shè)置描邊粗細(xì)的,用在 point 里也完全沒問題。


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


線段 line

要畫一根線段的語法:

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

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

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

line(x1, y1, x2, y2)
  • x1y1 代表起點(diǎn)坐標(biāo)
  • x2y2 代表終點(diǎn)坐標(biāo)

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


file
<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()說明文檔


三角形 triangle

三角形的語法是:

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

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

三角形有3個點(diǎn),每個點(diǎn)需要用2個坐標(biāo)(x和y)來描述,所以 triangle() 一共要傳入6個參數(shù)。


經(jīng)過前面的 點(diǎn)(point) 和 線段(line) 練習(xí),相信你看到三角形的參數(shù)名稱就已經(jīng)知道什么意思了。

確定了3個點(diǎn)的坐標(biāo)后,triangle() 會使用直線連接這3個點(diǎn),形成一個三角形。


file
<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()說明文檔


正方形 square

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

所以先從正方形講起。


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

square(x, y, s, [tl], [tr], [br], [bl])
  • xy 是正方形左上角的坐標(biāo)
  • s 是正方形的邊長

tl、tr、brbl 是用來設(shè)置正方形的圓角半徑,分別是 上左、上右、下右、下左。如果不傳這幾個參數(shù),正方形的角默認(rèn)是90°(直角)。


file
<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>


圓角半徑

圓角半徑參數(shù)遵循以下規(guī)則:

省略的角半徑參數(shù)設(shè)置為參數(shù)列表中先前指定的半徑值的值。

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


file
<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個圓角半徑,那第三和第四個圓角半徑的值會取第二個的值。


file
<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()說明文檔


矩形 rect

前面了解完 正方形(quad) 如何創(chuàng)建后,學(xué)習(xí) 矩形(rect) 會覺得非常簡單。

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

語法如下:

rect(x, y, w, [h], [tl], [tr], [br], [bl])
  • xy 是矩形左上角坐標(biāo)位置
  • w 是邊長

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

file
<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個參數(shù)的話,就可以分別設(shè)置長和寬了,第3和第4個參數(shù)分別是 wy。

  • w: x軸方向的長度(寬)
  • h: y軸方向的長度(高)


file
<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個參數(shù) tltr、brbl 分別設(shè)置四個角的圓角半徑,不設(shè)置的話默認(rèn)就是90°。用法和正方形一樣的,自己動手試試看吧~


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


四邊形 quad

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

四邊形有4個頂點(diǎn),1個定點(diǎn)用2個參數(shù)表示 xy 坐標(biāo)。

語法如下:

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

需要注意繪制四邊形時頂點(diǎn)的繪制順序


file
<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()說明文檔


圓形 circle

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

語法如下:

circle(x, y, d)
  • xy 是圓形的坐標(biāo)
  • d 是圓的直徑


file
<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()說明文檔


橢圓 ellipse

使用 ellipse() 可以創(chuàng)建橢圓,橢圓(ellipse) 的創(chuàng)建方法和 矩形(rect) 其實(shí)是有點(diǎn)像的。

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

語法如下:

ellipse(x, y, w, [h])
  • xy 確定了橢圓的圓心
  • w 橢圓在x軸的寬度
  • h 橢圓在y軸的高度

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

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


file
<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()說明文檔


弧狀 arc

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

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

先來看看語法:

arc(x, y, w, h, start, stop, [mode], [detail])
  • xy: 圓弧的圓心坐標(biāo)
  • w : x軸方向的寬度
  • h: y軸方向的高度
  • start: 弧形開始的角度(用弧度定義)
  • stop: 弧形結(jié)束的角度(用弧度定義)
  • mode: 定義弧形的畫法??蛇x值:開放式半圓形(OPEN),封閉式半圓形(CHORD),封閉式餅形段(PIE)
  • detail: 指定構(gòu)成圓弧周長的頂點(diǎn)數(shù)量,在 2D 模式下不會用到


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

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


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

file
<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 的效果

file
<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() {
    // 左上角的圖形,默認(rèn)
    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 已經(jīng)在全局定義好了。


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



其他圖形

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

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



文本

創(chuàng)建文本的方法叫 text()。

語法如下:

text(str, x, y, [x2], [y2])
  • str: 文本
  • xy 是文本基線左側(cè)的坐標(biāo)
  • x2y2 定義文本內(nèi)容占用的面積,x2 表示寬度,y2 表示高度。


file
<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 參數(shù)來控制內(nèi)容的展示方式。

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

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

比如一個字符的寬度是 5px ,x 設(shè)為10,x2 設(shè)為20,那么一行就可以展示2個文字。

x2 并不能很好的控制文本長度,它只會判斷這行文本里有沒有空格,如果出現(xiàn)空格,且超出文本框?qū)挾鹊膬?nèi)容就會換行。


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


舉個例子

file
<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 的限制下,文本已經(jīng)無法完全展示出來了。



基礎(chǔ)樣式

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


顏色

p5.js 支持多種顏色值,比如 顏色關(guān)鍵字十六進(jìn)制CSS顏色字符串、RGB、HSB、HSL灰度。


關(guān)鍵字 與 十六進(jìn)制

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

  • 關(guān)鍵字: 'red'、'blue' 等
  • 十六進(jìn)制: #ff0000


需要注意的是 RGBHSBHSL灰度。

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


RGB

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

如果不傳第4個參數(shù),默認(rèn)值是 255。

我用 background 背景色來舉例。

file
<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) // 設(shè)置綠色背景色
  }
</script>

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

比如

file
background(152, 231, 162, 100)


HSB 與 HSL

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

  • HSB: H(Hue) 色相、S(Saturation) 飽和度、B(Brightness) 亮度
  • HSL: H(Hue) 色相、S(Saturation) 飽和度、L(Lightness) 明度

它們二者之間的區(qū)別可以自行百度搜搜,或者可以看看這篇文章:《色彩空間中的 HSL、HSV、HSB 有什么區(qū)別?》。這不是本文的重點(diǎn)。


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

  1. 使用 HSBHSL 前,要設(shè)置顏色模式,告訴 p5.js 要使用哪種顏色模式去渲染。而 RGB 就省略了這步。
  2. HSBHSL 第1個參數(shù)取值 0 ~ 360,第2和第3個參數(shù)取值是 0 ~ 100。而 RGB 前3個參數(shù)的取值都是 0 ~ 255。
  3. 在透明度上,HSBHSL 在第4個參數(shù)的取值范圍是 0 ~ 1 ,而 RGB0 ~ 255 。

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


還是用 background() 舉例

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


灰度

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

灰度模式是默認(rèn)的顏色模式,不需要進(jìn)行特殊設(shè)置。

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


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

還是拿 background() 舉例

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


背景色 background()

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

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

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

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


填充顏色 fill()

創(chuàng)建圖像后,圖像默認(rèn)的填充色是白色。

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

file
<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') // 設(shè)置填充色
    rect(30, 30, 100, 80)
    circle(220, 70, 80)
  }
</script>

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

如果希望后面的圖形使用別的顏色,可以再重新調(diào)用一遍 fill() 進(jìn)行設(shè)置。

file
<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') // 設(shè)置填充色
    rect(30, 30, 100, 80)
    fill('yellow') // 重新設(shè)置填充色
    circle(220, 70, 80)
  }
</script>


無填充 noFill()

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

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

file
<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 創(chuàng)建出來的元素默認(rèn)是有一個黑色邊框,如果想要修改邊框顏色,可以使用 stroke() 方法。

file
<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') // 設(shè)置邊框顏色
    rect(30, 30, 100, 80)
    circle(220, 70, 80)
  }
</script>

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


無邊框 noStroke()

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

file
<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>


設(shè)置邊框粗細(xì) strokeWeight()

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

file
<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) // 設(shè)置邊框粗細(xì)
    rect(30, 30, 100, 80)
    circle(220, 70, 80)
  }
</script>


修改文字大小 textSize()

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

file
<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>


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



圖片

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

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

preload() 可以強(qiáng)制程序等待,直到 preload() 函數(shù)內(nèi)的資源加載完成或者事件執(zhí)行完再執(zhí)行其他代碼。

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


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

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

本例請來的演員是我的貓 Bubble

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

  function preload() {
    img = loadImage('./cat-bubble.jpg') // 加載圖片
  }

  function setup() {
    createCanvas(200, 200) // 創(chuàng)建畫布
  }

  function draw() {
    image(img, 0, 0) // 渲染圖片
  }
</script>
  • loadImage() 方法傳入圖片地址
  • image(img, x, y) 方法第一個參數(shù)是圖片對象。xy 是圖片左上角的坐標(biāo)。


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

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

  function preload() {
    img = loadImage('./portrait.gif') // 加載 gif
  }

  function setup() {
    createCanvas(240, 150)
  }

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

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



交互事件

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

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


鼠標(biāo)點(diǎn)擊 mouseIsPressed

本例使用 mouseIsPressed 判斷用戶是否點(diǎn)擊了鼠標(biāo),點(diǎn)擊鼠標(biāo)時畫布背景是藍(lán)色,松開鼠標(biāo)后畫布背景是橙色

file
<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) { // 檢測鼠標(biāo)是否按下
      background('skyblue')
    } else {
      background('orange')
    }
  }
</script>

draw() 函數(shù)在頁面運(yùn)行時會一直執(zhí)行,所以 mouseIsPressed 寫在 draw() 里可以被捕捉到。如果用戶點(diǎn)擊鼠標(biāo),且被捕捉到 mouseIsPressed 時,mouseIsPressed 會返回 true。


按住鍵盤 keyIsPressed

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


file
<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>



動畫

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

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


舉個例子:圓形圖案跟隨鼠標(biāo)指針移動

file
<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>


有沒有發(fā)現(xiàn),上面的例子在 draw() 里首先設(shè)置背景色,再創(chuàng)建一個新的圓。

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

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

file
<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官網(wǎng)的例子


到此,相信各位工友已經(jīng)對 p5.js 有一定的了解了。



代碼倉庫

?P5.js 學(xué)習(xí)案例



推薦閱讀

??《Canvas 從入門到勸朋友放棄(圖解版)》

??《SVG 從入門到后悔,怎么不早點(diǎn)學(xué)起來(圖解版)》

??《Three.js 起飛》

??《Fabric.js 從入門到膨脹》

??《純CSS實(shí)現(xiàn)117個Loading效果》

??《這18個網(wǎng)站能讓你的頁面背景炫酷起來》


點(diǎn)贊 + 關(guān)注 + 收藏 = 學(xué)會了
代碼倉庫

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容