HTML5中实现玻璃折射滤镜效果,核心是利用Canvas的像素级操作能力,模拟光线穿过玻璃时的偏移变形效果,不需要依赖复杂的第三方库,通过原生API就能完成实现。

玻璃折射的核心原理
真实的玻璃折射是光线穿过不同密度的介质时发生偏折,在视觉上表现为图像局部的位置偏移和轻微扭曲。在Canvas中实现这个效果,主要分为三个步骤:
- 获取原始图像的所有像素数据
- 根据折射规则计算每个像素的新位置偏移量
- 将原始像素绘制到偏移后的新位置,生成最终效果
实现步骤拆解
1. 准备Canvas和原始图像
首先需要在页面中创建Canvas元素,加载需要添加滤镜的原始图像,确保图像加载完成后再执行后续操作,避免获取不到像素数据的问题。
<canvas id="glassCanvas" width="800" height="500"></canvas> <img id="sourceImg" src="test.jpg" style="display:none;">
2. 获取像素数据
通过Canvas的<code>getImageData</code>方法可以拿到画布上所有像素的RGBA信息,每个像素占4个数组位置,分别对应红、绿、蓝、透明度通道。
// 获取Canvas上下文
const canvas = document.getElementById('glassCanvas');
const ctx = canvas.getContext('2d');
// 加载原始图像并绘制到Canvas
const img = document.getElementById('sourceImg');
img.onload = function() {
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
// 获取整个画布的像素数据
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const data = imageData.data;
// 后续处理像素数据
applyGlassRefraction(data, imageData);
};
3. 计算折射偏移量
折射偏移通常使用正弦或余弦函数模拟,让偏移量随位置变化产生自然的扭曲感,同时可以设置折射强度参数控制变形程度。
function applyGlassRefraction(pixelData, imageData) {
const width = imageData.width;
const height = imageData.height;
// 创建新的像素数组存放偏移后的数据
const newData = new Uint8ClampedArray(pixelData.length);
// 折射强度,数值越大变形越明显
const refractionStrength = 20;
// 遍历每个像素
for (let y = 0; y < height; y++) {
for (let x = 0; x < width; x++) {
// 计算当前像素的偏移量,使用正弦函数模拟自然扭曲
const offsetX = Math.sin(y * 0.05) * refractionStrength;
const offsetY = Math.cos(x * 0.05) * refractionStrength;
// 计算偏移后的坐标,限制在画布范围内
const newX = Math.max(0, Math.min(width - 1, Math.floor(x + offsetX)));
const newY = Math.max(0, Math.min(height - 1, Math.floor(y + offsetY)));
// 原始像素的索引
const originalIndex = (y * width + x) * 4;
// 偏移后像素的索引
const newIndex = (newY * width + newX) * 4;
// 将原始像素的RGBA值复制到新位置
newData[newIndex] = pixelData[originalIndex]; // R
newData[newIndex + 1] = pixelData[originalIndex + 1]; // G
newData[newIndex + 2] = pixelData[originalIndex + 2]; // B
newData[newIndex + 3] = pixelData[originalIndex + 3]; // A
}
}
// 将处理后的像素数据绘制回Canvas
const newImageData = new ImageData(newData, width, height);
ctx.putImageData(newImageData, 0, 0);
}
参数调整技巧
可以通过调整几个核心参数改变折射效果的表现:
| 参数名称 | 作用说明 | 推荐取值范围 |
|---|---|---|
| refractionStrength | 控制折射变形的强度,数值越大扭曲越明显 | 10-30 |
| 正弦余弦的系数 | 控制扭曲的频率,系数越小扭曲越平缓 | 0.03-0.08 |
| 偏移计算方式 | 可以替换为随机偏移模拟磨砂玻璃效果 | 根据需求调整 |
注意事项
像素级操作属于计算密集型操作,如果处理的图像尺寸过大,可能会导致页面卡顿,建议先对大尺寸图像进行缩放再处理。另外如果图像来自不同域,Canvas会受到同源策略限制,无法获取像素数据,需要提前解决跨域问题。
如果需要模拟更真实的玻璃折射,还可以结合透明度调整,让折射区域的透明度轻微降低,增强玻璃的质感表现。