【Rain Effect】是一个令人惊叹的雨滴效果,您可本站首页看到其应用的效果。该js库较为古早且不支持配置,本文记录了将其重构及react组件化的实践过程。
你或许也惊叹于本站落地页那真实的雨滴效果,该效果的实现在来自于一个开源项目RainEffect(下称简称RE)。
该项目通过webgl实现了这些神奇的雨滴效果并让其他开发者得已使用,不过由于项目久远并缺少维护想要真正在项目中集成该效果并不容易,本文详细介绍下本站使用该项目的实践过程和基于该项目的重构方案。
如果你不想安装本人重构后的库并快速在项目中渲染雨滴可以选择此方式,这也是重构完成前本站的使用方式。
前往RE下载打包后的代码,将下载的代码文件放到你的项目中,我们后续将会通过script标签的方式引入该文件。
本人目前只使用了基础的版本也就是index.min.js
图片背景,所以其他版本能否正常运行未知,如果你希望使用其他版本(例如视频背景)可以下载index3.min.js
。
在你的项目中通过script标签引入下载的文件,例如:
js<script src="./index.min.js"></script>
同时你的页面上需要创建一个canvas标签用来渲染内容:
js<body> <!-- 其他元素 --> <canvas id="container"></canvas> <script src="./index.min.js"></script> </body>
代码文件内部会通过id来获取canvas
标签并渲染,所以id的值需要和代码文件一致,如果想使用其他id需要在代码文件中同步修改:
jsfunction s() {
W = document.querySelector('#container') //改成其他id
var t = window.devicePixelRatio
;(W.width = window.innerWidth * t),
(W.height = window.innerHeight * t),
(W.style.width = window.innerWidth + 'px'),
(W.style.height = window.innerHeight + 'px'),
(G = new g['default'](W.width, W.height, t, N, I, {
trailRate: 1,
trailScaleRange: [0.2, 0.45],
collisionRadius: 0.45,
dropletsCleaningRadiusMultiplier: 0.28
})),
(z = (0, $['default'])(Y.width, Y.height)),
(L = z.getContext('2d')),
(B = (0, $['default'])(U.width, U.height)),
(X = B.getContext('2d')),
p(O, j),
(q = new m['default'](W, G.canvas, z, B, null, {
brightness: 1.04,
alphaMultiply: 6,
alphaSubtract: 3
})),
o()
}
代码修改到此告一段落。
完成代码修改操作你的代码仍无法运行,因为雨滴的渲染用到了背景图等资源,下载img文件夹下的所有文件放到自己项目中的img文件夹中,渲染过程中会自动加载这些文件。
如果图片路径正确且正常加载你应该能在项目中看到渲染好的页面,就像下面这样:
将你的背景图片放到img文件夹下,修改index.min.js中的文件路径来加载你自己的背景图:
js{ name: "textureRainFg", src: "./weather/texture-rain-fg.png" },//src修改成你自己的背景图路径
{ name: "textureRainBg", src: "./weather/texture-rain-bg.png" },//src修改成你自己的背景图路径
不难发现上述使用方法较为繁琐且已无法与如今前端的工程化应用很好的配合(例如webpack,vite),本次重构工作将会以工程化为目的在不修改核心源代码的基础上开展,预计实现的特性如下:
下称重构后的库为Arain
Arain的默认导出为Rain,你可以通过该类来初始化一个Rain实例,该类的基本结构如下:
typescriptexport interface RainOptions {
bg?: string //渲染的背景图片
}
export default class Rain {
private _id: string //canvas元素id,例如#my-canvas
private _options?: RainOptions // 暴露的配置项
constructor(id: string, options?: RainOptions) {
this._id = id
this._options = options
}
init() {
loadTextures(this._id,this._options)
}
}
基本使用如下:
typescriptconst rainInstance = new Rain('#aling-rain-cover')
rainInstance.init()