Skip to content

🖼️ Canvas 的两种尺寸 ​

在使用 HTML5 Canvas 时,理解其尺寸设置是至关重要的。本文将详细解释 Canvas 的尺寸问题,并提供最佳实践和注意事项。

Canvas 可以被视为一张纸,具有两种尺寸:

  1. 画布尺寸(canvas.width/height):表示纸张本身有多少个格子可以绘制。
  2. CSS 尺寸(canvas.style.width/height):表示纸张在页面上展示时占用的空间大小。

🛠️ 设置方式对比 ​

<canvas> 标签只有两个属性—— width 和 height,当没有设置宽度和高度的时候,<canvas> 会初始化宽度为 300px 和高度为 150px

以下是几种设置 Canvas 尺寸的方式:

html
<!-- 方式1:HTML中设置 -->
<canvas width="500" height="300"></canvas>

<!-- 方式2:HTML中设置style -->
<canvas style="width: 500px; height: 300px;"></canvas>

<!-- 方式3:JavaScript中设置 -->
<script>
const canvas = document.querySelector('canvas');
canvas.width = 500;  // 设置画布尺寸
canvas.height = 300;

canvas.style.width = "500px";  // 设置CSS尺寸
canvas.style.height = "300px";
</script>

🌟 最佳实践 ​

固定大小 Canvas ​

对于固定大小的 Canvas,推荐如下设置:

vue
<template>
  <canvas ref="canvas"></canvas>
</template>

<script>
export default {
  mounted() {
    const canvas = this.$refs.canvas;
    const displayWidth = 500;
    const displayHeight = 300;
    
    // 设置显示大小
    canvas.style.width = `${displayWidth}px`;
    canvas.style.height = `${displayHeight}px`;
    
    // 设置画布大小
    canvas.width = displayWidth * devicePixelRatio;
    canvas.height = displayHeight * devicePixelRatio;
  }
}
</script>

响应式大小 Canvas ​

对于需要响应式布局的 Canvas,推荐如下设置:

vue
<template>
  <div class="canvas-container">
    <canvas ref="canvas"></canvas>
  </div>
</template>

<script>
export default {
  mounted() {
    const resizeCanvas = () => {
      const canvas = this.$refs.canvas;
      const container = canvas.parentElement;
      const rect = container.getBoundingClientRect();
      
      // 设置显示大小
      canvas.style.width = `${rect.width}px`;
      canvas.style.height = `${rect.height}px`;
      
      // 设置画布大小
      canvas.width = rect.width * devicePixelRatio;
      canvas.height = rect.height * devicePixelRatio;
    };
    
    // 初始化尺寸
    resizeCanvas();
    
    // 监听容器大小变化
    new ResizeObserver(resizeCanvas).observe(canvas.parentElement);
  }
}
</script>

<style scoped>
.canvas-container {
  width: 100%;
  height: 100%;
  position: relative;
}

canvas {
  display: block;  /* 避免底部间隙 */
}
</style>

🤔 为什么会出现拉伸? ​

如果画布尺寸与 CSS 尺寸不匹配,可能会导致图像拉伸。例如:

js
// 错误示例
canvas.width = 500;          // 画布是500个格子
canvas.style.width = "1000px";  // 但要显示在1000px的空间里

// 结果:500个格子被拉伸显示在1000px的空间中,画面变形

📏 正确的比例关系 ​

确保画布尺寸与 CSS 尺寸成比例,以避免拉伸:

javascript
// 正确示例
const displayWidth = 500;  // 想要显示的大小

// CSS尺寸 = 显示大小
canvas.style.width = displayWidth + 'px';

// 画布尺寸 = 显示大小 * devicePixelRatio
canvas.width = displayWidth * devicePixelRatio;

// 这样,在视觉上是500px,但在高清屏上实际有更多像素,保证清晰度

🏗️ 外层 div 的必要性 ​

需要外层 div 的情况: ​

  • 需要控制 Canvas 在页面中的定位
  • 需要响应式布局
  • 需要添加其他元素与 Canvas 共同布局

不需要外层 div 的情况: ​

  • Canvas 是独立的,大小固定
  • 不需要特殊的定位和布局

💡 实际应用建议 ​

  1. 固定大小:适用于不需要响应式的场景。
  2. 响应式大小:适用于需要根据容器大小调整的场景。

通过以上设置,可以确保 Canvas 显示不会变形,在高清屏上保持清晰度,并且大小符合预期,方便进行响应式调整。