pixi 做一个动态模糊背景

1,804 阅读1分钟

pixiJS

做一个动态背景,模糊处理,让关注点放在内容上。动态用几个圆形图案在背景缓慢移动就可以。

步骤

1. 安装引入

npm install pixi.js

import * as PIXI from 'pixi.js'

2. 布置背景画布

<div id="layout">
    <canvas id="layout-canvas" ref="layoutCanvas"></canvas>
    <header>...</header>
    <main>...</main>
</div>
// script
methods: {
    initAnimate() {
        const app = new PIXI.Application({
            view: this.$refs.layoutCanvas, 
            resizeTo: window, //尺寸响应源
            transparent: true //默认为黑色,这里设置为透明,就可以用css控制背景色
        })
    }
},
mounted() {
    this.initAnimate()
}
// css
#layout {
    position: relative;
    min-height: 100vh;
}
#layout-canvas {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
    z-index: -1;
}

3. 画一个小圆

initAnimate() {
    const app = new PIXI.Application({...})
    
    const circle = new PIXI.Graphics() //几何图形画笔
    
    circle.beginFill(0xffffff, 1) // (十六进制色彩,alpha)
    circle.drawCircle(200, 200, 50) // ( x, y, radius )
    circle.endFill()
    
    app.stage.addChild(circle)
}

image.png

4. 动起来

initAnimate() {
    ...
    // 默认1s 60帧,所以每秒向x方向移动60,y方向移动60
    app.ticker.add(_ => {
        circle.x ++
        circle.y ++
    })
}

5. 流畅地动起来

使用Math.random()生成位移值会在起点位置疯狂抖动,所以就得研究Perlin noise了。

...

费了半天劲,终于让小园球随机圆滑地动起来了,然后浏览器崩了...,虽然simplex-noise作者在readme写了too expensive,当时还没明白为什么一条圆滑随机曲线为什么会昂贵?现在明白了。

6. 换个思路

预定义条曲线,让小球跟着动,随机的话,就多弄几条曲线。查不到什么PixiJS path移动相关的动画,然后决定用animejssvg操作,这样我对时间、帧数、过渡之类的更好把握一些,并且还不是有现成的path motion可以用嘛。

PIXI官方 EXAMPLES 推荐的用GSAP动画联动,但种种原因,让我从喜欢GASP到anime真香。具体什么原因,其它地方再说。

7. 用anime让小球动起来

initAnimate() {
    ...
    // anime在main文件挂载到vue.prototype
    this.$anime({
        targets: circle
        x: 500,
        duration: 3000,
        loop: true
    })
}

image.png

8. 让小球跟着<path>动起来

用svg工具Inkscape画一条圆滑的曲线。

image.png

保存为svg,用vscode打开,用svg插件对文件Minify SVG

image.png

<path>复制出来(只保留d属性),然后加上id

<canvas id="layout-canvas" ref="layoutCanvas">
    <path id="path1" d="M56.911 73.236c36.258.507 47.296 28.494 47.296 56.345s11.982 55.81 48.268 55.81 48.532-28.607 48.532-56.177-13.103-56.46-47.662-56.46c-34.56 0-49.359 23.713-49.359 55.812 0 32.098-15.902 56.788-46.097 56.788-30.196 0-48.138-27.363-48.138-54.39 0-27.029 10.903-58.236 47.16-57.728z" />
</canvas>

动起来

const  path1 = this.$anime.path('#layout-canvas #path1');
this.$anime({
    targets: circle,
    x: path1('x'),
    y: path1('y'),
    duration: 3000,
    loop: true,
    easing: 'linear'
})

9. 加一个模糊滤镜

const blurFilter = new PIXI.filters.BlurFilter();
app.stage.filters = [blurFilter]

image.png

到这就基本完了,然后稍微调一下。

10. 成品

image.png

知识点