pixi.js 入门学习(v7)

720 阅读4分钟

载入

1.安装pixi.js

npm install pixi.js@7.1.1

2.引入

import * as PIXI from 'pixi.js';
// or 每个类单独引用
import { Application, Graphics } from 'pixi.js';

(1) 创建Application

  1. 要使用Pixi,我们要先创建一个Pixi Application的实例。
  2. Pixi会产生canvas元素,我们要再把它放到DOM里。
// 创建应用
const app = new PIXI.Application({
  width: window.innerWidth,
  height: window.innerHeight,
  backgroundColor: 0x1099bb,
  resolution: window.decodeURIComponent || 1,
})

// or
const app = new Application({
  width: window.innerWidth,
  height: window.innerHeight,
  antialias: true,  // 反锯齿
  background: '0x23395d'
});

document.body.appendChild(app.view)

(2) 绘制Graphics(图形)

  • Pixi的各种形状都在Grahpics这个Class底下,我们创建的形状无论是方形、圆型、线条…等,都是Grahpics的实例。
  • 画好形状后,要把这个形状放到舞台(stage)上面。可把stage想像成是HTML的 <body>,所有要显示的东西都要放到这边。
// 线条
let line = new Graphics()
line.lineStyle(5, 0xde3249, 1)
line.moveTo(100, 500).lineTo(200, 500)
app.stage.addChild(line);

// 矩形
let rectangle = new Graphics();
rectangle.beginFill(0x66CCFF, 0.3);
rectangle.drawRect(100, 100, 164, 64);
rectangle.endFill();
app.stage.addChild(rectangle);

(3) 文字

// 文字样式
const myStyle = new TextStyle({
  fontFamily: 'Arial',
  fontSize: 36,
  fontStyle: 'italic',
  fontWeight: 'bold',
  fill: '#ffffff',
  stroke: '#4a1850',
})
// 創建文字
const myText = new Text('Hello World!!', myStyle);

app.stage.addChild(myText);

(4) Texture 和 Sprite

  • 在 pixi 中,不能直接使用图片,要先把图片转为 texture,再把 textrure 转成 sprite。
  • 什么是 texture?
    • 因为 Pixi 使用 WebGL 在 GPU 上渲染图像,图像需要转换为 GPU 可以处理的东西,這个东西被称为 texture
  • 什么是 sprite ?
    • sprite 是 pixi 的物件,我们可以控制它的大小、位置…等,图片都要轉為 sprite 的形式,才能添加到舞台。
// 纹理
const texture = Texture.from('../public/textures/shajin1.png')
// 创建精灵
const sprite = new Sprite(texture)

// 设置锚点
sprite.anchor.set(0.5, 0.5)

// 设置精灵位置
sprite.x = app.screen.width / 2
sprite.y = app.screen.height / 2

// 设置宽高
sprite.width = 500
sprite.height = 500

// 设置缩放
sprite.scale.set(0.8, 0.8)

//设置精灵透明度
sprite.alpha = 1

app.stage.addChild(sprite)

(5) Container

  • 前面范例中,都是把文字、形状、图片…等直接加到舞台,我们也可以先把这些东西放到 container 里变成一组,再加到舞台上。
  • 使用 Container() 创建 container
  • 也可改变 container 及里面物件的的大小、位置。
  • container 里面物件的位置是相对于 container (可以想像成:container 是 css 中的 position: relative,而里面物件是 position: absolute 的概念)
const myImageTexture = await Assets.load('https://img02.songzhaopian.cn/rzt/2024/05/13/038e76d3-6a59-4a9a-bd9f-c2af6481f198.png')

const sprite1 = new Sprite(myImageTexture)
// 锚点
sprite1.anchor.set(0.5, 0.5)
// 位置
sprite1.x = app.screen.width / 2
sprite1.y = app.screen.height / 2

// 创建文字
const myText = new Text('Welcome to China!!', {
  fontFamily: 'Arial',
  fontSize: 36,
  fontStyle: 'italic',
  fontWeight: 'bold',
  fill: '#ffffff',
  stroke: '#4a1850',
})
myText.position.set(0, 0)

// 创建容器
let container = new Container()
container.addChild(sprite1)
container.addChild(myText)


app.stage.addChild(container)

(6) Ticker (动画效果)

  • 使用 pixi 的 ticker 来创建循环函数
  • 每秒循环次数依使用者装置的帧数而不同,例如:使用者用的是60hz的屏幕,函数就会每秒被呼叫60次。ticker 有一个 delta 参数,因使用者装置的帧数不同,动画效果会有差异,要用 delta 来修正。
// 纹理
const texture = Texture.from('../public/textures/shajin1.png')
// 创建精灵
const sprite = new Sprite(texture)

// 设置锚点
sprite.anchor.set(0.5, 0.5)

// 设置精灵位置
sprite.x = app.screen.width / 2
sprite.y = app.screen.height / 2

// 设置宽高
sprite.width = 500
sprite.height = 500

// 设置缩放
sprite.scale.set(0.8, 0.8)

//设置精灵透明度
sprite.alpha = 1

// ticker实例动画
app.ticker.add((delta) => {
  sprite.rotation += 0.01 * delta
})
app.stage.addChild(sprite)

(7) 事件绑定

// 创建矩形
const rectangle = new Graphics()
rectangle.beginFill(0xaaffaa).drawRect(300, 400, 100, 100).endFill()

app.stage.addChild(rectangle)

function moveRight () {
  rectangle.x += 10
}

// 设为可互动的
rectangle.eventMode = 'dynamic'
rectangle.cursor = 'pointer'

// 绑定点击事件

rectangle.on('pointerdown', moveRight)
window.addEventListener('keydown', (e) => {
  const { code } = e
  if (code === 'Space') {
    moveRight()
  }
})

(8) Asset(资源加载)

Asset类可以载入素材,可以是图片或JSON文件

  1. 用 Assets 来载入图片,它会回传一个 promise
  2. 当 promise 执行成功,就会回传这个图片的 texture
  3. 再把这个 texture 转成 sprite
  4. 放到舞台上

add

Assets.add('shajin1', '../public/textures/shajin1.png')
Assets.add('shajin2', '../public/textures/shajin2.png')
Assets.add('wukong', '../public/textures/wukong.png')
const myTextrues = await Assets.load(['shajin1', 'shajin2', 'wukong'])
// 图1
let sprite1 = new Sprite(myTextrues.shajin1)
sprite1.width = 300
sprite1.height = 300
app.stage.addChild(sprite1)
// 图2
let sprite2 = new Sprite(myTextrues.shajin2)
sprite2.width = 300
sprite2.height = 300
sprite2.position.set(300, 0)
app.stage.addChild(sprite2)
// 图3
let sprite3 = new Sprite(myTextrues.wukong)
sprite3.width = 300
sprite3.height = 300
sprite3.position.set(600, 0)
app.stage.addChild(sprite3)

load

const myImageTexture = await Assets.load('https://img02.songzhaopian.cn/rzt/2024/05/13/038e76d3-6a59-4a9a-bd9f-c2af6481f198.png')

const sprite1 = new Sprite(myImageTexture)
// 锚点
sprite1.anchor.set(0.5, 0.5)
// 位置
sprite1.x = app.screen.width / 2
sprite1.y = app.screen.height / 2

app.stage.addChild(sprite1)

addBundle

Assets.addBundle('imgs', {
  'shajin1': '../public/textures/shajin1.png',
  'shajin2': '../public/textures/shajin2.png',
  'wukong': '../public/textures/wukong.png',
})
const myTextrues = await Assets.loadBundle('imgs')

let sprite1 = new Sprite(myTextrues.shajin1)
  sprite1.width = 300
  sprite1.height = 300
  app.stage.addChild(sprite1)

  let sprite2 = new Sprite(myTextrues.shajin2)
  sprite2.width = 300
  sprite2.height = 300
  sprite2.position.set(300, 0)
  app.stage.addChild(sprite2)

  let sprite3 = new Sprite(myTextrues.wukong)
  sprite3.width = 300
  sprite3.height = 300
  sprite3.position.set(600, 0)
  app.stage.addChild(sprite3)

addBundle

Assets.addBundle('imgs', {
  'shajin1': '../public/textures/shajin1.png',
  'shajin2': '../public/textures/shajin2.png',
  'wukong': '../public/textures/wukong.png',
})
const myTextrues = await Assets.loadBundle('imgs',()=>{
  console.log("加载完成!")
})

let sprite1 = new Sprite(myTextrues.shajin1)
  sprite1.width = 300
  sprite1.height = 300
  app.stage.addChild(sprite1)

  let sprite2 = new Sprite(myTextrues.shajin2)
  sprite2.width = 300
  sprite2.height = 300
  sprite2.position.set(300, 0)
  app.stage.addChild(sprite2)

  let sprite3 = new Sprite(myTextrues.wukong)
  sprite3.width = 300
  sprite3.height = 300
  sprite3.position.set(600, 0)
  app.stage.addChild(sprite3)

(9) BlurFilter(滤镜)

Assets.addBundle('imgs', {
  'shajin1': '../public/textures/shajin1.png',
})
const myTextrues = await Assets.loadBundle('imgs', () => {
  console.log("加载完成!")
})

let sprite1 = new Sprite(myTextrues.shajin1)
sprite1.width = 300
sprite1.height = 300
// 设置锚点
sprite1.anchor.set(0.5, 0.5)

sprite1.x = app.screen.width / 2
sprite1.y = app.screen.height / 2

// 创建模糊滤镜
const blurFilter = new BlurFilter();
//模糊程度
blurFilter.blur = 20
sprite1.filters = [blurFilter]

// 监听事件
sprite1.interactive = true
sprite1.on('pointerover',()=>{
  blurFilter.blur = 0
})
sprite1.on('pointerout',()=>{
  blurFilter.blur = 20
})