为什么浏览器中canvas渲染高度是设定值两倍,图形比例异常?
问题核心原因
你遇到的拉伸问题是由canvas的两套独立尺寸体系不匹配导致的:
- canvas存在两个互不干扰的尺寸定义:
- 画布实际像素尺寸:由
<canvas>标签自带的width、height属性控制(不带单位),默认值为300px * 150px,是你调用JS绘图API时的坐标基准 - 页面显示尺寸:由CSS的
width、height属性控制,是画布最终在页面上渲染的拉伸后大小
- 画布实际像素尺寸:由
- 你当前只设置了CSS显示尺寸为
500px * 500px,但画布实际像素尺寸仍为默认的300*150,浏览器会将画布做拉伸适配:
横向拉伸比例 = 500/300 ≈ 1.67
纵向拉伸比例 = 500/150 ≈ 3.33
纵向拉伸比例刚好是横向的2倍,所以你绘制的50*50正方形会显示为纵向拉长的矩形,所有高度坐标看起来都是设定值的两倍。
另外你的代码里还有两处笔误:
- 绘图API是
getContext('2d')不是getContent('2d'),写错会直接抛出异常无法执行绘图 - CSS里的背景色值缺少
#前缀,正确写法是#E0E0E0
修复方案
基础修复(无高DPI适配需求)
直接给canvas标签添加和CSS尺寸一致的width、height属性即可:
<canvas id="canvasArea" width="500" height="500" style=" width: 500px; height: 500px; background-color: #E0E0E0; "></canvas>
高DPI屏幕适配(避免绘制内容模糊)
如果需要适配视网膜等高分屏,可以按设备像素比放大画布实际尺寸:
let cv = document.getElementById("canvasArea"); let dpr = window.devicePixelRatio || 1; // 设置画布实际像素尺寸为显示尺寸的dpr倍 cv.width = 500 * dpr; cv.height = 500 * dpr; let cvArea = cv.getContext('2d'); // 绘图坐标全部乘以dpr cvArea.scale(dpr, dpr); cvArea.fillRect(10, 10, 50, 50); cvArea.fillRect(60, 10, 50, 25);
内容的提问来源于stack exchange,提问作者S. Baek
相关产品推荐
相关产品推荐

