前言
我写这个文章的目的,主要是因为网上大多数pixijs的基础教程都有各种问题,不适合入门或者直接开始用;结合我查阅资料和官网文档来写这篇文章,保证写的列子都是直接可用的;如有错误,希望指出,谢谢!
pixijs简介
官方介绍: 它是一款基于canvas的2D WebGL渲染引擎,可以创建丰富的交互式图形、动画和游戏。pixi的目标是提供一个快速的、轻量级且是兼容所有设备的2D库,无需了解WebGL就可以让开发者享受到硬件加速,它默认使用WebGL渲染,但在浏览器不支持的情况下可优雅降级成Canvas渲染。同时对绘制内容支持完整的鼠标和触摸事件。
我总结特征:
- 支持WebGL渲染,因为能调用GPU渲染,所以渲染性能高
- 支持canvas渲染,当设备不支持WebGL时自动使用canvas渲染,也可以手动选择canvas渲染
- 十分简单易用的绘图Api,提供了很多封装好的方法
- 丰富的交互事件,支持完整的鼠标和移动端touch事件
…
接下来我们来写写代码…
先放个图片镇楼,后面都会用到这个图片
pixijs绘制开始
pixijs有几个重要的Class:
- view(UI,所见view)
- Container (舞台,场景)
- Renderer (渲染器)
- Ticker (计时器)
- Loader (资源加载器)
- Sprite (精灵)
view 和 render
view 其实就是可以实例到多个dom元素
所以 Renderer 呢?
PixiJS 的 Renderer 有二种,
一种是 PIXI.WebGLRenderer,使用 WebGL 绘制
一种是 PIXI.CanvasRenderer,使用 canvas 绘制
看这个例子:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>pixijs</title>
<script src="https://cdn.bootcdn.net/ajax/libs/pixi.js/5.3.8/pixi.min.js"></script>
</head>
<style>
body {
height: 100vh;
width: 100vw;
}
</style>
<body>
<div id="canvas1"></div>
<div id="canvas2"></div>
<script>
const app = new PIXI.Application({
width: 400,
height: 400,
antialias: true,
transparent: false,
backgroundColor: 0xFF33CCFF, //十六进制
});
document.getElementById('canvas1').appendChild(app.view); // app.view 是一个 HTMLCanvasElement
// app.renderer.backgroundColor = 0x00CC99;
const app1 = new PIXI.Application({
width: 400,
height: 400,
antialias: true,
transparent: false,
backgroundColor: 0xff0000,
});
document.getElementById('canvas2').appendChild(app1.view);
</script>
</body>
</html>
复制代码
运用pixijs绘图的方式非常简单,主要使用 new PIXI.Application()
來实例化 Pixi,而实例化的方式主要有二种:
// 直接创建
const app = new PIXI.Application();
document.body.appendChild(app.view);
复制代码
// 选定元素(看上面的例子)
const app = new PIXI.Application({
view: document.getElementById('canvas1'),
});
复制代码
Container (舞台,场景)
api地址: api
先用一张图来说明它是什么?
app.stage是一个Container的实例,作为最底层的舞台(stage),所有要渲染的图形都应放在它的内部才能被显示出来(可以理解为背景)
PIXI.Container 有一些特性:
- 可加入其他元件與元件索引操作,如新增设置深度和排序( container.sortableChildren = true;)
- 默认不可互动,可设置互动,可使用各种监听器(鼠标事件等等)(container.interactive = true;)
- 可設定 x、y、alpha、setTransform 等
看个例子(绘制一张图片,图片在最上面):
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>pixijs</title>
<script src="https://cdn.bootcdn.net/ajax/libs/pixi.js/5.3.8/pixi.min.js"></script>
</head>
<style>
body {
height: 100vh;
width: 100vw;
}
</style>
<body>
<canvas id="main"></canvas>
<script>
const app = new PIXI.Application({
view: document.getElementById('main'),
width: 1000,
height: 1000,
antialias: true,
transparent: false,
backgroundColor: 0xFF33CCFF,
});
const container = new PIXI.Container();
// container也有自身的x,y位置
app.stage.addChild(container); // 一般会自定义一个 container
// 加载纹理
const img = PIXI.Texture.from('./he.jpg'); // 你的图片地址
// 再将纹理添加到精灵当中,只有精灵才能设置各种自身的属性
const bunny = new PIXI.Sprite(img);
bunny.x = app.screen.width / 2;
bunny.y = app.screen.height / 2;
bunny.zIndex = 1;
bunny.anchor.set(0.5);
// // 这种可以多个图片,等图从网络或者本地加载完了再渲染
// const loader = new PIXI.Loader();
// loader
// .add('img1', './he.jpg')
// .load((loader, resource) => {
// console.log('Done');
// for (let prop in resource) {
// const sprite = new PIXI.Sprite(resource[prop].texture);
// sprite.x = 10;
// sprite.y = 10;
// sprite.width = 200;
// sprite.height = 200;
// sprite.zIndex = 1;
// // sprite.anchor.set(0.5)
// container.addChild(sprite)
// }
// })
// 最后别忘了加入到容器里面
container.addChild(bunny);
</script>
</body>
</html>
复制代码
?♂️ Sprite
api地址: api
刚才在上面介绍container 已经用到了它,用一张图说明关系:
注: ?♀️:PIXI.Sprite()和 文字:PIXI.TextStyle() 是2个很重要的API
PIXI.Graphics()是专门用来绘制图形的,这篇不多做介绍,后续会专门讲;
Ticker
api地址: api
通常在制作动画的时候,我们会使用setInterval、setTimeout、requestAnimationFrame等方式,而Ticker就类似他们;
比较重要的几个API:
- add
- addOnce
- destroy
- start
- stop
- update
看一个例子(图片在最上面:)
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>pixijs</title>
<script src="https://cdn.bootcdn.net/ajax/libs/pixi.js/5.3.8/pixi.min.js"></script>
</head>
<style>
body {
height: 100vh;
width: 100vw;
}
</style>
<body>
<canvas id="main"></canvas>
</div>
<script>
const app = new PIXI.Application({
view: document.getElementById('main'),
width: 1000,
height: 1000,
antialias: true,
transparent: false,
backgroundColor: 0xFF33CCFF,
});
const container = new PIXI.Container();
app.stage.addChild(container);
// 等着图片加载好
const loader = new PIXI.Loader();
loader
.add('fakeimg', './21.jpg') // 你的图片地址
.load((loader, resource) => {
console.log('Done');
init(resource);
})
function init(item) {
const sprite = new PIXI.Sprite(item.fakeimg.texture);
container.addChild(sprite);
}
app.ticker.add((delta) => {
container.x += 2;
container.y += 2;
})
</script>
</body>
</html>
复制代码
但是你发现,图片运动后不在了,那么我们做个更好的检测碰撞,
让他做一个来回运动
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>pixijs</title>
<script src="https://cdn.bootcdn.net/ajax/libs/pixi.js/5.3.8/pixi.min.js"></script>
</head>
<style>
body {
height: 100vh;
width: 100vw;
}
</style>
<body>
<canvas id="main"></canvas>
</div>
<script>
const app = new PIXI.Application({
view: document.getElementById('main'),
width: 1000,
height: 1000,
antialias: true,
transparent: false,
backgroundColor: 0xFF33CCFF,
});
const container = new PIXI.Container();
app.stage.addChild(container);
const loader = new PIXI.Loader();
loader
.add('fakeimg', './21.jpg')
.load((loader, resource) => {
console.log('Done');
init(resource);
})
function init(item) {
const sprite = new PIXI.Sprite(item.fakeimg.texture);
container.addChild(sprite);
}
let status = 1;
app.ticker.add((delta) => {
// container.x += 2;
// container.y += 2;
tickerLoop()
})
function tickerLoop() {
if (status) {
container.x += 5;
container.y += 5;
if (container.x > 800) {
status = 0;
}
} else {
container.x -= 5;
container.y -= 5;
if (container.x < 0) {
status = 1;
}
}
}
</script>
</body>
</html>
复制代码
pixijs事件交互
- 兼容鼠标和触摸屏的共同触发
type InteractionPointerEvents = “pointerdown” | “pointercancel” | “pointerup” | “pointertap” | “pointerupoutside” | “pointermove” | “pointerover” | “pointerout”;
- 触摸屏触发事件
type InteractionTouchEvents = “touchstart” | “touchcancel” | “touchend” | “touchendoutside” | “touchmove” | “tap”;
- 鼠标触发事件
type InteractionMouseEvents = “rightdown” | “mousedown” | “rightup” | “mouseup” | “rightclick” | “click” | “rightupoutside” | “mouseupoutside” | “mousemove” | “mouseover” | “mouseout”;
看个列子:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>pixijs</title>
<script src="https://cdn.bootcdn.net/ajax/libs/pixi.js/5.3.8/pixi.min.js"></script>
</head>
<style>
body {
height: 100vh;
width: 100vw;
}
</style>
<body>
<canvas id="main"></canvas>
<script>
const app = new PIXI.Application({
view: document.getElementById('main'),
width: 1000,
height: 1000,
antialias: true,
transparent: false,
backgroundColor: 0xFF33CCFF,
});
const container = new PIXI.Container();
app.stage.addChild(container);
// 加载纹理
const img = PIXI.Texture.from('./21.jpg'); // 图片在最上面
// 再将纹理添加到精灵当中,只有精灵才能设置各种属性
const imgSprite = new PIXI.Sprite(img);
imgSprite.x = app.screen.width / 2;
imgSprite.y = app.screen.height / 2;
imgSprite.anchor.set(0.5);
// 最后别忘了加入到容器里面
container.addChild(imgSprite);
// 这句话不能忘了
imgSprite.interactive = true;
// 监听事件
imgSprite
.on('pointerdown', onDragStart)
.on('pointermove', onDragMove)
.on('pointerup', onDragEnd)
.on('pointerupoutside', onDragEnd)
function onDragStart(event) {
this.data = event.data;
this.alpha = 0.5;
this.dragging = true;
}
function onDragEnd() {
this.alpha = 1;
this.dragging = false;
this.data = null;
}
function onDragMove() {
if (this.dragging) {
const newPosition = this.data.getLocalPosition(this.parent);
this.x = newPosition.x;
this.y = newPosition.y;
}
}
</script>
</body>
</html>
复制代码
pixijs 操作事件跟普通的区别也不大,可以多看下官方demo
最后
以上例子都是自己手写,希望对学习和使用有一定帮助,后续会写一些比较深入的东西,谢谢!
中秋节快乐!??
链接:
[pixjs官方](pixijs.com/)
[pixjs demo](pixijs.io/examples/)