眨個眼就學會了 Pixi-js

作者:德育處主任

https://juejin.cn/post/7215100383599870010

當今的 Web 開發中,圖形和動畫已經成爲了吸引用戶注意力的重要手段之一。而 Pixi.js 作爲一款高效、易用的 2D 渲染引擎,已經成爲了許多開發者的首選~~(我吹的)~~。本文將介紹 PixiJS 的基礎知識和使用方法,希望可以光速入門,掌握 Pixi.js 的用法。

實際工作中我還沒有用上 Pixi.js,本文只是記錄我的學習過程。將我認爲入門時需要掌握的知識點記錄下來。所以,你們懂的,太難的問題我回答不上,或者我會用拆特雞皮蹄敷衍你。

環境搭建

本文將使用原生三件套的方式講解如何使用 Pixi.js,你可以根據自己的需求搭建環境。

我使用 VS Code 開發,並在 VS Code 安裝了 Live Server 插件 [1] 方便啓動本地服務。

創建好項目後就需要安裝 Pixi.js,常用的方式有 CDNNPM,選其中一種就行。

本文使用 Pixi.js 7.2 版本

CDN

本文爲了和各位工友一起快速上手 Pixi.js ,所以會使用 CDN 的方式引入 Pixi.js

<script src="https://pixijs.download/release/pixi.js"></script>

在實際項目開發中,你最好還是將 Pixi.js 保存到你的項目中再引入。

根據你的項目需求選擇對應的 Pixi.js 版本:

🔗 Pixi.js 歷史版本下載地址:

https://github.com/pixijs/pixijs/releases

NPM

工作中很多項目都會使用腳手架的方式進行開發,通常也會使用 npm 的方式下載依賴包。Pixi.js 也提供了這種方式。

npm i pixi.js

下載好 Pixi.js 後,在需要用到 Pixi.js 的頁面中引入即可。

import * as PIXI from 'pixi.js'

其他依賴包

在創建一些特殊圖形時你可以還需要使用到 @pixi/graphics-extras

CDN

<script src="https://cdn.jsdelivr.net/npm/@pixi/graphics-extras@7.x/dist/graphics-extras.min.js"></script>

NPM

npm install @pixi/graphics-extras

這是 @pixi/graphics-extras 的 npm 地址:https://www.npmjs.com/package/@pixi/graphics-extras

起步

首先要做的是使用 Pixi.js 創建一個畫布,並將該畫布添加到頁面中。

創建畫布

分 2 步走:

  1. 使用 Pixi.js 創建畫布

  2. 將畫布添加到頁面中

<script src="https://pixijs.download/release/pixi.js"></script>
<script>
  // 1、創建 pixi畫布
  let app = new PIXI.Application()

  // 2、將畫布添加到頁面中
  document.body.appendChild(app.view)
</script>

如果你使用 npm 的方式安裝 Pixi.js 就需要用下面這種寫法。

import * as PIXI from 'pixi.js' // 引入 Pixi.js

// 1、創建 pixi畫布
let app = new PIXI.Application()

// 2、將畫布添加到頁面中
document.body.appendChild(app.view)

前面這兩個例子都是將畫布添加到頁面,你也可以根據需求將畫布添加到指定元素裏。

<div id="d1" style="margin: 100px; border: 1px solid red;"></div>

<script src="https://pixijs.download/release/pixi.js"></script>
<script>
  // 創建 pixi畫布
  let app = new PIXI.Application()

  // 找到id爲d1的元素
  let d1 = document.getElementById('d1')
  // 將畫布添加到d1元素裏
  d1.appendChild(app.view)
</script>

設置畫布寬高

Pixi.js 默認創建出來的畫布寬高是 800px * 600px

你可以在使用 Pixi.js 創建畫布的時候設置好畫布的寬高。

// 創建畫布時設置寬高
let app = new PIXI.Application({
  width: 640,
  height: 360
})

// 將畫布添加到頁面裏
document.body.appendChild(app.view)

設置畫布背景色

細心的工友可能已經發現,Pixi.js 創建出來的畫布背景默認是黑色的。你可以在創建畫布時手動設置背景色。

// 省略部分代碼...

let app = new PIXI.Application({
  backgroundColor: 'pink'
})

document.body.appendChild(app.view)

backgroundColor 接收一個顏色值,除了像上面這樣寫一個顏色關鍵詞,還可以傳入 rgb、十六進制等表示顏色的值。比如:

自動調整大小

如果希望畫布跟隨父元素大小改變,可以設置 resizeTo

比如,我想讓畫布跟隨瀏覽器窗口大小變化,可以這樣設置。

let app = new PIXI.Application({
  resizeTo: window
})

此時可能你會發現畫布的寬高好像導致瀏覽器產生了水平和垂直的滾動條,可以通過 CSS 解決這個問題。

html, body {
  margin: 0;
  padding: 0;
  width: 100%;
  height: 100%;
}

canvas {
  position: fixed;
  top: 0;
  left: 0;
}

銷燬畫布

使用 destroy() 方法可以銷燬畫布。

<button onclick="">刪除畫布</button>

<script>
// 省略創建畫布的代碼

// 刪除畫布
function delCanvas() {
  app.destroy()
}
</script>

細心的你可能發現了,上面的操作只是清除了畫布,<canvas> 元素還是留在頁面上的。

如果你想把 <canvas> 元素也清掉,可以使用 app.destroy() 時傳入 true

// 省略部分代碼

function delCanvas() {
  app.destroy(true)
}

基礎圖形

創建好畫布後,就開始學習一下如何創建基礎圖形。這也是我認爲入門階段最重要的內容。

先從最簡單的圖形說起,清楚 Pixi.js 可以創建哪些圖形後,後面的章節再講解如何設置樣式。

Pixi.js 創建圖形需要用到 GraphicsGraphics 裏包含了很多基礎圖形。

創建圖形需要做以下幾步:

  1. 實例化 Graphics 類。

  2. 設置填充或描邊顏色。

  3. 創建圖形。

  4. 執行繪製操作。

注意:以上幾個步驟一定要按順序做,一定要先設置顏色再創建圖形,不然圖形就可能沒顏色或者使用上下文的顏色。

矩形 (drawRect)

Pixi.js 提供了好幾種矩形,最基礎的是 drawRect。

語法

drawRect(x, y, width, height)

這語法和 原生Canvasrect() 方法很像。

看個例子:

// 創建畫布
let app = new PIXI.Application({
  width: 300,
  height: 300
})

// 將畫布添加到頁面
document.body.appendChild(app.view)

// 創建圖形類
const graphics = new PIXI.Graphics()
// 設置填充顏色 beginFill(顏色, 不透明度)
graphics.beginFill(0xffd900, 1)
// 創建圖形(矩形)
graphics.drawRect(50, 50, 200, 100)
// 繪製操作
graphics.endFill()

// 將繪製好的圖形添加到畫布中
app.stage.addChild(graphics)

圓角矩形 (drawRoundedRect)

瞭解了基礎的矩形怎麼創建之後,接下來的圖形都比較容易掌握了。

創建圓角矩形可以使用 drawRoundedRect() 方法,這個方法比普通矩形多一個圓角參數。

語法

drawRoundedRect(x, y, width, height, radius)

// 創建畫布
let app = new PIXI.Application({
width: 300,
height: 300
})

// 將畫布添加到頁面
document.body.appendChild(app.view)

// 創建圖形類
const graphics = new PIXI.Graphics()
// 設置填充顏色 beginFill(顏色, 不透明度)
graphics.beginFill(0xffd900, 1)
// 創建圓角矩形
graphics.drawRoundedRect(50, 50, 200, 100, 10) // 最後一個參數是圓角半徑
// 繪製操作
graphics.endFill()

// 將繪製好的圖形添加到畫布中
app.stage.addChild(graphics)

其實在用 drawRoundedRect 時,你不傳最後一個參數 radius 它也不會怪你的,因爲它本身有默認值嘛。

// 省略部分代碼...

graphics.drawRoundedRect(50, 50, 200, 100)

倒角矩形 (drawChamferRect)

我不知道把 drawChamferRect 翻譯成 “倒角矩形” 正不正確,意思就是將舉行的 4 個角切掉磨平。

drawChamferRect() 並不在 Pixi.js 的基礎包裏,你需要另外下載 @pixi/graphics-extrasCDNNPM 的地址在前面的《其他依賴包》章節。

drawChamferRect 語法

drawChamferRect(x, y, width, height, chamfer)

chamfer 參數就是倒角的切口,數值越大切口越大。

<!-- 引入 pixi -->
<script src="https://pixijs.download/release/pixi.js"></script>
<!-- 引入 graphics-extras,特殊圖形的包 --->
<script src="https://cdn.jsdelivr.net/npm/@pixi/graphics-extras@7.x/dist/graphics-extras.min.js"></script>

<script>
  // 創建畫布
  let app = new PIXI.Application({
    width: 300,
    height: 300
  })

  // 將畫布添加到頁面
  document.body.appendChild(app.view)

  // 創建圖形類
  const graphics = new PIXI.Graphics()
  // 設置填充顏色 beginFill(顏色, 不透明度)
  graphics.beginFill(0xffd900, 1)
  // 創建倒角矩形
  graphics.drawChamferRect(50, 50, 200, 100, 10) // 最後一個參數控制倒角切口大小
  // 繪製操作
  graphics.endFill()

  // 將繪製好的圖形添加到畫布中
  app.stage.addChild(graphics)
</script>

和圓角矩形不同,使用 drawChamferRect() 時一定要傳入最後一個參數。

倒圓角矩形 (drawFilletRect)

同樣的,我也不清楚用 “倒圓角矩形” 描述 drawFilletRect 這個方法有沒有問題,詳情看看效果圖。

要使用 drawFilletRect() 也需要引入 @pixi/graphics-extras

語法

DrawFilletRect(x,y,width,height,fillet)

參數 fillet 表示圓角半徑,它屬於 圓角矩形 drawRoundedRect 的升級版,因爲 fillet 可以接收負數。

fillet 是正數是,它畫出來的圖像和普通圓角矩形差不多;當 fillet 爲負數時,圓角就會向內凹進去。

<script src="../js/pixi.js"></script>
<script src="../js/graphics-extras.js"></script>
<script>
  // 創建畫布
  let app = new PIXI.Application({
    width: 300,
    height: 300
  })

  // 將畫布添加到頁面
  document.body.appendChild(app.view)

  // 創建圖形類
  const graphics = new PIXI.Graphics()
  // 設置填充顏色 beginFill(顏色, 不透明度)
  graphics.beginFill(0xffd900, 1)
  // 創建倒圓角矩形
  graphics.drawFilletRect(50, 50, 200, 100, -20) // 最後一個參數爲負數時,圓角向內凹進去
  // 繪製操作
  graphics.endFill()

  // 將繪製好的圖形添加到畫布中
  app.stage.addChild(graphics)
</script>

圓形 (drawCircle)

圓形是 Pixi.js 的基礎圖形,並不需要額外的引入 @pixi/graphics-extras.js

創建圓形的方法叫 drawCircle(),語法如下:

drawCircle(x, y, radius)

需要注意的是 xy ,它和矩形不同,矩形的 xy 是定義矩形左上角的位置。

// 創建畫布
let app = new PIXI.Application({
  width: 300,
  height: 300
})

// 將畫布添加到頁面
document.body.appendChild(app.view)

// 創建圖形類
const graphics = new PIXI.Graphics()
// 設置填充顏色 beginFill(顏色, 不透明度)
graphics.beginFill(0xffd900, 1)
// 創建圓形
graphics.drawCircle(100, 100, 50) // x, y, radius
// 繪製操作
graphics.endFill()

// 將繪製好的圖形添加到畫布中
app.stage.addChild(graphics)

橢圓 (drawEllipse)

使用 drawEllipse() 方法可以繪製橢圓,該方法是 Pixi.js 提供的,無需額外引入 @pixi/graphics-extras.js

語法

drawEllipse(x, y, width, height)

需要注意,在 Pixi.js 中,橢圓是用寬高來表示的。其他 Canvas 庫的橢圓寬高可能會用 xy 方向的半徑來表示,比如 Fabric.js 的橢圓 [2] ,這點大家需要注意一下。

// 創建畫布
let app = new PIXI.Application({
  width: 300,
  height: 300
})

// 將畫布添加到頁面
document.body.appendChild(app.view)

// 創建圖形類
const graphics = new PIXI.Graphics()
// 設置填充顏色 beginFill(顏色, 不透明度)
graphics.beginFill(0xffd900, 1)
// 創建橢圓
graphics.drawEllipse(100, 50, 100, 50) // x, y, width, height
// 繪製操作
graphics.endFill()

// 將繪製好的圖形添加到畫布中
app.stage.addChild(graphics)

多邊形 (drawPolygon)

使用 drawPolygon() 方法可以繪製多邊形,該方法接收 1 個參數,這個參數是一個數值型數組,用來表示多邊形頂點座標。

drawPolygon 方法會自動將起始點和結束點連接起來,形成一個封閉的圖形。

語法

drawPolygon(…path)

// 這是我書寫習慣
drawPolygon([
	x1, y1,
	x2, y2,
	x3, y3,
	......
])

// 創建畫布
let app = new PIXI.Application({
  width: 300,
  height: 300
})

// 將畫布添加到頁面
document.body.appendChild(app.view)

// 創建圖形類
const graphics = new PIXI.Graphics()
// 設置填充顏色 beginFill(顏色, 不透明度)
graphics.beginFill(0xffd900, 1)

// 路徑,兩兩一組代表一個座標
const path = [
  30, 30,
  100, 50,
  100, 180,
  30, 200
]

// 創建多邊形
graphics.drawPolygon(path)
// 繪製操作
graphics.endFill()

// 將繪製好的圖形添加到畫布中
app.stage.addChild(graphics)

路徑座標是兩兩一組的,二維世界裏一個點用 x 和 y 兩個座標來描述。

上面是我的書寫習慣,比較容易看出點的位置和數量。

正多邊形 (drawRegularPolygon)

正方形、等邊三角形都屬於正多邊形。

Pixi.js 裏,使用 drawRegularPolygon() 方法可以繪製正多邊形,但前提是要引入 @pixi/graphics-extras.js

語法

drawRegularPolygon(x, y, radius, sides, rotation)

需要注意的是,rotation 是以弧度爲單位的,如果想直觀的表達角度,可以用下面這條公式

角度 * Math.PI / 180

舉個例子

<!-- 引入 pixi -->
<script src="https://pixijs.download/release/pixi.js"></script>
<!-- 引入 graphics-extras,特殊圖形的包 --->
<script src="https://cdn.jsdelivr.net/npm/@pixi/graphics-extras@7.x/dist/graphics-extras.min.js"></script>

<script>
  // 創建畫布
  let app = new PIXI.Application({
    width: 300,
    height: 300
  })

  // 將畫布添加到頁面
  document.body.appendChild(app.view)

  // 創建圖形類
  const graphics = new PIXI.Graphics()
  // 設置填充顏色 beginFill(顏色, 不透明度)
  graphics.beginFill(0xffd900, 1)

  // 創建正多邊形
  // x, y, 半徑(圖形尺寸), 邊數, 旋轉弧度
  graphics.drawRegularPolygon(40, 40, 30, 6, 10 * Math.PI / 2)
  // 繪製操作
  graphics.endFill()

  // 將繪製好的圖形添加到畫布中
  app.stage.addChild(graphics)

</script>

圓角正多邊形 (drawRoundedPolygon)

Pixi.js 使用 drawRoundedPolygon() 方法繪製圓角,使用該方法之前需要引入 @pixi/graphics-extras.js

語法

drawRoundedPolygon(x, y, radius, sides, corner, rotation)

相比起正多邊形,圓角正多邊形多了個圓角,所以需要傳入的參數也會比正多邊形多一個圓角半徑

舉個例子

<!-- 引入 pixi -->
<script src="https://pixijs.download/release/pixi.js"></script>
<!-- 引入 graphics-extras,特殊圖形的包 --->
<script src="https://cdn.jsdelivr.net/npm/@pixi/graphics-extras@7.x/dist/graphics-extras.min.js"></script>

<script>
  // 創建畫布
  let app = new PIXI.Application({
    width: 300,
    height: 300
  })

  // 將畫布添加到頁面
  document.body.appendChild(app.view)

  // 創建圖形類
  const graphics = new PIXI.Graphics()
  // 設置填充顏色 beginFill(顏色, 不透明度)
  graphics.beginFill(0xffd900, 1)

  // 創建圓角正多邊形
  // x, y, 半徑(圖形尺寸), 邊數, 圓角, 旋轉弧度
  graphics.drawRoundedPolygon(100, 100, 80, 6, 10, 10 * Math.PI / 180)
  // 繪製操作
  graphics.endFill()

  // 將繪製好的圖形添加到畫布中
  app.stage.addChild(graphics)

</script>

環形 (drawTorus)

環形也是特殊圖形,同樣 需要引入 @pixi/graphics-extras.js

創建環形的方法是 drawTorus()

語法

drawTorus(x, y, innerRadius, outerRadius, startArc, endArc)

如果不填寫 startArcendArc ,畫出來的是一個沒缺口的環形。

經過前面幾個圖形的鍛鍊,本例開始就省略一些套路式的代碼了。

// 創建畫布
let app = new PIXI.Application({
  width: 300,
  height: 300
})

// 將畫布添加到頁面
document.body.appendChild(app.view)

// 創建圖形類
const graphics = new PIXI.Graphics()
// 設置填充顏色 beginFill(顏色, 不透明度)
graphics.beginFill(0xffd900, 1)

// 創建環形,只傳入4個參數 x, y, 內圓半徑, 外圓半徑
graphics.drawTorus(100, 100, 30, 60)
// 繪製操作
graphics.endFill()

// 將繪製好的圖形添加到畫布中
app.stage.addChild(graphics)

如果把開始位置和結束位置也設置一下,就有可能得到一個 “不閉合” 的環形

// 創建環形
graphics.drawTorus(100, 100, 30, 60, 0.5, 5.5)

星形 (drawStar)

星形 drawStar() 也是特殊圖形, 需要引入 @pixi/graphics-extras.js

語法

drawStar(x, y, points, radius, innerRadius, rotation)

繪製圖形 (drawShape)

從官方文檔的描述來看,drawShape() 方法是可以繪製任何圖形的。

Draw any shape.

// 省略部分代碼......

// 創建圖形類
const graphics = new PIXI.Graphics()
// 設置填充顏色 beginFill(顏色, 不透明度)
graphics.beginFill(0xffd900, 1)

// 創建一個多邊形對象
const path2 = new PIXI.Polygon([
  10, 10, // 第一個點的座標
  50, 100, // 第二個點的座標
  100, 10 // 第三個點的座標
])

graphics.drawShape(path2)
// 繪製操作
graphics.endFill()

// 將繪製好的圖形添加到畫布中
app.stage.addChild(graphics)

在這個例子中我使用 PIXI.Polygon 建立了 3 個座標點的形狀,然後把結果丟進 drawShape 創建圖形。

折線 (moveTo 和 lineTo)

Pixi.js 裏使用 moveTo()lineTo()方法繪製折線,和 原生Canvas 很像。

// 省略部分代碼......

// 創建圖形類
const graphics = new PIXI.Graphics()
// 設置描邊顏色 beginFill(顏色, 不透明度)
graphics.lineStyle(4, 0xffd900, 1)

// 創建折線
graphics.moveTo(10, 40) // 起始點
graphics.lineTo(40, 20) // 經過的點
graphics.lineTo(50, 80)
graphics.lineTo(100, 70)

// 將繪製好的圖形添加到畫布中
app.stage.addChild(graphics)

閉合折線

在折線的基礎上,還可以在最後加上一個 closePath() 方法閉合折線。這就會形成一個封閉圖形。

closePath() 方法會將折線的起點和終點連接起來。

// 省略部分代碼......

// 創建圖形類
const graphics = new PIXI.Graphics()

// 設置秒變顏色
graphics.lineStyle(4, 0xffd900, 1)

graphics.moveTo(10, 40) // 起始點
graphics.lineTo(40, 20) // 經過的點
graphics.lineTo(50, 80)
graphics.lineTo(100, 70)

graphics.closePath() // 閉合

圓弧 (arc)

創建圓弧使用的方法是 arc()

語法

arc(cx, cy, radius, startAngle, endAngle, anticlockwise)

// 省略部分代碼......

// 創建圖形類
const graphics = new PIXI.Graphics()

// 設置線的顏色
graphics.lineStyle(4, 0xffd900, 1)

// 創建圓弧
graphics.arc(100, 100, 50, Math.PI, 2.3 * Math.PI)

// 將繪製好的圖形添加到畫布中
app.stage.addChild(graphics)

圓弧(arcTo)

你沒看錯,創建圓弧除了 arc() 方法外,還有 arcTo() 方法。

arcTo()Pixi.js 中的一個圖形繪製函數,用於繪製從當前點到指定點之間的弧線。

Pixi.jsarcTo() 方法其實和 原生CanvasarcTo() 用法差不多,在使用之前害需要 moveTo 配合。

Pixi.jsarcTo() 語法

arcTo(x1, y1, x2, y2, radius)

// 省略部分代碼......

// 創建圖形類
const graphics = new PIXI.Graphics()

// 創建折線
graphics.lineStyle(4, 0xffd900, 1)
graphics.moveTo(40, 40) // 先確定起始點
graphics.arcTo(120, 40, 120, 120, 80)
graphics.endFill()

// 將繪製好的圖形添加到畫布中
app.stage.addChild(graphics)

貝塞爾曲線

貝塞爾曲線是一種數學曲線,可以用於繪製複雜的圖形。在 Pixi.js 中,bezierCurveTo 方法可以用來繪製二次或三次貝塞爾曲線。

二次貝塞爾曲線有 3 個關鍵座標點:起始點、控制點、結束點。

三次貝塞爾曲線比二次貝塞爾曲線多 1 個控制點,理解了二次貝塞爾曲線就能理解三次貝塞爾曲線。

我用一張圖簡單講解一下二次貝塞爾曲線。

moveTo(50, 100) 是起始點,(100, 50)(150, 100) 是貝塞爾曲線的控制點。

將這 3 個座標連起來,也就是上圖所示的 2 條灰色的線。

在這兩條灰色的線上,各自平均畫了 4 個點,然後按順序把這些點連起來,如上圖所示。

最後,將第一條灰線和紅線點交點、紅線和黃線點交點、黃線和藍線點交點、藍線和綠線點交點以及綠線和最後一條灰線點交點連接起來。形成一條新的曲線。這就是貝塞爾曲線(下圖的紫線)。

因爲我畫的線比較少,所以形成的曲線還是有棱角。如果希望曲線更圓潤,你需要畫更多的線形成更多的交點。

說了這麼多,回到 Pixi.js ,看看使用 Pixi.js 怎麼畫貝塞爾曲線。

二次貝塞爾曲線

使用 quadraticCurveTo() 方法可以繪製二次貝塞爾曲線。

語法

quadraticCurveTo(cpX, cpY, toX, toY)

// 創建圖形類
const graphics = new PIXI.Graphics()

// 創建折線
graphics.lineStyle(4, 0xffd900, 1)

graphics.moveTo(50, 100)
graphics.quadraticCurveTo(100, 50, 150, 100) // 二次貝塞爾曲線

// 將繪製好的圖形添加到畫布中
app.stage.addChild(graphics)

三次貝塞爾曲線

Pixi.js 中,繪製三次貝塞爾曲線需要使用另一個方法:bezierCurveTo()

語法

bezierCurveTo(cpX, cpY, cpX2, cpY2, toX, toY)

繪製三次貝塞爾曲線同樣需要先使用 moveTo() 配合。

// 創建圖形類
const graphics = new PIXI.Graphics()

// 創建折線
graphics.lineStyle(4, 0xffd900, 1)

graphics.moveTo(50, 100)
graphics.bezierCurveTo(100, 50, 150, 100, 200, 100) // 三次貝塞爾曲線

// 將繪製好的圖形添加到畫布中
app.stage.addChild(graphics)

文本 Text

使用 Pixi.js 渲染文本非常簡單,只需用到 Text() 方法即可。

語法

new PIXI.Text(text, style, canvas)

在本小節我們只需知道 new PIXI.Text('文本內容') 這樣用即可,樣式部分我放在後面講解。

// 創建畫布
let app = new PIXI.Application({
  width: 300,
  height: 300,
  backgroundColor: 0xf0f0f0
})

// 將畫布添加到頁面
document.body.appendChild(app.view)

const text = new PIXI.Text('雷猴')

// 將文本添加到畫布中
app.stage.addChild(text)

使用 new PIXI.Text() 創建的文字默認是黑色,所以在本例中我把畫布背景色設置成淺灰色,方便觀察文字。

圖片

Pixi.js 裏,加載圖片資源需要做以下操作:

  1. 加載圖片紋理

  2. 將紋理放入 “精靈” 對象

  3. 將 “精靈” 添加到畫布中

// 創建畫布
let app = new PIXI.Application()

// 將畫布添加到頁面
document.body.appendChild(app.view)

// 加載圖片
const texture = PIXI.Texture.from('./dinosaur.png')
// 將紋理放在“精靈“的圖形對象上
const sprite = new PIXI.Sprite(texture)
// 將精靈添加到畫布中
app.stage.addChild(sprite)

使用 PIXI.Texture 方法加載圖片紋理,但這個方法前面是不需要 new 的,這點要注意!

PIXI.Texture.from() 除了加載本地圖片,還能加載網絡圖片。

const texture = PIXI.Texture.from('https://pixijs.io/examples/examples/assets/bunny.png')

常用樣式配置

終於來到樣式講解部分了。

前面講解的圖形、文本、圖片都是 Pixi.js 的基礎元素,他們都支持樣式設置。

基礎圖形樣式

圖形的樣式我用矩形來舉例。基礎圖形的寬高、半徑之類的使用方法在前面已經講過了,這裏不再重複。

填充色

使用 beginFill() 設置填充色。

使用 endFill() 可以結束上一個 beginFill() 方法定義的填充樣式。如果沒有調用endFill()方法,則填充樣式會一直應用到後續的所有形狀上,直到定義新的填充樣式。

在繪製圖形時,通常需要使用beginFill()方法定義填充樣式,然後使用drawRect()drawCircle()等方法繪製形狀,最後調用endFill()方法結束填充。

beginFill() 語法

beginFill(color, alpha)

顏色關鍵字

舉個例子(顏色關鍵字)

// 省略部分代碼......

// 創建圖形類
const graphics = new PIXI.Graphics()

// 設置填充顏色 beginFill
graphics.beginFill('hotpink')

// 創建圖形(矩形)
graphics.drawRect(50, 50, 200, 100)

// 繪製操作
graphics.endFill()

// 將繪製好的圖形添加到畫布中
app.stage.addChild(graphics)

在這個例子中,我傳入的是 'hotpink' 亮粉色。使用顏色關鍵字時,需要把關鍵字用單引號或者雙引號括起來。

十六進制

接下來看另一種情況:十六進制顏色表示法。

// 省略部分代碼......

// 十六進制顏色表示法
graphics.beginFill('#0fff00')

// 或者
graphics.beginFill(0x0fff00)

上面兩種寫法都是十六進制的顏色表示法,學過 CSS 的工友對這種顏色表示方法應該不陌生。

需要注意的是,如果你使用 # 開頭的方式,需要套上單引號或者雙引號,把它變成一個字符串。

如果不想套引號,就是用 0x 開頭的方式。

數值

接下來看看只傳入一個數字的情況。

beginFill(color) 裏的 color 參數默認值是 0。它表示黑色。

Pixi.js 會將你傳入的十進制數轉成十六進制。也就是說,0 會變成 0x000000

我們將上一個例子中的 0x0fff00 綠色轉成十進制再傳入 beginFill() 裏,出來的效果是一樣的。

我用手算法計算了一下,0x0fff00 轉成十進制後是 1048320

// 省略部分代碼......

graphics.beginFill(1048320)

現在應該知道爲什麼 beginFill() 默認是黑色了吧。

這種傳單個十進制數值的方法我們很少用。

不透明度

不透明度的配置方法就是給 beginFill() 傳入第二個參數,這個參數的取值範圍是 0 ~ 1 。默認值是 1。

graphics.beginFill('hotpink', 0.8)

這個太簡單了,我就不貼圖了,你們在自己電腦試試吧。

邊框樣式

lineStyle()Pixi.js 的描邊方法。

語法

lineStyle(width, color, alpha, alignment, native)

我們通常只用到前 3 個參數,甚至只是用到前 2 個參數。

const app = new PIXI.Application({
  width: 300,
  height: 300
})

document.body.appendChild(app.view)

const graphics = new PIXI.Graphics()

// 設置描邊寬度和顏色
graphics.lineStyle(2, 0xff0000)
graphics.drawRect(50, 50, 100, 100)

app.stage.addChild(graphics)

文本樣式

前面提到創建文本使用 new PIXI.Text() 方法,第一個參數是文本內容,第二個參數是樣式對象。

常用配置

常見的配置有字體、字號、填充色、描邊色。

// 省略部分代碼......

const text = new PIXI.Text(
  "雷猴",
  {
    fontFamily: 'Arial', // 字體
    fontSize: 36, // 字號
    fill: 'yellow', // 填充色
    stroke: 'red', // 描邊顏色
    strokeThickness: 2 // 描邊寬度,默認是0
  }
)

app.stage.addChild(text)

字距

letterSpacing 屬性可以設置字距。

const text = new PIXI.Text(
  "雷猴",
  {
    fill: 'yellow', // 填充色
    letterSpacing: 20
  }
)

文本投影

Pixi.js 裏設置文字投影需要配置一堆屬性,這堆屬性都是以 dropShadow 開頭的。

具體用法請看代碼註釋。

const text = new PIXI.Text(
  "雷猴",
  {
    fontSize: 60,
    fill: 'yellow', // 填充色
    dropShadow: true, // 開啓投影
    dropShadowColor: 'red', // 投影顏色
    dropShadowBlur: 6, // 投影羽化程度(模糊度)
    dropShadowAngle: 45 * Math.PI / 180, // 投影角度
    dropShadowDistance: 10 // 投影距離
  }
)

文本漸變填充

通過前面的例子我們已經知道設置文本的 fill 屬性可以配置文本顏色,其實這個屬性還可以傳入一個顏色數組,它就會變成漸變填充。

const text = new PIXI.Text(
  "雷猴",
  {
    fontSize: 60,
    fill: ['yellow''red''purple''blue'], // 填充色
  }
)

默認的漸變方向是從上往下,如果你想改成從左往右漸變,可以設置 fillGradientType 屬性。

const text = new PIXI.Text(
  "雷猴",
  {
    fontSize: 60,
    fill: ['yellow''red''purple''blue'], // 填充色
    fillGradientType: PIXI.TEXT_GRADIENT.LINEAR_HORIZONTAL
  }
)

fillGradientType 的默認值是 PIXI.TEXT_GRADIENT.LINEAR_VERTICAL ,就是讓漸變從上往下走。

PIXI.TEXT_GRADIENT.LINEAR_HORIZONTAL 可以讓漸變從左往右走。

PIXI.TEXT_GRADIENT.LINEAR_VERTICALPIXI.TEXT_GRADIENT.LINEAR_HORIZONTAL 都是 Pixi.js 提供的。

文本紋理

我們還可以使用圖片作爲文本的紋理。

操作步驟:

  1. 創建文字

  2. 加載圖片

  3. 將圖片設置爲文本的遮罩層

const text = new PIXI.Text(
  "雷猴,帶尬猴,我嗨德育處主任",
  {
    fontSize: 60,
    fontWeight: 900, // 字體重量
    fill: 0xffffff, // 必須設置非黑色的填充色
  }
)

// 加載圖片
const bunny = PIXI.Sprite.from('./pexels-alexander-grey.jpg')
// 設置圖片寬高
bunny.width = app.screen.width
bunny.height = app.screen.height

// 配置文字遮罩層
bunny.mask = text

// 注意!需要將遮罩層圖片添加到畫布中,而不是添加文字text
app.stage.addChild(bunny)

爲了方便演示,我還設置了 fontWeight 屬性,讓文本變得更粗。

這個例子我使用的圖片是這個:

圖片樣式

前面已經講過圖片怎麼使用了,本小節講講圖片常用的屬性。

寬高

通過設置 widthheight 可以修改圖片的寬高。

// 省略部分代碼

// 加載圖片
const texture = PIXI.Texture.from('./dinosaur.png')
// 將紋理放在“精靈“的圖形對象上
const sprite = new PIXI.Sprite(texture)

// 設置精靈寬高
sprite.width = 100
sprite.height = 100

// 將精靈添加到畫布中
app.stage.addChild(sprite)

位置

通過設置 xy 可以修改圖片的位置。

// 省略部分代碼

// 加載圖片
const texture = PIXI.Texture.from('./dinosaur.png')
// 將紋理放在“精靈“的圖形對象上
const sprite = new PIXI.Sprite(texture)

// 設置精靈寬高
sprite.x = 100
sprite.y = 100

// 將精靈添加到畫布中
app.stage.addChild(sprite)

旋轉

通過設置 rotation 屬性旋轉圖片。

// 省略部分代碼

// 加載圖片
const texture = PIXI.Texture.from('./dinosaur.png')
// 將紋理放在“精靈“的圖形對象上
const sprite = new PIXI.Sprite(texture)

// 往右移動精靈
sprite.x = 100
// 旋轉45度
sprite.rotation = 45 * Math.PI / 180

// 將精靈添加到畫布中
app.stage.addChild(sprite)

可見性

使用 visible 可以控制圖片的可見性。

當圖片的 visible 屬性設置爲 false 時就不可見了。

// 加載圖片
const texture = PIXI.Texture.from('./dinosaur.png')
// 將紋理放在“精靈“的圖形對象上
const sprite = new PIXI.Sprite(texture)

// 隱藏圖片
sprite.visible = false

透明度

通過 alpha 屬性可以設置圖片的不透明度,取值範圍是 0 ~ 1

// 省略部分代碼

// 加載圖片
const texture = PIXI.Texture.from('./dinosaur.png')
// 將紋理放在“精靈“的圖形對象上
const sprite = new PIXI.Sprite(texture)

// 設置不透明度
sprite.alpha = 0.6

濾鏡

濾鏡是個挺有意思的東西,濾鏡可以用來增強圖形的視覺效果,同時也可以用來實現各種特殊效果,例如模糊、發光等。Pixi.js 中的濾鏡功能十分簡單易用,只需要在對象上添加相應的濾鏡即可。

我拿幾款濾鏡出來講解一下,其他的濾鏡用法可以自行查閱文檔,不難的~

模糊濾鏡

使用 new PIXI.BlurFilter() 可以創建模糊濾鏡。

// 創建畫布
let app = new PIXI.Application({
  width: 300,
  height: 300
  // resizeTo: window
})

// 將畫布添加到頁面
document.body.appendChild(app.view)

// 加載圖片
const texture = PIXI.Texture.from('./dinosaur.png')
// 將紋理放在“精靈“的圖形對象上
const sprite = new PIXI.Sprite(texture)

// 模糊濾鏡
const blurFilter = new PIXI.BlurFilter()
// 模糊程度
blurFilter.blur = 10

// 將模糊濾鏡添加到圖片精靈上
sprite.filters = [blurFilter]

// 將精靈添加到畫布中
app.stage.addChild(sprite)

細心的工友可能已經發現,添加濾鏡是用數組存起來的:sprite.filters = [blurFilter]

這意味着一個元素可以同時使用多款濾鏡組合。

上面的寫法,其實還可以進一步簡化

const blurFilter = new PIXI.BlurFilter()
blurFilter.blur = 10

// 還可以這樣寫
const blurFilter = new PIXI.BlurFilter(10)

Alpha 濾鏡

Alpha 濾鏡可以設置元素的 Alpha 通道,也就是能設置元素的不透明度,正常的取值範圍是 0 ~ 1

// 省略部分代碼

// Alpha濾鏡
const alphaFilter = new PIXI.AlphaFilter(0.5)

// 將濾鏡添加到精靈上
sprite.filters = [alphaFilter]

剛剛說了,正常取值 0 ~ 1,那不正常取值呢?

我測試了一下,如果取值超出 1,元素就會出現過曝的效果。如果取值小於 0,會保持透明。

const alphaFilter = new PIXI.AlphaFilter(2)

其他濾鏡我就不在本文過多講解了,有興趣的可以自行查閱文檔。

事件

Pixi.js 提供了許多交互事件,以便用戶可以與場景中的元素進行交互。在 Pixi.js 中,交互事件可以是鼠標事件,也可以是觸摸事件。

由於用法比較簡單,我用鼠標事件舉例。

鼠標點擊事件

點擊事件會在用戶單擊鼠標或觸摸屏時觸發,在 Pixi.js 裏,點擊事件叫 click

完整用法如下所示

// 創建畫布
let app = new PIXI.Application({
  width: 300,
  height: 300
  // resizeTo: window
})

// 將畫布添加到頁面
document.body.appendChild(app.view)

// 創建矩形
const rect = new PIXI.Graphics()
rect.beginFill(0xff6600)
rect.drawRect(0, 0, 64, 64)
rect.endFill()

// 開啓交互模式
rect.interactive = true
// 設置指針樣式
rect.cursor = "pointer"

// 矩形的點擊事件
rect.on('click'() ={
  console.log('click')
})

// 將精靈添加到畫布中
app.stage.addChild(rect)

上面的代碼有幾個關鍵信息:

  1. 首先需要開啓交互模式 rect.interactive = true

  2. 如果你希望鼠標移入元素內指針會發生變化,可以設置 rect.cursor = "pointer"

  3. 使用 xxx.on('事件名', 回調函數) 的方式監聽指定事件。

如果是在移動端,你就需要使用 tap 代替 click 事件了。

👉 點擊查看 Pixi.js 更多事件: https://pixijs.download/release/docs/PIXI.BitmapText.html#added

動畫

動畫是一種通過在一段時間內連續播放一系列圖像來創造運動效果的藝術形式。在計算機圖形學中,動畫通常是通過在相鄰的幀之間進行微小的變化來實現的。Pixi.js 是一個強大的 2D 渲染引擎,可以用於創建各種類型的動畫。

Pixi.js 提供了一個處理循環的對象 ticker,它是 Pixi.js 的核心組件之一。這個對象可以幫助我們創建各種類型的動畫效果,例如移動、旋轉、縮放等。ticker 可以自動更新場景,並在每個幀之間執行我們指定的代碼。

比如,我想讓矩形旋轉起來。

// 創建畫布
let app = new PIXI.Application({
  width: 300,
  height: 300
  // resizeTo: window
})

// 將畫布添加到頁面
document.body.appendChild(app.view)

// 創建矩形
const rectangle = new PIXI.Graphics()
rectangle.beginFill(0xff6600)
rectangle.drawRect(0, 0, 64, 64)
rectangle.endFill()

// 將精靈添加到畫布中
app.stage.addChild(rectangle)


app.ticker.add((delta) ={
 // 讓矩形旋轉起來
  rectangle.rotation += 0.1 * delta
})

ticker 是一個用來處理循環的對象,它負責在每一幀更新和重新渲染畫布。

delta 是一個與時間相關的因子,通常用於處理動畫循環。 delta 是上一幀和當前幀之間經過的時間的比例值。這個值可以用於確保動畫在不同性能和速度的設備上儘可能保持一致的表現。

細心的工友可能發現了,矩形是圍繞這它的左上角進行旋轉的。

如果想讓矩形進行中心旋轉,可以設置它的 pivot 的值爲自身寬高的一半。

// 省略部分代碼

// 創建矩形
const rectangle = new PIXI.Graphics()
rectangle.beginFill(0xff6600)
rectangle.drawRect(0, 0, 64, 64)
rectangle.endFill()

// 修改矩形的軸心點
rectangle.pivot.set(32, 32)

// 將矩形移動到畫布中間
rectangle.x = app.screen.width / 2
rectangle.y = app.screen.height / 2

app.ticker.add((delta) ={
 // 讓矩形旋轉起來
  rectangle.rotation += 0.1 * delta
})

其他

Pixi.js 的功能遠不止這些,由於篇幅有限,無法一一列舉所有的功能。

參考資料

[1]

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

[2]

https://juejin.cn/post/7026941253845516324#heading-30: https://juejin.cn/post/7026941253845516324#heading-30

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