02.canvas之PixiJS的学习之路
原创大约 9 分钟
官网
初识PixiJS
1.容器Containers | PixiJS
/**
* 创建一个应用程序
* @param {number} width - 画布的宽度,以像素为单位
* @param {number} height - 画布的高度,以像素为单位
* @param {object} [options] - 可选的应用程序选项
* @param {boolean} [options.view] - 用于呈现的HTMLCanvasElement。如果没有指定,将创建一个新的canvas元素
* @param {boolean} [options.transparent=false] - 画布是否透明,默认为false
* @param {boolean} [options.antialias=false] - 是否开启抗锯齿,默认为false
* @param {boolean} [options.preserveDrawingBuffer=false] - 是否保留绘图缓冲区,默认为false
* @param {number} [options.resolution=1] - 画布的分辨率/设备像素比
* @param {boolean} [options.forceCanvas=false] - 强制画布渲染为画布,而不是使用WebGL。如果浏览器不支持WebGL,此选项将自动启用
* @param {boolean} [options.backgroundColor=0x000000] - 画布的背景色,如果transparent为true,则将忽略此项
* @param {string} [options.powerPreference] - 用于选择电源模式的提示
* @param {boolean} [options.sharedTicker=false] - 如果为true,则将使用PIXI.Ticker.shared,否则将创建新的ticker。如果您的应用程序将在多个画布/渲染器上运行,则应将其设置为true
* @param {boolean} [options.sharedLoader=false] - 如果为true,则将使用PIXI.Loader.shared,否则将创建新的加载程序。如果您的应用程序将在多个画布/渲染器上运行,则应将其设置为true
* @param {number} [options.resizeTo] - 调整大小的元素。如果设置,应用程序将自动调整大小以匹配该元素的大小。这只适用于画布
* @param {boolean} [options.autoDensity=false] - 如果为true,则画布的大小将根据设备像素比例自动缩放。这只适用于画布
* @param {boolean} [options.legacy=false] - 如果为true,则将使用PIXI.WebGLRenderer,否则将使用PIXI.Renderer。如果您的应用程序将在多个画布/渲染器上运行,则应将其设置为true
* @param {boolean} [options.clearBeforeRender=true] - 是否在渲染之前清除画布。如果您的应用程序将在多个画布/渲染器上运行,则应将其设置为false
* @param {number} [options.resizeTo] - 调整大小的元素。如果设置,应用程序将自动调整大小以匹配该元素的大小。这只适用于画布
* @param {boolean} [options.forceFXAA=false] - 如果为true,则将使用FXAA抗锯齿。如果浏览器不支持WebGL,则此选项将自动启用
* @param {boolean} [options.context] - WebGL上下文选项。请参阅https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/getContext
* @param {boolean} [options.autoStart=true] - 如果为true,则将自动启动渲染器。如果您的应用程序将在多个画布/渲染器上运行,则应将其设置为false
*
*/
const app: PIXI.Application = new PIXI.Application({
width: divRef.value?.clientWidth,
height: divRef.value?.clientHeight,
backgroundColor: 0x1099bb,
resolution: window.devicePixelRatio || 1
})
//将应用程序的视图添加到DOM中
divRef.value?.appendChild(app.view as HTMLCanvasElement)
2.图形Graphics | PixiJS
Graphics 类主要用于呈现基本形状,如线条、圆形和 矩形到显示器,并对其进行着色和填充。但是,您也可以使用图形 对象来构建要用作掩码或复杂命中区域的基元列表。
2.1矩形
//创建一个矩形
const rectangle: PIXI.Graphics = new PIXI.Graphics()///创建一个矩形
rectangle.beginFill(0x66ccff) //填充颜色
rectangle.drawRect(0, 0, 64, 64) //绘制矩形
rectangle.endFill() //结束绘制
app.stage.addChild(rectangle)//将矩形添加到舞台
2.2圆形
//创建一个圆形
const circle: PIXI.Graphics = new PIXI.Graphics() //创建一个圆形
circle.beginFill(0x9966ff) //填充颜色
circle.drawCircle(400, 400, 32) //绘制圆形
circle.endFill() //结束绘制
app.stage.addChild(circle) //将圆形添加到舞台
2.3圆角矩形
//绘制一个圆角矩形
const roundBox: PIXI.Graphics = new PIXI.Graphics()//创建一个圆角矩形
roundBox.lineStyle(4, 0x99ccff, 1) //线条样式
roundBox.beginFill(0xff9933)//填充颜色
roundBox.drawRoundedRect(0, 0, 84, 36, 10)//绘制圆角矩形(x,y,width,height,radius)
roundBox.endFill()//结束绘制
roundBox.position.set(48, 190)//设置位置
app.stage.addChild(roundBox)//将圆角矩形添加到舞台
2.4椭圆
//绘制一个椭圆
const ellipse: PIXI.Graphics = new PIXI.Graphics()//创建一个椭圆
ellipse.lineStyle(4, 0xff00ff, 1)//线条样式
ellipse.beginFill(0x650a5a)//填充颜色
ellipse.drawEllipse(0, 0, 50, 20)//绘制椭圆(x,y,width,height)width和height是椭圆的宽度和高度
ellipse.endFill()//结束绘制
ellipse.position.set(48, 250)//设置位置
app.stage.addChild(ellipse)//将椭圆添加到舞台
2.5多边形
//绘制一个多边形
const polygon: PIXI.Graphics = new PIXI.Graphics()//创建一个多边形
polygon.lineStyle(4, 0x00ff99, 1)//线条样式
polygon.beginFill(0x00ff00)//填充颜色
const path: number[] = [//绘制路径(点的集合)
0, 0,
50, 50,
100, 50,
100, 100,
50, 100
]
polygon.drawPolygon(path)//绘制多边形
polygon.endFill()//结束绘制
polygon.position.set(48, 320)//设置位置
app.stage.addChild(polygon)//将多边形添加到舞台
2.6圆弧
//绘制一个圆弧
const arc: PIXI.Graphics = new PIXI.Graphics()//创建一个圆弧
arc.lineStyle(4, 0xff00ff, 1)//线条样式
arc.beginFill(0x650a5a)//填充颜色
arc.arc(0, 0, 50, 0, Math.PI / 2)//绘制圆弧(x,y,radius,startAngle,endAngle)
arc.endFill()//结束绘制
arc.position.set(48, 400)//设置位置
app.stage.addChild(arc)//将圆弧添加到舞台
2.7线段
//绘制一个线段
const line: PIXI.Graphics = new PIXI.Graphics()//创建一个线段
line.lineStyle(4, 0xff00ff, 1)//线条样式
line.moveTo(0, 0)//移动到起始点
line.lineTo(80, 50)//绘制线段(x,y)
line.position.set(48, 480)//设置位置
app.stage.addChild(line)//将线段添加到舞台
注意
样式设置必须在图像的绘制之前
4.图形的常见属性Display Objects | PixiJS
| 描述 | |
|---|---|
| 位置 | X 和 Y 位置以像素为单位给出,并更改对象相对于其父对象的位置,也可直接用作object.x / object.y |
| 旋转 | 旋转以弧度为单位指定,并顺时针旋转对象 (0.0 - 2 * Math.PI) |
| 角度 | 角度是旋转的别名,以度而不是弧度 (0.0 - 360.0) 为单位指定 |
| 支点 | 点对象旋转,以像素为单位 - 还设置子对象的原点 |
| 阿尔法 | 不透明度从 0.0(完全透明)到 1.0(完全不透明),由子项继承 |
| 规模 | 比例指定为百分比,1.0 表示 100% 或实际大小,并且可以为 x 和 y 轴独立设置 |
| 扭曲 | Sskew在x和y中转换对象,类似于CSS skew()函数,并以弧度指定 |
| 可见 | 无论对象是否可见,作为布尔值 - 阻止更新和呈现对象和子项 |
| 可渲染 | 是否应渲染对象 - 何时 ,对象仍将更新,但不会渲染,不会影响子对象false |
3.纹理Textures | PixiJS
//创建一个纹理
const texture: PIXI.Texture = PIXI.Texture.from(textureImage) //创建一个纹理
4..精灵Sprites | PixiJS
注意
创建精灵时需要纹理
//创建一个精灵
const sprite: PIXI.Sprite = new PIXI.Sprite(texture)
5.交互Interaction | PixiJS
//交互
sprite.interactive = true //设置精灵是否可以交互
//为精灵添加点击事件
sprite.on('pointerenter', () => {
sprite.alpha = 1
})
sprite.on('pointerout', () => {
sprite.alpha = 0.5
})
6.文字Text | PixiJS
//文字
const basicText: PIXI.Text = new PIXI.Text('Basic text in pixi', {
fill: 0xffffff,
fontFamily: 'Arial',
fontSize: 36,
align: 'center'
})
basicText.x = app.screen.width / 2//设置位置
basicText.y = app.screen.height / 2//设置位置
basicText.anchor.set(0.5)//设置锚点
app.stage.addChild(basicText)//添加到舞台
在文字上添加一个遮罩
//加载一个精灵
const bunny: PIXI.Sprite = PIXI.Sprite.from(textureImage)
bunny.width = app.screen.width
bunny.height = app.screen.height
//遮罩
bunny.mask = basicText//遮罩 可以是一个图形或者是一个精灵
app.stage.addChild(bunny)
7.ticker实现动画
/*ticker实现动画
* @param {number} delta - 从上一帧到现在的时间,以毫秒为单位
* @emits PIXI.Ticker#prerender - 在渲染之前触发
* @emits PIXI.Ticker#postrender - 在渲染之后触发
* @emits PIXI.Ticker#preupdate - 在更新之前触发
* @emits PIXI.Ticker#postupdate - 在更新之后触发
* @emits PIXI.Ticker#tick - 每帧触发
* @emits PIXI.Ticker#complete - 当ticker完成时触发
* @emits PIXI.Ticker#add - 当ticker添加到全局ticker时触发
* @emits PIXI.Ticker#remove - 当ticker从全局ticker中删除时触发
* @emits PIXI.Ticker#start - 当ticker启动时触发
* @emits PIXI.Ticker#stop - 当ticker停止时触发
* @emits PIXI.Ticker#update - 每次更新时触发
* @emits PIXI.Ticker#deltaTime - 每次更新时触发
* @emits PIXI.Ticker#FPS - 每次更新时触发
* @emits PIXI.Ticker#minFPS - 每次更新时触发
* @emits PIXI.Ticker#maxFPS - 每次更新时触发
* @emits PIXI.Ticker#lag - 每次更新时触发
* @emits PIXI.Ticker#started - 每次更新时触发
* @emits PIXI.Ticker#stopped - 每次更新时触发
* @emits PIXI.Ticker#destroyed - 每次更新时触发
* @emits PIXI.Ticker#tickStart - 每次更新时触发
* @emits PIXI.Ticker#tickEnd - 每次更新时触发
* @emits PIXI.Ticker#tickComplete - 每次更新时触发
* @emits PIXI.Ticker#tick - 每次更新时触发
* @emits PIXI.Ticker#add - 每次更新时触发
* @emits PIXI.Ticker#remove - 每次更新时触发
*/
app.ticker.add((delta) => {
sprite.rotation += 0.01 * delta
})
8.多个资源加载
8.1按场景添加资源
//添加场景一的资源
PIXI.Assets.addBundle('sceneOne', {
textureImage: textureImage,
...
})
//异步加载场景一的资源 返回一个promise 用于监听加载进度
const sceneOnePromise: Promise<Record<string, any>> = PIXI.Assets.loadBundle('sceneOne',(progress: number) => {
console.log('加载完成', progress)
})
//加载完成后执行
sceneOnePromise.then((textures: Record<string, any>) => {
//创建一个容器
let container: PIXI.Container = new PIXI.Container()
//创建精灵
const sprite:PIXI.Sprite = new PIXI.Sprite(textures.textureImage)
//设置精灵的位置
sprite.x = app.renderer.width / 2
sprite.y = app.renderer.height / 2
//设置精灵的锚点
sprite.anchor.set(0.5)
//设置精灵的大小
sprite.width = 100
sprite.height = 100
//将精灵添加到容器
container.addChild(sprite)
//将容器添加到舞台
app.stage.addChild(container)
})
8.2直接添加资源
//添加资源
PIXI.Assets.add('textureImage', textureImage) //添加资源(图片名称,图片路径)
......
//异步加载场景一的资源 返回一个promise 用于监听加载进度
const textureImagesPromise: Promise<Record<string, any>> = PIXI.Assets.load(['textureImage'],(progress: number) => {
console.log('加载完成', progress)
})
//加载完成后执行
textureImagesPromise.then((textures: Record<string, any>) => {
//创建一个容器
let container: PIXI.Container = new PIXI.Container()
//创建精灵
const sprite:PIXI.Sprite = new PIXI.Sprite(textures.textureImage)
//设置精灵的位置
sprite.x = app.renderer.width / 2
sprite.y = app.renderer.height / 2
//设置精灵的锚点
sprite.anchor.set(0.5)
//设置精灵的大小
sprite.width = 100
sprite.height = 100
//将精灵添加到容器
container.addChild(sprite)
//将容器添加到舞台
app.stage.addChild(container)
})
9.过滤器PixiJS API Documentation
- 滤镜种类PixiJS API Documentation
- PixiJS 的滤镜库pixijs/filters: Collection of community-authored custom display filters for PixiJS (github.com)](https://github.com/pixijs/filters)
9.1模糊滤镜
//创建一个模糊滤镜
const blurFilter:PIXI.BlurFilter = new PIXI.BlurFilter()
//设置滤镜的模糊程度
blurFilter.blur = 20
//将滤镜应用到精灵
head.filters = [blurFilter]
// 监听鼠标移动事件
app.stage.interactive = true
app.stage.on('pointerover', () => {
blurFilter.blur = 0
})
app.stage.on('pointerout', () => {
blurFilter.blur = 20
})
9.2轮廓滤镜
//创建一个轮廓滤镜
const outlineFilterBlue:OutlineFilter = new OutlineFilter(10, 0xffff00)//第一个参数是描边的宽度,第二个参数是描边的颜色
head.filters = [outlineFilterBlue]//将滤镜添加到精灵上
9.3发光滤镜
//创建一个发光滤镜
const glowFilter:GlowFilter = new GlowFilter({
distance: 50,//发光距离
outerStrength: 1,//外部强度
color: 0x00ff00,//发光颜色
quality: 0.2//质量
})
head.filters = [glowFilter]