跳至主要內容

02.canvas之PixiJS的学习之路

pinia原创大约 9 分钟CANVAScanvas

官网

PixiJSopen in new window

初识PixiJS

1.容器Containers | PixiJSopen in new window

/**
 * 创建一个应用程序
 * @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 | PixiJSopen in new window

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 | PixiJSopen in new window

描述
位置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 | PixiJSopen in new window

//创建一个纹理
const texture: PIXI.Texture = PIXI.Texture.from(textureImage) //创建一个纹理

4..精灵Sprites | PixiJSopen in new window

注意

创建精灵时需要纹理

//创建一个精灵
const sprite: PIXI.Sprite = new PIXI.Sprite(texture)

5.交互Interaction | PixiJSopen in new window

//交互
sprite.interactive = true //设置精灵是否可以交互
//为精灵添加点击事件
sprite.on('pointerenter', () => {
 sprite.alpha = 1
})
sprite.on('pointerout', () => {
 sprite.alpha = 0.5
})

6.文字Text | PixiJSopen in new window

//文字
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 Documentationopen in new window

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]
上次编辑于:
贡献者: 林深不见鹿