You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

实现鼠标移动时背景图片去模糊效果(参考Canva注册页)

实现Canva风格鼠标移动背景去模糊效果

我帮你完善并梳理这个效果的实现逻辑,先从你现有代码的小问题入手,再补全核心的背景模糊交互功能:

首先,你的distance函数没写完,先补全它:

function distance(x1, y1, x2, y2) {
  var a = x1 - x2;
  var b = y1 - y2;
  return Math.sqrt(a * a + b * b);
}

接下来,要实现Canva那种「鼠标划过区域背景从模糊变清晰」的效果,核心思路是:

  • 底层放清晰的背景图
  • 上层放模糊的背景遮罩层
  • 用Canvas覆盖在最上层,通过鼠标移动绘制的路径,把上层的模糊遮罩“擦除”,露出底层的清晰背景

完整实现代码

HTML结构

<div class="bg-container">
  <div class="bg-clear"></div>
  <div class="bg-blur"></div>
  <canvas id="log"></canvas>
</div>

CSS样式

.bg-container {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  overflow: hidden;
}

.bg-clear, .bg-blur {
  position: absolute;
  width: 100%;
  height: 100%;
  background-image: url('你的清晰背景图地址'); /* 替换成你的背景图 */
  background-size: cover;
  background-position: center;
}

.bg-blur {
  filter: blur(8px); /* 模糊程度,可根据需求调整 */
}

#log {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  cursor: crosshair;
  /* 关键:让Canvas的绘制内容作为遮罩,擦除上层模糊层 */
  mix-blend-mode: destination-out;
}

JavaScript逻辑

var canvas, ctx, prevX = 0, currX = 0, prevY = 0, currY = 0;

function init() {
  canvas = document.getElementById('log');
  ctx = canvas.getContext("2d");
  // 适配窗口大小
  resizeCanvas();
  window.addEventListener('resize', resizeCanvas);

  // 鼠标移动事件处理
  canvas.addEventListener('mousemove', function(e) {
    currX = e.clientX;
    currY = e.clientY;
    
    // 计算鼠标移动距离,动态调整线条宽度
    var d = distance(prevX, prevY, currX, currY);
    // 移动越慢线条越宽,移动越快线条越窄,贴合Canva的自然效果
    var lineWidth = d > 0 ? Math.min(80 / d, 60) : 60;

    ctx.beginPath();
    // 用圆形衔接路径起点,让轨迹更顺滑
    ctx.arc(prevX, prevY, lineWidth / 2, 0, Math.PI * 2);
    ctx.fill();
    // 绘制鼠标移动的轨迹线条
    ctx.moveTo(prevX, prevY);
    ctx.lineTo(currX, currY);
    ctx.lineCap = "round";
    ctx.lineWidth = lineWidth;
    ctx.stroke();

    prevX = currX;
    prevY = currY;
  });

  // 鼠标离开窗口时重置位置,避免回到窗口时出现突兀线条
  canvas.addEventListener('mouseleave', function() {
    prevX = currX = 0;
    prevY = currY = 0;
  });
}

function distance(x1, y1, x2, y2) {
  var a = x1 - x2;
  var b = y1 - y2;
  return Math.sqrt(a * a + b * b);
}

function resizeCanvas() {
  canvas.width = window.innerWidth;
  canvas.height = window.innerHeight;
  // 重置Canvas状态,确保窗口大小变化后效果正常
  ctx.globalCompositeOperation = 'source-over';
  ctx.fillStyle = '#fff';
  ctx.fillRect(0, 0, canvas.width, canvas.height);
  ctx.globalCompositeOperation = 'destination-out';
}

// 页面加载完成后初始化效果
window.onload = init;

关键细节解释

  • CSS的mix-blend-mode: destination-out:这是实现擦除效果的核心,Canvas上绘制的内容会把上层的模糊背景层“挖掉”,从而露出底层的清晰背景。
  • 动态线条宽度:通过计算鼠标移动的距离,让快速移动时线条更窄、慢速移动时更宽,模拟Canva那种自然的跟随手感。
  • 窗口适配:监听窗口resize事件,实时调整Canvas尺寸,保证效果在窗口大小变化时依然正常显示。

内容的提问来源于stack exchange,提问作者Yuki.kuroshita

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 03:08:23