canvas HTML属性尺寸和CSS尺寸多个细节深入

这篇文章发布于 2018年07月8日,星期日,14:22,归类于 Canvas相关。 阅读 27514 次, 今日 8 次 10 条评论

 

一、canvas width/height HTML属性值合法性

我们可以使用widthheight这两个HTML属性控制<canvas>元素的尺寸。

从定义上讲,<canvas>元素的widthheight标准属性值只能是整数,但是实际上,你设置小数,浏览器不会认为是不合法的。例如:

<canvas height="88.888" style="background:green;"></canvas>

实时效果如下:

经测试,各个主流浏览器下都会渲染为88像素高度。

或者你自带px单位,也是有效的,例如:

<canvas height="88px" style="background:green;"></canvas>

实时效果如下:

经测试,各个主流浏览器下都会渲染为88像素高度。

但是,如果是其他单位,例如em,则会被忽略,或者说单位会自动忽略(包括px):

<canvas height="88em" style="background:green;"></canvas>

实时效果如下:

经测试,各个主流浏览器下都会渲染为88像素高度。


但是,如果设置的是负数,或者直接不设置,对于高度,则会以150像素高度呈现;对于宽度,则会以300像素宽度呈现。

例如下面的height负值以及直接不设置width/height属性:

<canvas height="-150" style="background:green;"></canvas>
<canvas style="background:green;"></canvas>

实时效果如下:

然而,在IE浏览器下,负数尺寸值会被当做0解析,因此,看不到尺寸。这个和Chrome和Firefox浏览器是不一样的。

为什么默认尺寸是300*150?

为什么<canvas>元素默认尺寸是300*150,而不是其他尺寸组合呢?这个是CSS规范中定义的,作为替换元素,默认的尺寸是300*150<canvas>元素就是替换元素,因此默认尺寸是300*150。由于<svg>元素也是替换元素,因此,<svg>默认的尺寸也是300*150。

canvas没有尺寸设置,我们可以通过HTML属性获取吗?

例如,下面HTML,没有widthheight设置,请问canvas.height的返回值是多少?

<canvas style="background:green;"></canvas>
console.log(document.querySelector('canvas').height);

结果返回值就是默认的150,而不是undefined

高度缺省时候依然能够获取

二、HTML属性尺寸和CSS尺寸关系

从视觉表现上而言,CSS的widthheight属性权重要大于<canvas>元素的widthheight属性权重,例如下面HTML代码,最终<canvas>元素高度是88像素。

<canvas height="150" style="background:green; height:88px;"></canvas>

实时效果如下:

<canvas>元素本质上就是一个图片,其很多样式表现和<img>元素是一致的,例如这里,CSS控制图片尺寸时候,如果高度或宽度缺省,<canvas>元素依然保持原始的高宽比例。具体描述为:<canvas>元素这里原始尺寸是300*150,CSS设置为88px,最终的宽度表现不是300而是等比例缩放的176px

但是,深究下来,和<img>还是有一点区别,就是<canvas>的等比例特性是强制的,会忽略HTML属性的设置,但<img>不会这样。对比下面的测试HTML:

<img src="./1.jpg" width="300" height="150" style="height:88px;">
<canvas width="300" height="150" style="background:green; height:88px;"></canvas>

可以看到<img>宽度依然是300px,并没有保持原始比例,这就是和<img>的区别。

Canvas绘制与CSS尺寸无关

当我们使用各个Canvas API进行图形图像绘制的时候,其坐标位置,尺寸大小等都是相对于<canvas>元素的HTML属性height,与CSS height没有任何关系。例如:

<canvas height="150" style="background:green; height:88px;"></canvas>

我们想以<canvas>元素中心点为圆心画一个圆,则垂直坐标应该是75,是HTML height属性值的一半,而非最终视觉展示高度的一半。

var canvas = document.querySelector('canvas');
var context = canvas.getContext('2d');
context.fillStyle = 'orange';
context.arc(150, 75, 75, 0, 2 * Math.PI);
context.fill();

实时效果如下:

<canvas>元素本质上是个位图,因此,在retina高密度屏幕下,如果如果绘制图像,则如果按照视觉尺寸来绘制,可能就会模糊,我们可以将<canvas>元素的尺寸用HTML高宽属性设置为2倍尺寸,然后使用CSS高宽属性设置视觉尺寸为布局需要的尺寸大小。

三、结束语

就放个笑脸吧~

(本篇完)

分享到:


发表评论(目前10 条评论)

  1. 鸿碧青山说道:

    “可以看到宽度依然是300px,并没有保持原始比例,这就是和的区别。”

    第一个 img 是 canvas

  2. magiconch说道:

    旭哥,可以讲一讲SVG和Canvas的自适应如何设置吗

  3. 扎肾了老铁说道:

    张大,有个问题我困扰已久。请问你对各个版本浏览器,甚至ie各种低版本的浏览器的测试是怎么完成的?

  4. LovLong悸动说道:

    哎,知道的越多,越发现自己越无知?

  5. 广建说道:

    理清楚最重要

  6. Kouleason说道:

    长知识, 一直以来都感觉canvas的width 和height就很坑,今天总算明了

  7. lalala说道:

    我想知道有些非常复杂的canvas都是自己一点一点写出来的吗?还是有什么生成公式….