JavaScript 拾遗:Canvas的尺寸设置

0 阅读2分钟

一、两种方式的本质区别

✅ 1. 直接设置 width / height 属性(HTML 属性)

<canvas width="800" height="600"></canvas>

👉 作用:

定义 Canvas 的“绘图缓冲区大小”(真实像素尺寸)

  • 决定画布内部坐标系(0 ~ 800, 0 ~ 600)
  • 决定绘制的清晰度
  • 重置画布内容

✅ 2. 用 CSS 控制大小

<canvas style="width: 800px; height: 600px;"></canvas>

👉 作用:

只改变显示尺寸(视觉缩放)

  • 不改变内部像素
  • 相当于把画布“拉伸/压缩”
  • 会导致模糊

二、核心差异对比(重点)

维度HTML 属性 width/heightCSS width/height
控制对象画布内部像素显示尺寸
是否影响清晰度✅ 是❌ 否(会拉伸)
坐标系改变不变
是否会重置内容✅ 会❌ 不会
默认值300 × 150由布局决定

三、为什么 CSS 会导致模糊?

假设:

<canvas width="300" height="150" style="width:600px;height:300px;"></canvas>

👉 实际发生的是:

  • 内部像素:300 × 150
  • 显示尺寸:600 × 300

👉 浏览器做了:

把 300×150 的位图放大 2 倍

结果:

  • 像素被插值 → 模糊

四、正确姿势(高清 Canvas)

👉 标准做法:

const canvas = document.querySelector('canvas')
const dpr = window.devicePixelRatio

canvas.width = 800 * dpr
canvas.height = 600 * dpr

canvas.style.width = '800px'
canvas.style.height = '600px'

const ctx = canvas.getContext('2d')
ctx.scale(dpr, dpr)

💡 原理

  • 内部用高分辨率(适配 Retina 屏)
  • 外部用正常尺寸
  • 绘制时缩放回来

五、为什么设置 width 会清空画布?

canvas.width = 800

👉 本质:

浏览器会重新创建一个新的绘图缓冲区

所以:

  • 所有内容清空
  • 状态(transform、style)也会重置

六、一个形象理解

你可以这样记:


🖼️ Canvas = 画布 + 显示框

  • width/height → 画布分辨率(像素密度)
  • CSS → 画框大小(缩放)

👉 类比:

  • HTML 属性 = 图片分辨率(比如 4K)
  • CSS = 图片展示大小(比如缩小到 800px)

七、常见坑(面试高频)

⚠️ 1. 只用 CSS → 模糊

<canvas style="width: 800px"></canvas>

👉 ❌ 错


⚠️ 2. 忘记 devicePixelRatio

👉 在 Retina 屏会糊


⚠️ 3. 动态改 width 导致内容丢失

canvas.width = canvas.width // ❌ 也会清空

八、一句话总结

HTML 的 width/height 决定“画布像素”,CSS 决定“显示大小”,两者不一致就会导致拉伸和模糊