Pixi.js 滤镜实现水面波纹效果
创建画布
ts
import * as PIXI from "pixi.js"
import { ShockwaveFilter } from "pixi-filters"
const app = new PIXI.Application({
width: window.innerWidth,
height: window.innerHeight,
backgroundColor: 0x1099bb,
resolution: window.devicePixelRatio || 1, // 像素比
antialias: true, // 抗锯齿
})
document.documentElement.appendChild(app.view as any)添加背景纹理
ts
// 创建一个纹理
const texture = PIXI.Texture.from(
"https://img0.baidu.com/it/u=3731332350,3913552989&fm=253&fmt=auto&app=120&f=JPEG?w=1200&h=712"
)
// 创建一个精灵
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)添加文字
ts
// 添加文字
const text = new PIXI.Text("Hello Pixi", {
fontFamily: "Arial",
fontSize: 136,
fill: 0xffffff,
align: "center",
dropShadow: true, // 阴影
dropShadowColor: "#000",
dropShadowBlur: 5,
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)添加置换滤镜纹理贴图
ts
// 添加置换滤镜纹理贴图
let displacementSprite = PIXI.Sprite.from(
"https://img1.baidu.com/it/u=2212687164,1673962414&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500"
)
// 设置置换滤镜
displacementSprite.texture.baseTexture.wrapMode = PIXI.WRAP_MODES.REPEAT
// 设置置换精灵的缩放,值越大水波纹越不明显,值越小越明显
displacementSprite.scale.set(5)
// 将纹理放置在置换滤镜上
const displacementFilter = new PIXI.DisplacementFilter(displacementSprite)
// 将置换精灵添加到容器上
container.addChild(displacementSprite)
// 将滤镜添加到容器上,文本与背景都放置在容器上,对容器设置可以全部生效
container.filters = [displacementFilter]
// 添加动画帧,实现水面波浪的效果
app.ticker.add(() => {
displacementSprite.x += 1
displacementSprite.y += 1
})水面波纹效果
ts
// 添加振波滤镜(鼠标点击时产生圆形波纹效果)
const shockwaveFilter = new ShockwaveFilter(
[
// 随机位置
Math.random() * app.screen.width,
Math.random() * app.screen.height,
],
{
radius: 100, // 半径
wavelength: 30, // 波长
amplitude: 30, // 振幅
speed: 250, // 扩散的速度
},
0.1 // 时间,从 0 开始
)
// 添加滤镜到容器上
container.filters.push(shockwaveFilter)
const createWave = (waveFilter: ShockwaveFilter, resetTime: number) => {
waveFilter.time += 0.01 // 每帧让波纹的时间增加
if (waveFilter.time > resetTime) {
// 超过重置秒数时间时重置
waveFilter.time = 0
waveFilter.center = [
// 新的随机位置
Math.random() * app.screen.width,
Math.random() * app.screen.height,
]
}
}点击事件生成波纹
ts
app.ticker.add(() => {
createWave(shockwaveFilter, 2.5)
})
// 监听点击事件,对应位置产生波纹效果
;(app.view as HTMLCanvasElement).addEventListener("click", e => {
// 在当前方法可以创建新的波纹,这里节省代码就直接修改当前的波纹位置
// 设置为当前点击的位置
shockwaveFilter.center = [e.clientX, e.clientY]
// 让波纹的时间从 0 开始
shockwaveFilter.time = 0
})