Number.isInteger() 不能直接解决 Canvas 模糊,但可拦截非整数坐标以防止抗锯齿模糊;需配合整数宽高、禁用 CSS 缩放及 DPR 缩放才能彻底防模糊。

Number.isInteger() 本身不能直接解决 Canvas 绘图模糊问题,但它可以帮你提前发现并拦截那些“看似整数、实为浮点数”的坐标值——而这正是导致 Canvas 像素对齐失效、图像模糊的常见根源。
为什么非原始整数会让 Canvas 变模糊?
Canvas 的 2D 渲染基于像素网格。当绘制路径、填充或图像时,若传入的 x 或 y 坐标是小数(如 10.5),浏览器会触发抗锯齿插值,把颜色“涂抹”在相邻像素上,结果就是边缘发虚、文字/线条变粗、图标失真。
问题常出现在:缩放计算、CSS 像素转换、DOM 尺寸读取(getBoundingClientRect().left 可能返回小数)、动画插值、或简单地误用 Math.round() 后未校验类型(比如 Math.round("12.7") === 13,但 13 是 number,没问题;而 Math.round("abc") === NaN,再传给 ctx.fillRect(NaN, 0, 10, 10) 就静默失败)。
用 Number.isInteger() 主动拦截非法坐标
它只对真正的 number 类型且值为整数时返回 true,对 NaN、Infinity、字符串数字(如 "10")、布尔值等一律返回 false——这比 typeof x === 'number' && x % 1 === 0 更安全、语义更明确。
- 在关键绘图前校验坐标参数:
function safeFillRect(ctx, x, y, w, h) {<br> if (!Number.isInteger(x) || !Number.isInteger(y) ||<br> !Number.isInteger(w) || !Number.isInteger(h)) {<br> console.warn('Canvas draw rejected: non-integer coordinate', {x, y, w, h});<br> return;<br> }<br> ctx.fillRect(x, y, w, h);<br>}
- 配合
Math.floor()或Math.round()转换后再校验(注意:先转再判,避免丢失精度):
const x = Math.round(el.getBoundingClientRect().left);<br>if (Number.isInteger(x)) {<br> ctx.strokeRect(x, 0, 100, 100);<br>} else {<br> // 不该发生,但保底兜底<br> ctx.strokeRect(0, 0, 100, 100);<br>}
别忽略 Canvas 自身的整数对齐前提
Number.isInteger() 是第一道防线,但还需配合以下设置才能真正防模糊:
- 确保 Canvas 元素的
width和height属性是整数(不是 CSS 样式); - 避免用 CSS 缩放 Canvas(如
transform: scale(1.5)),应直接修改 canvas 的width/height并调整绘图逻辑; - 开启像素精准渲染(适用于高 DPI 屏幕):
const dpr = window.devicePixelRatio || 1;<br>canvas.width = Math.floor(canvas.clientWidth * dpr);<br>canvas.height = Math.floor(canvas.clientHeight * dpr);<br>ctx.scale(dpr, dpr);
扩展:识别“伪整数”陷阱
有些值看起来像整数,却不是原始 number:
-
Number("10")→10(合法,Number.isInteger()返回true) -
parseInt("10.9")→10(合法) -
+"10"→10(合法) -
new Number(10)→ 对象,Number.isInteger()返回false(必须用.valueOf()转回原始值) -
Math.round(10.00000000000001)→10(仍是 number,但原始值有浮点误差;此时Number.isInteger()仍返回true,需结合Number.EPSILON判定是否“足够接近整数”)
对精度敏感场景,可补充判断:
function isSafeInteger(n) {<br> return Number.isInteger(n) &&<br> Math.abs(n - Math.round(n)) < Number.EPSILON;<br>}


















