载入
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
- 要使用Pixi,我们要先创建一个Pixi Application的实例。
- 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文件
- 用 Assets 来载入图片,它会回传一个 promise
- 当 promise 执行成功,就会回传这个图片的 texture
- 再把这个 texture 转成 sprite
- 放到舞台上
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
})