js实现扫描图片效果
使用Canvas实现图片扫描效果
通过Canvas的getImageData和putImageData方法逐行或逐列处理像素数据,模拟扫描仪效果。以下是一个基础实现示例:
function scanImageEffect(imageElement, canvasElement, speed = 5) {
const ctx = canvasElement.getContext('2d');
canvasElement.width = imageElement.width;
canvasElement.height = imageElement.height;
let scanLine = 0;
const totalHeight = imageElement.height;
function draw() {
ctx.clearRect(0, 0, canvasElement.width, canvasElement.height);
ctx.drawImage(imageElement, 0, 0);
const imageData = ctx.getImageData(0, scanLine, canvasElement.width, 1);
ctx.putImageData(imageData, 0, scanLine);
scanLine += speed;
if (scanLine < totalHeight) {
requestAnimationFrame(draw);
}
}
draw();
}
添加渐变扫描效果
通过调整像素数据的透明度实现渐变扫描效果:

function gradientScanEffect(imageElement, canvasElement) {
const ctx = canvasElement.getContext('2d');
canvasElement.width = imageElement.width;
canvasElement.height = imageElement.height;
ctx.drawImage(imageElement, 0, 0);
const imageData = ctx.getImageData(0, 0, canvasElement.width, canvasElement.height);
const data = imageData.data;
let revealHeight = 0;
const gradientSize = 50;
function animate() {
ctx.clearRect(0, 0, canvasElement.width, canvasElement.height);
ctx.putImageData(imageData, 0, 0);
for (let y = 0; y < revealHeight; y++) {
for (let x = 0; x < canvasElement.width; x++) {
const idx = (y * canvasElement.width + x) * 4;
if (y > revealHeight - gradientSize) {
const opacity = (revealHeight - y) / gradientSize;
data[idx + 3] = opacity * 255;
} else {
data[idx + 3] = 255;
}
}
}
revealHeight += 2;
if (revealHeight <= canvasElement.height) {
requestAnimationFrame(animate);
}
}
animate();
}
使用CSS遮罩实现扫描效果
纯CSS方案适用于简单场景,通过动画改变遮罩位置:

<style>
.scan-container {
position: relative;
overflow: hidden;
}
.scan-mask {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 10px;
background: rgba(255, 255, 255, 0.7);
animation: scan 3s linear infinite;
}
@keyframes scan {
from { top: -10px; }
to { top: 100%; }
}
</style>
<div class="scan-container">
<img src="your-image.jpg">
<div class="scan-mask"></div>
</div>
高级扫描线效果
结合噪声和像素位移实现更真实的扫描效果:
function advancedScanEffect(imageElement, canvasElement) {
const ctx = canvasElement.getContext('2d');
canvasElement.width = imageElement.width;
canvasElement.height = imageElement.height;
let scanPosition = 0;
const scanWidth = 2;
const noiseIntensity = 0.1;
function addNoise(imageData) {
const data = imageData.data;
for (let i = 0; i < data.length; i += 4) {
const noise = (Math.random() - 0.5) * noiseIntensity * 255;
data[i] += noise; // R
data[i + 1] += noise; // G
data[i + 2] += noise; // B
}
return imageData;
}
function animate() {
ctx.clearRect(0, 0, canvasElement.width, canvasElement.height);
ctx.drawImage(imageElement, 0, 0);
const scanData = ctx.getImageData(0, scanPosition, canvasElement.width, scanWidth);
const noisyData = addNoise(scanData);
ctx.putImageData(noisyData, 0, scanPosition);
scanPosition += 1;
if (scanPosition < canvasElement.height) {
requestAnimationFrame(animate);
}
}
animate();
}
性能优化建议
对于大尺寸图片处理,建议使用离屏Canvas或Web Worker避免主线程阻塞:
// 使用离屏Canvas
const offscreenCanvas = document.createElement('canvas');
const offscreenCtx = offscreenCanvas.getContext('2d');
offscreenCanvas.width = imageElement.width;
offscreenCanvas.height = imageElement.height;
offscreenCtx.drawImage(imageElement, 0, 0);
以上方法可根据实际需求组合使用,调整扫描速度、宽度和特效强度等参数获得不同视觉效果。






