梦亦同趋
首页
记忆
链接
React组件化
webgl

【Rain Effect】效果的组件化实践

【Rain Effect】是一个令人惊叹的雨滴效果,您可本站首页看到其应用的效果。该js库较为古早且不支持配置,本文记录了将其重构及react组件化的实践过程。

Aling
2025-06-25
阅读时长
通过现有方案快速集成
下载项目代码
使用其他版本(未验证)
修改代码
下载渲染所需资源
更改背景图片
组件化重构
Rain类

你或许也惊叹于本站落地页那真实的雨滴效果,该效果的实现在来自于一个开源项目RainEffect(下称简称RE)。

该项目通过webgl实现了这些神奇的雨滴效果并让其他开发者得已使用,不过由于项目久远并缺少维护想要真正在项目中集成该效果并不容易,本文详细介绍下本站使用该项目的实践过程和基于该项目的重构方案。

#通过现有方案快速集成

如果你不想安装本人重构后的库并快速在项目中渲染雨滴可以选择此方式,这也是重构完成前本站的使用方式。

#下载项目代码

前往RE下载打包后的代码,将下载的代码文件放到你的项目中,我们后续将会通过script标签的方式引入该文件。

INFO

上述操作下载代码是如果你回到了上级目录你会发现该文件下存在三个版本的index.js文件:图片背景(index.js,无背景(index2.js)和视频背景(index3.js)以及每个版本对应的未压缩版本,我们下载的是压缩版本index.min.js。点击此处查看各个版本效果。

#使用其他版本(未验证)

本人目前只使用了基础的版本也就是index.min.js图片背景,所以其他版本能否正常运行未知,如果你希望使用其他版本(例如视频背景)可以下载index3.min.js。

WARNING

不推荐使用未压缩版本,因为版本较老可能存在未解决的issue,目前确定的是该issue在图片背景的未压缩版本下确实存在。

#修改代码

在你的项目中通过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需要在代码文件中同步修改:

js
function 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文件夹中,渲染过程中会自动加载这些文件。

image.png

如果图片路径正确且正常加载你应该能在项目中看到渲染好的页面,就像下面这样:

image.png

#更改背景图片

将你的背景图片放到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),本次重构工作将会以工程化为目的在不修改核心源代码的基础上开展,预计实现的特性如下:

  • 提供typescript的支持,这项工作将会在整个重构的生命周期中开展。
  • 开放出一些常用的配置:例如背景图,雨滴参数等
  • 及其他...

下称重构后的库为Arain

#Rain类

Arain的默认导出为Rain,你可以通过该类来初始化一个Rain实例,该类的基本结构如下:

typescript
export 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) } }

基本使用如下:

typescript
const rainInstance = new Rain('#aling-rain-cover') rainInstance.init()
ERROR

我们推荐options.bg为本地资源,例如./public/yourbackgroundimg.png,否则你可能收到以下报错:

Failed to execute 'texImage2D' on 'WebGLRenderingContext': Tainted canvases may not be loaded. SecurityError: Failed to execute 'texImage2D' on 'WebGLRenderingContext': Tainted canvases may not be loaded.

这是因为你的背景图属于跨域资源,当使用跨域资源(如图片)绘制内容,且该资源未正确设置 CORS 响应头(Access-Control-Allow-Origin),画布会被标记为“污染“。WebGL 的安全限制禁止污染的画布用于 texImage2D 等操作。

上次更新:2025-06-26 10:51:08
上一篇
下一篇
关于2024年