提前了解:以下画布上的黑色线条全都是从坐标点(0,0)到(200,200)绘制,只对canvas的宽高设置方式做了改变,可以看出不同的设置方式,画出的线条是不同的,原因是什么,我们来分析一下鸭!

为了方便理解,我们可以做如下解释:
美术课上我们画图时,首先会有一个画板,然后将画纸铺到画板上,然后在纸上作画。
Canvas既然是画布,那我们就可以理解为,一个canvas就是一个画板和一张画纸,画图作业是在画纸上进行的。
当画板的宽高与画纸的宽高相等时,画出的图像就不会拉伸;相反,当画板的宽高与画纸的宽高不相等时,画出的图像就会被拉伸变形。

我们用以下几个例子详细说明:

Your browser does not support the Canvas API. Please upgrade your browser.
您的浏览器不支持Canvas API,请升级您的浏览器!

1. 宽高不做任何设置,默认宽高会是300*150;
即,画板和画纸的宽高默认都是300*150,画出的图像点位正常,不会被拉伸。只是有部分线条超出了画布范围,所以不显示。

2. 在canvas元素中设置宽高(带不带px都一样) <canvas id="canvas2" width="200" height="200"></canvas>
这种是正确的设置canvas宽高的方式,这样画板和画纸的宽高是相等的,所以画出的图像不会被拉伸变形。

3. 在样式中设置宽高 <canvas id="canvas3" style="width: 200px;height: 200px;"></canvas>
这种在样式中设置宽高的,实际上相当于只对画板设置了宽200、高200,而画纸的宽高为默认300*150,此时,画板和画纸的宽高不一致,画出的图像就会被拉伸变形。 图片
如图,我们设置画板的宽高200*200,而画纸默认宽高300*150,我们在canvas上画线从点(0,0)到点(200,200),那么理论上留在画纸上的线条就是oa段,但实际上由于画板与画纸宽高不一致,在我们画线的时候,画纸就像变得有弹性一样,并向着与画板宽高保持一致的方向压缩或者拉伸(画纸宽高大于画板就压缩,小于画板就拉伸,也就是趋于向画板保持一致);于是,x方向先压缩到与画板一致,a点就跑到了b点位置,然后y方向拉伸至与画板一致,b点又跑到了c点位置,此时画板与画纸宽高一致了,那么原来画在画纸上的oa段,就变成了现在的oc段,也就是我们最终在画布上看到的线条效果。

注:在CSS中或者用JS/JQ设置canvas的样式宽高,线条绘制效果是一样的,这里不做演示
#canvas3{width: 200px;height: 200px;}
document.getElementById("canvas3").style.width = "200px"
document.getElementById("canvas3").style.height = "200px"
$("#canvas3").css({"width":"200px","height":"200px"})

4. 在canvas元素中设置百分比宽高 <canvas id="canvas4" width="100%" height="100%"></canvas>
canvas会忽略百分比,把数值作为画布的宽高,也就是说canvas不支持百分比宽高。

总结:
1. canvas元素有默认宽高,宽300px,高150px;
2. 给canvas元素设置宽高两种方法:
    一,<canvas id="canvas" width="200" height="200"></canvas>
    二,在js中使用canvas API操作,
    var ctx = document.getElementById("canvas"),
    ctx = ctx.getContext("2d");
    ctx.width = 200;
    ctx.height = 200;
3. 通过css样式来给canvas设置的宽高,与canvas默认值不一致时,会使画出的图像拉伸变形;
    例:
    var ctx = document.getElementById("canvas");
    ctx = ctx.getContext("2d");
    ctx.style.width = "200px";
    ctx.style.height = "200px";
4. canvas的宽高不能用百分比表示,canvas会忽略百分号,只取百分比数值显示。