PixiJS
大约 8 分钟
PixiJS
介绍
PixiJS 是一个非常快的2D sprite渲染引擎 项目地址
项目依赖
yarn add pixi-filters pixi.js
示例
绘制图形
<template>
<div id="tag"></div>
</template>
<script>
import * as PIXI from 'pixi.js'
// /绘制图形
export default {
name: 'Home',
mounted() {
let _this = this
this.$nextTick(() => {
_this.initPixi()
})
},
methods: {
initPixi() {
const options = {
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0x1099bb,
resolution: window.devicePixelRatio || 1,
antialias: true
}
// 创建应用
const app = new PIXI.Application(options)
// 将应用画布添加到DOM中
document.querySelector('#tag').appendChild(app.view)
// 绘制矩形=============================
const rectangle = new PIXI.Graphics()
// 设置边框样式
rectangle.lineStyle(4, 0xff0000, 1) // 线宽,颜色,透明度
rectangle.beginFill(0xffffff, 1) // 填充颜色,透明度
rectangle.drawRect(0, 0, 50, 50) // 绘制矩形
rectangle.endFill() // 结束填充
// 图形缩放
rectangle.scale.set(2, 2)
// 图形位移
rectangle.position.set(100, 100)
// 图形旋转
rectangle.rotation = 0.8
// 图形锚点
rectangle.pivot.set(10, 12)
// 将矩形添加到画布
app.stage.addChild(rectangle)
// 绘制圆形=============================
const circle = new PIXI.Graphics()
circle.beginFill(0x66ccff, 0.9)
circle.drawCircle(0, 0, 32)
circle.endFill() // 结束填充
circle.position.set(300, 300)
app.stage.addChild(circle)
// 绘制圆角矩形=============================
const roundedRectangle = new PIXI.Graphics()
roundedRectangle.beginFill(0x66ccff, 0.9)
// drawRoundedRect(x: number, y: number, width: number, height: number, radius: number)
roundedRectangle.drawRoundedRect(0, 0, 164, 164, 10)
roundedRectangle.endFill() // 结束填充
roundedRectangle.position.set(600, 600)
app.stage.addChild(roundedRectangle)
// 绘制椭圆=============================
const ellipse = new PIXI.Graphics()
ellipse.beginFill(0x66ccff, 0.9)
// drawEllipse(x: number, y: number, width: number, height: number)
ellipse.drawEllipse(0, 0, 120, 164)
ellipse.endFill() // 结束填充
ellipse.position.set(500, 500)
app.stage.addChild(ellipse)
// 绘制多边形=============================
const polygon = new PIXI.Graphics()
polygon.beginFill(0x660000, 0.9)
// 绘制多边形,参数为数组
polygon.drawPolygon([0, 0, 100, 0, 100, 100, 0, 100])
polygon.endFill() // 结束填充
polygon.position.set(50, 300)
app.stage.addChild(polygon)
// 绘制圆弧=============================
const arc = new PIXI.Graphics()
arc.beginFill(0x70eb77, 1)
// PIXI.Graphics.arc(cx: number, cy: number, radius: number, startAngle: number, endAngle: number)
arc.arc(0, 0, 32, Math.PI / 2, false)
arc.endFill() // 结束填充
arc.position.set(800, 80)
app.stage.addChild(arc)
// 绘制线段=============================
const line = new PIXI.Graphics()
line.lineStyle(4, 0xed6341, 1)
line.moveTo(0, 0) // 线段开始位置
line.lineTo(100, 100) // 线段结束位置
line.lineTo(200, 1)
line.position.set(800, 120)
app.stage.addChild(line)
}
}
}
</script>
<style>
#tag {
width: 100%;
height: 100%;
}
</style>
纹理和动画
<template>
<div id="vein"></div>
</template>
<script>
import * as PIXI from 'pixi.js'
export default {
name: 'vein',
mounted() {
let _this = this
this.$nextTick(() => {
_this.initPixi()
})
},
methods: {
initPixi() {
const options = {
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0x1099bb,
resolution: window.devicePixelRatio || 1,
antialias: true
}
// 创建应用
const app = new PIXI.Application(options)
// 将应用画布添加到DOM中
document.querySelector('#vein').appendChild(app.view)
// 创建纹理
const texture = PIXI.Texture.from('/textures/arrow.png')
// 创建精灵
const sprite = new PIXI.Sprite(texture)
// 设置精灵锚点
sprite.anchor.set(0.5, 0.5)
// 设置位置
sprite.x = app.screen.width / 2
sprite.y = app.screen.height / 2
// 设置精灵旋转-45°
sprite.rotation = Math.PI / -4
// 设置精灵缩放
sprite.scale.set(2, 2)
// 设置精灵透明度
sprite.alpha = 0.8
// 添加到画布
app.stage.addChild(sprite)
// ticker 实现动画
app.ticker.add((delta) => {
sprite.rotation += 0.01 * delta
})
}
}
}
</script>
事件和交互
<template>
<div id="event"></div>
</template>
<script>
import * as PIXI from 'pixi.js'
export default {
name: 'event',
mounted() {
let _this = this
this.$nextTick(() => {
_this.initPixi()
})
},
methods: {
initPixi() {
const options = {
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0x1099bb,
resolution: window.devicePixelRatio || 1,
antialias: true
}
// 创建应用
const app = new PIXI.Application(options)
// 将应用画布添加到DOM中
document.querySelector('#event').appendChild(app.view)
// 创建纹理
const texture = PIXI.Texture.from('/textures/arrow.png')
// 创建精灵
const sprite = new PIXI.Sprite(texture)
// 设置精灵锚点
sprite.anchor.set(0.5, 0.5)
// 设置位置
sprite.x = app.screen.width / 2
sprite.y = app.screen.height / 2
// 设置精灵旋转-45°
sprite.rotation = Math.PI / -4
// 设置精灵缩放
sprite.scale.set(2, 2)
// 设置精灵透明度
sprite.alpha = 0.5
// 添加到画布
app.stage.addChild(sprite)
// ticker 实现动画
app.ticker.add((delta) => {
sprite.rotation += 0.01 * delta
})
// 为精灵添加交互事件
sprite.interactive = true // 使精灵对象可以点击
sprite.on('click', () => {
alert('点击了')
})
// 鼠标进入
sprite.on('pointerover', () => {
console.log('鼠标移入 :>> ')
sprite.alpha = 0.5
})
sprite.on('pointerout', () => {
console.log('鼠标移出 :>> ')
sprite.alpha = 1
})
// 绘制矩形
const rect = new PIXI.Graphics()
rect.beginFill(0xff0000)
rect.drawRect(0, 0, 100, 100)
rect.endFill()
rect.x = 100
rect.y = 100
app.stage.addChild(rect)
// 给矩形添加点击事件
rect.interactive = true
rect.on('click', () => {
console.log('点击矩形 :>> ')
})
}
}
}
</script>
<style>
#tag {
width: 100%;
height: 100%;
}
</style>
资源管理
<template>
<div id="resourceManagement"></div>
</template>
<script>
import * as PIXI from 'pixi.js'
export default {
name: 'as',
mounted() {
let _this = this
this.$nextTick(() => {
_this.initPixi()
})
},
methods: {
initPixi() {
const options = {
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0x1099bb,
resolution: window.devicePixelRatio || 1,
antialias: true
}
// 创建应用
const app = new PIXI.Application(options)
// 将应用画布添加到DOM中
document.querySelector('#resourceManagement').appendChild(app.view)
// 添加资源
// PIXI.Assets.add('arrow', require('../assets/textures/arrow.png'))
// PIXI.Assets.add('dog', require('../assets/textures/dog.png'))
// // 异步加载资源
// const texturesPromise = PIXI.Assets.load(['arrow', 'dog'], (progress) => {
// console.log('加载完成...', progress)
// })
// texturesPromise.then((textures) => {
// // 创建容器
// const container = new PIXI.Container()
// // 创建精灵位置
// const sprite = new PIXI.Sprite(textures.arrow)
// // 精灵位置
// sprite.x = app.screen.width / 2
// sprite.y = app.screen.height / 2
// // 设置精灵锚点
// sprite.anchor.set(0.5)
// // 设置透明度
// sprite.alpha = 0.5
// // 设置缩放
// sprite.scale.set(0.5)
// // 设置旋转
// sprite.rotaion = 0.5
// // 设置混合模式
// sprite.blendMode = PIXI.BLEND_MODES.ADD
// // 设置交互
// sprite.interactive = true
// // 设置鼠标样式
// sprite.buttonMode = true
// // 设置鼠标事件
// sprite.on('click', () => {
// alert('点击')
// })
// // 容器添加arrow
// container.addChild(sprite)
// const dog = new PIXI.Sprite(textures.dog)
// dog.scale.set(0.5)
// // 容器添加dog
// container.addChild(dog)
// // 添加到画布
// app.stage.addChild(container)
// })
/* ******************************************** */
// 添加场景1的资源文件
PIXI.Assets.addBundle('scene1', {
arrow: '/textures/arrow.png',
dog: '/textures/dog.png'
})
const assets = PIXI.Assets.loadBundle('scene1', (progress) => {
console.log('加载完成...', progress)
})
assets.then((textures) => {
// 创建容器
const container = new PIXI.Container()
// 创建精灵位置
const sprite = new PIXI.Sprite(textures.arrow)
// 精灵位置
sprite.x = app.screen.width / 2
sprite.y = app.screen.height / 2
// 设置精灵锚点
sprite.anchor.set(0.5)
// 设置透明度
sprite.alpha = 0.5
// 设置缩放
sprite.scale.set(1)
// 设置旋转
sprite.rotaion = 0.5
// 设置混合模式
sprite.blendMode = PIXI.BLEND_MODES.ADD
// 设置交互
sprite.interactive = true
// 设置鼠标样式
sprite.buttonMode = true
// 设置鼠标事件
sprite.on('click', () => {
alert('点击')
})
// 容器添加arrow
container.addChild(sprite)
const dog = new PIXI.Sprite(textures.dog)
dog.scale.set(0.5)
// 容器添加dog
container.addChild(dog)
// 添加到画布
app.stage.addChild(container)
})
}
}
}
</script>
<style>
#tag {
width: 100%;
height: 100%;
}
</style>
文字与遮罩
<template>
<div id="texts"></div>
</template>
<script>
import * as PIXI from 'pixi.js'
export default {
name: 'texts',
mounted() {
let _this = this
this.$nextTick(() => {
_this.initPixi()
})
},
methods: {
initPixi() {
const options = {
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0x1099bb,
resolution: window.devicePixelRatio || 1,
antialias: true
}
// 创建应用
const app = new PIXI.Application(options)
// 将应用画布添加到DOM中
document.querySelector('#texts').appendChild(app.view)
// 显示文字
const text = new PIXI.Text('文本信息', {
fontSize: 300,
fill: 0xff0000,
align: 'center'
})
// 设置文字位置
text.x = app.screen.width / 2
text.y = app.screen.height / 2
// 设置锚点
text.anchor.set(0.5)
// app.stage.addChild(text)
// 创建一个圆形
const circle = new PIXI.Graphics()
circle.beginFill(0x0000ff)
circle.drawCircle(app.screen.width / 2, app.screen.height / 2, 100)
circle.endFill()
circle.x = app.screen.width / 2
circle.y = app.screen.height / 2
const arrow = PIXI.Sprite.from('/textures/arrow.png')
// 创建精灵
const bunny = PIXI.Sprite.from('/textures/bg.png')
// 设置精灵铺满屏幕
bunny.width = app.screen.width
bunny.height = app.screen.height
// 使用文字作为精灵的遮罩
bunny.mask = text
// 使用圆形作为精灵的遮罩
// bunny.mask = arrow
app.stage.addChild(bunny)
}
}
}
</script>
<style>
#texts {
width: 100%;
height: 100%;
}
</style>
滤镜特效
<template>
<div id="filterEffect"></div>
</template>
<script>
import * as PIXI from 'pixi.js'
import { OutlineFilter, GlowFilter } from 'pixi-filters'
export default {
name: 'filterEffect',
mounted() {
let _this = this
this.$nextTick(() => {
_this.initPixi()
})
},
methods: {
initPixi() {
const options = {
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0x1099bb,
resolution: window.devicePixelRatio || 1,
antialias: true
}
// 创建应用
const app = new PIXI.Application(options)
// 将应用画布添加到DOM中
document.querySelector('#filterEffect').appendChild(app.view)
const arrow = PIXI.Texture.from('/textures/arrow.png')
const sprite = new PIXI.Sprite(arrow)
sprite.x = app.screen.width / 2
sprite.y = app.screen.height / 2
// 设置精灵锚点
sprite.anchor.set(0.5)
// 添加到画布
app.stage.addChild(sprite)
// 创建模糊滤镜
const blurFilter = new PIXI.BlurFilter()
// 设置模糊程度
blurFilter.blur = 0
// 模糊应用到精灵
// sprite.filters = [blurFilter]
// // 监听鼠标是否进入
// sprite.interactive = true
// sprite.on('pointerover', () => {
// blurFilter.blur = 10
// })
// sprite.on('pointerout', () => {
// blurFilter.blur = 0
// })
// 轮廓滤镜
const outlineFilter = new OutlineFilter(3, 0xffff00)
// 辉光滤镜
const glowFilter = new GlowFilter({
distance: 120,
outerStrength: 3,
innerStrength: 0,
color: 0xff0000,
quality: 0.5
})
sprite.filters = [outlineFilter, glowFilter]
}
}
}
</script>
<style>
#tag {
width: 100%;
height: 100%;
}
</style>
水滴特效主页
<template>
<div id="waterDrop"></div>
</template>
<script setup>
import { onMounted } from 'vue'
import * as PIXI from 'pixi.js'
import { ShockwaveFilter } from 'pixi-filters'
onMounted(() => {
initPixi()
})
// 初始化
const initPixi = () => {
const optoions = {
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0x1099bb,
resolution: window.devicePixelRatio || 1,
antialias: true
}
const app = new PIXI.Application(optoions)
document.querySelector('#waterDrop').appendChild(app.view)
// 创建纹理
const texture = PIXI.Texture.from('/textures/002.jpg')
// 创建精灵
const sprite = new PIXI.Sprite(texture)
sprite.width = app.screen.width
sprite.height = app.screen.height
// 创建容器
const container = new PIXI.Container()
// 将精灵添加到容器中
container.addChild(sprite)
// 将容器添加到画布
app.stage.addChild(container)
// 添加文字
const text = new PIXI.Text('Hello PixiJs', {
fontFamily: 'Arial',
fontSize: 30 + Math.floor(app.screen.width * 0.1),
fill: 0xffffff,
align: 'center',
dropShadow: true,
dropShadowColor: '#000000',
dropShadowBlur: 40, // 阴影模糊度
dropShadowAngle: Math.PI / 2, // 阴影照射角度
dropShadowDistance: 2 // 阴影厚度
})
text.x = app.screen.width / 2
text.y = app.screen.height / 2
text.anchor.set(0.5)
container.addChild(text)
// 添加置换滤镜
const displacementSprite = PIXI.Sprite.from('/textures/water.png')
displacementSprite.scale.set(3)
// 纹理重复模式
displacementSprite.texture.baseTexture.wrapMode = PIXI.WRAP_MODES.REPEAT
// 将纹理放到滤镜上
const displacementFilter = new PIXI.DisplacementFilter(displacementSprite)
// 精灵天机到容器
container.addChild(displacementSprite)
// 添加水波纹
const shockwaveFilter1 = new ShockwaveFilter(
[Math.random() * app.screen.width, Math.random() * app.screen.height],
{
radius: 100, // 半径
wavelength: 80, // 波长
amplitude: 108, // 振幅
speed: 150 // 速度
},
0
)
const shockwaveFilter2 = new ShockwaveFilter(
[Math.random() * app.screen.width, Math.random() * app.screen.height],
{
radius: 40, // 半径
wavelength: 30, // 波长
amplitude: 10, // 振幅
speed: 200 // 速度
},
0
)
const shockwaveFilter3 = new ShockwaveFilter(
[Math.random() * app.screen.width, Math.random() * app.screen.height],
{
radius: 160, // 半径
wavelength: 65, // 波长
amplitude: 105, // 振幅
speed: 300 // 速度
},
0
)
// 将滤镜添加到容器
container.filters = [
displacementFilter,
shockwaveFilter1,
shockwaveFilter2,
shockwaveFilter3
]
// 添加动画
app.ticker.add((delta) => {
displacementSprite.x += 0.5
displacementSprite.y += 0.5
createRandomWave(shockwaveFilter1, 1.2)
createRandomWave(shockwaveFilter2, 1)
createRandomWave(shockwaveFilter3, 0.7)
})
function createRandomWave(waveFilter, restTime) {
waveFilter.time += 0.01
if (waveFilter.titme > restTime) {
waveFilter.time = 0
waveFilter.center = [
Math.random() * app.screen.width,
Math.random() * app.screen.height
]
}
}
// 监听点击事件,根据位置及创建波纹
app.view.addEventListener('click', (e) => {
shockwaveFilter1.center = [e.clientX, e.clientY]
shockwaveFilter1.time = 0
})
}
</script>