当前位置:首页 > JavaScript

js实现扫描图片效果

2026-03-01 22:33:14JavaScript

使用Canvas实现图片扫描效果

通过Canvas的getImageDataputImageData方法逐行或逐列处理像素数据,模拟扫描仪效果。以下是一个基础实现示例:

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避免主线程阻塞:

js实现扫描图片效果

// 使用离屏Canvas
const offscreenCanvas = document.createElement('canvas');
const offscreenCtx = offscreenCanvas.getContext('2d');
offscreenCanvas.width = imageElement.width;
offscreenCanvas.height = imageElement.height;
offscreenCtx.drawImage(imageElement, 0, 0);

以上方法可根据实际需求组合使用,调整扫描速度、宽度和特效强度等参数获得不同视觉效果。

标签: 效果图片
分享给朋友:

相关文章

css制作卷边效果

css制作卷边效果

使用伪元素和渐变实现卷边效果 通过CSS伪元素和线性渐变可以模拟纸张卷边的视觉效果。这种方法不需要额外元素,仅通过::before或::after伪元素实现。 .element { positi…

h5实现图片压缩

h5实现图片压缩

使用Canvas API压缩图片 HTML5的Canvas API可以通过调整画布尺寸和图像质量来实现图片压缩。创建一个Canvas元素,将图片绘制到Canvas上,再通过toDataURL或toBl…

vue实现tag效果

vue实现tag效果

实现基本标签结构 使用 Vue 的模板语法创建标签容器和单个标签元素。通过 v-for 动态渲染标签列表,结合 v-bind:key 确保渲染性能。 <template> <…

vue实现图片切换

vue实现图片切换

实现图片切换的方法 使用v-for和v-bind动态绑定图片 通过v-for循环渲染图片列表,结合v-bind动态绑定图片路径,实现切换效果。 <template> <div&…

react如何添加效果

react如何添加效果

React 添加动画效果的方法 使用 CSS 过渡动画 在 React 组件中直接通过 className 或 style 属性应用 CSS 过渡效果。定义 CSS 类包含 transition 属性…

js实现点击效果

js实现点击效果

实现点击效果的JavaScript方法 使用addEventListener绑定点击事件 通过document.getElementById或document.querySelector获取DOM元素…