Skip to content
本页目录

波纹涟漪效果

代码

vue
<template>
  <div></div>
</template>

<script setup lang="ts">
// 导入pixi
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 // 像素比
})

// 将应用画布添加到DOM中
document.body.appendChild(app.view as any)

// 创建一个纹理
const texture = PIXI.Texture.from(
  'https://pic.rmb.bdstatic.com/05b0ea405c9e690ab51627853a13de56.jpeg'
)
// 创建一个精灵
const sprite = PIXI.Sprite.from(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: '#000',
  dropShadowBlur: 4,
  dropShadowAngle: Math.PI / 2,
  dropShadowDistance: 5
})
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/displacement.jpg')
displacementSprite.scale.set(0.5)
displacementSprite.texture.baseTexture.wrapMode = PIXI.WRAP_MODES.REPEAT
const displacementFilter = new PIXI.DisplacementFilter(displacementSprite)
container.addChild(displacementSprite)

// 添加水波纹滤镜
const shockwaveFilter = new ShockwaveFilter(
  [Math.random() * app.screen.width, Math.random() * app.screen.height],
  {
    radius: 100, //半径
    wavelength: 85, //波长
    amplitude: 55, //振幅
    speed: 300 //扩散速度
  }
)
const shockwaveFilter1 = new ShockwaveFilter(
  [Math.random() * app.screen.width, Math.random() * app.screen.height],
  {
    radius: 160, //半径
    wavelength: 90, //波长
    amplitude: 60, //振幅
    speed: 250 //扩散速度
  }
)
const shockwaveFilter2 = new ShockwaveFilter(
  [Math.random() * app.screen.width, Math.random() * app.screen.height],
  {
    radius: 140, //半径
    wavelength: 60, //波长
    amplitude: 40, //振幅
    speed: 200 //扩散速度
  }
)

container.filters = [displacementFilter, shockwaveFilter, shockwaveFilter1, shockwaveFilter2]

// 添加动画帧
app.ticker.add((delta) => {
  displacementSprite.x += 1
  displacementSprite.y += 1
  createWave(shockwaveFilter, 1)
  createWave(shockwaveFilter1, 1.2)
  createWave(shockwaveFilter2, 0.7)
})

function createWave(waveFilter: any, resetTime: any) {
  waveFilter.time += 0.01
  if (waveFilter.time > resetTime) {
    waveFilter.time = 0
    waveFilter.center = [Math.random() * app.screen.width, Math.random() * app.screen.height]
  }
}

// 监听点击事件,根据位置产生波纹
app.view.addEventListener?.('click', (e: any) => {
  // console.log(e);
  shockwaveFilter.center = [e.clientX, e.clientY]
  shockwaveFilter.time = 0
})
</script>

lemon's personal blog.