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

浏览器缩放<100%时Canvas模糊及滚动渲染偏移问题求解

修复Canvas滚动时渲染位置偏差的问题

问题根源

你当前代码里对滚动增量做了取整处理(Math.round(event.wheelDeltaY/6)),导致startY每次只能增减整数,滚动时元素位置是跳变而非连续平滑的,这直接让行与文本的固定间距在轻微滚动时出现偏差。同时整数型的startY会丢失亚像素级的滚动细节,进一步放大渲染错位的问题。

修复方案

  1. 保留滚动增量的小数精度:去掉对滚动值的取整操作,让startY可以是浮点数,保证滚动时位置连续变化,维持元素间的固定间距。
  2. 用标准滚动事件属性:替换非标准的wheelDeltaY为标准的deltaY,同时调整符号适配滚动方向逻辑(deltaY向下滚动为正,我们需要让startY随向上滚动增加)。

修复后的完整代码

let canvas = document.querySelector('canvas');
let ctx = canvas.getContext('2d');
let width = 500;
let height = 500;
canvas.width = width * devicePixelRatio;
canvas.height = height * devicePixelRatio;
ctx.scale(devicePixelRatio, devicePixelRatio);
let startY = 0;
let lineHeight = 30;
let offSet = 0.5;
let padding = 2;

function draw(){
  ctx.clearRect(0, 0, width, height);
  for(let i=0; i<30; i++){
    let y = (i * lineHeight) + (startY % lineHeight);
    // 绘制分隔线
    ctx.beginPath();
    ctx.moveTo(250 + offSet, y + offSet);
    ctx.lineTo(350 + offSet, y + offSet);
    ctx.stroke();
    
    // 绘制文本
    ctx.font = '20px Arial';     
    ctx.fillText('text', 280 + offSet, y + offSet - padding);
  }
}

draw();
canvas.addEventListener('wheel', (event)=>{
  // 保留小数增量,适配deltaY的滚动方向
  let wheel = event.deltaY / -6;
  startY += wheel;
  draw();
});
canvas{
  width : 500px;
  height : 500px;
  border : 1px solid;
}
<canvas></canvas>

额外优化建议

  • 把硬编码的坐标数值换成变量,后续调整布局更高效;
  • 可以给startY设置上下边界,避免滚动超出合理范围;
  • 添加节流函数,减少高频滚动时的重绘次数,提升页面性能。

内容的提问来源于stack exchange,提问作者UNKNOWN .MR.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 02:06:30